← Files ModRetro Chromatic PluginARCHIVED FILE

docs/reviewed-custom-events.md

25.8 KB · Oct 2, 2026 · 00:37 UTC

↓ Download file

# Reviewed custom-event dependencies

The world index can use a reviewed custom-event extractor without evaluating
project JavaScript. This is trusted maintained-source configuration, not a
public project setting. A command name, plugin manifest, successful build, or
project-provided `complete` flag never establishes complete semantic coverage.

The default catalog includes separately reviewed Wrecklight native13, r06, r31,
r36, r37, gameplay-feedback, Condenser-cue and r44 profiles.
Each profile requires its complete matching handler/helper set;
individual hashes from different profiles cannot be combined. The r31 profile
binds its noncontiguous map words, connector rooms and actors, combat targets,
compiled sprites, player states and non-parallax background associations.
Changed or ambiguous inputs leave coverage incomplete. Generic fixture tests
do not substitute for this maintained-source review, and installing the plugin
or playing a game is a separate operation.

When coverage is incomplete, use `world_dependencies` and its `coverageCursor`
to inspect the actual reasons. Some reasons concern native references, such as
an unresolved variable or engine field. `UNVERIFIED_CUSTOM_EVENT_CONTRACT` can
mean changed, mixed or unreviewed handler/compiler sources, an unsupported
authored contract (for example, a different owner or descriptor), or an invalid
invocation. A successful build, retry, or `adopt_binding` cannot establish an
unsupported custom-event contract. Bound-room tilemap operations refuse with
`TILEMAP_DEPENDENCY_UNCERTAIN` and leave native output unchanged. Atlas-only
inspection remains available, but does not grant room-edit coverage.

The bundled-remix successor preserves the chamber profile's event effects and
adds the two Airworks enemy ticks. It binds the curated sample's complete native
source, including its four-channel title score and optimized Cargo/Reactor idle
helpers. It accounts for the sample's updated chamber helper and omitted
inactive source backup. Historical profiles retain their original hashes.
This successor and its performance descendants permit string changes to the
project descriptor's `name` and `author`, as made by `project_create`. Every
other descriptor field must
match the reviewed snapshot, and extra fields are rejected. Engine settings,
variables, plugin files and resource relationships keep their existing guards.
The title music adds no VM-global or authored-resource dependencies.

The performance profiles retain the earlier bundled-remix profile and each bind
a separate complete set of native sources. They accept the combat `grace`
operation: it reads variable 9 and
decrements it when its signed value is positive. The operation has no compiled
child branches. Its calling actor script remains editable and is read by the
ordinary graph. The compiler profile stays unchanged; partial mixtures of
the native source sets remain unreviewed.

The busy-room successor binds the revised sprite renderer, actor collision loop,
VM dispatcher and scheduler, Airworks argument packets, door bounds, rewards,
and HUD charge lookup. It also binds the supported `50000` compiler preset and
the exact descriptor note `Native save compatibility revision: wrecklight-v5-engine-1`.
The note distinguishes the new native RAM and saved-script layout. Earlier
profiles keep their original descriptor notes and source hashes. These source
contracts establish dependencies; performance and save behavior require their
separate native-ROM checks.

The frame-pacing successor retains that complete profile and separately binds
the projectile, door-scan and reward changes, the core frame loop, queued OAM
and camera publication, and the single-column tile upload. The interrupt, shadow-header
and tile-copy patches are required native inputs, not optional extras.
Its descriptor note is `Native save compatibility revision: wrecklight-v6-engine-3`.
The stock tile-copy assembly is an additional compiler dependency for this
profile, so changed or missing patch input prevents complete coverage.
Complete older profiles remain valid; partial upgrades and mismatched save
revisions do not receive reviewed dependency coverage.

The Airworks event requires an explicit `bellows` or `skimmer` profile and its
exact Airworks actor owner at native slot 4 or 12. It publishes player and actor
positions, writes and reads the owning actor's five existing sampled locals,
and records the profile's phase, facing, arming, epoch and timer effects. Its
three compiled branches (`moveLeft`, `moveRight`, `afterMove`) remain authored
events with their own dependencies; both movement branches lead to `afterMove`.
The native call pops all six arguments before any branch can yield. Immediate
sampling and phase decisions now share one native call; this review does not
claim identical scheduler interleaving. Actor scripts remain editable under the
ordinary semantic index, with exact actor membership and ordering still guarded.

The r36 profile covers the Warden Deck and its selected player presentation.
The r37 alternative changes only the exact presentation-helper binding for two
reviewed HUD cue conditions; its dependency effects and other guards stay the
same. Ordinary presentation edits still invalidate an exact binding until their
semantics are reviewed in maintained source. There is no project setting or
refresh call that accepts arbitrary changed helper bytes.

The gameplay-feedback alternative reviews three files together: jump facing,
HUD acknowledgments and door guidance, and Map/Pause input and item labels.
Their variable and resource dependencies are unchanged; their gameplay behavior
is not claimed to be equivalent. Partial mixtures remain unsupported.

The Condenser-cue alternative keeps that feedback set and narrows the Bay exit
cue to the eastern doorway's height. It uses the same coordinate inputs and
notice values; lower Airworks guidance and the wider western approach remain.
This dependency review does not establish that the route has passed a native
playtest.

The r44 alternative adds HUD reads for Dash readiness, Brakemaw recovery and
the Sump return, plus the Condenser-capacity compiler alias. These reads apply
to map, pause and saved operations that can redraw the HUD, not every native
command. The earlier profiles keep their original effects. Ordinary actor
sprite changes still require unique current resource metadata and the same
reviewed actor layout; this profile does not accept missing or ambiguous assets.

The September Warden successor binds the nine changed helper inputs and the
complete added event, native helper, collision patches and resident art. Older
profiles keep their original bindings. Its seven explicit operations retain
their own VM reads/writes and compiled children; missing operations and inherited
object-property names are rejected. The Warden requires its Deck actor at native
slot 5, the reviewed fixed animation, and the exact 40×24 resident background.

The collision overlay substitutes `COLLISION_ALL` (0x0f) at closed seal cells,
then uses the stock scan's mask, coordinate progression and bank restoration.
This replaces the source collision byte, including any ladder bit. The reviewed
scene-load hook clears the private active/seal/material flags for every scene,
including LOGO. Rendering publishes the seal only after drawing its visible cells.
Shared hook reads of globals 8, 21, 58 and 59 appear as verified
`native-engine-render-read` resource dependencies, separately from each event's
direct VM access records. Variable-access-only queries do not include these hook
dependencies. The reset hook has no VM-global accesses.

This successor also accepts the two reviewed title background identities and
the original or Optical steel palette in slot 2. The other seven slots remain
fixed. An unassigned imported image does not invalidate the current title; once
assigned, replacement art must have a complete manual-color grid. Its bottom
60 startup cells must be uniformly 0, matching the legacy background, or uniformly
7, matching previously accepted native-generated metadata. The exact bound native
header supplies palette 7 for the visible menu; startup metadata does not replace
that header. `asset_update.copyTileColorsFrom` preserves the legacy grid exactly;
ordinary painting can then update the art above row 15 without writing reserved
UI slots. This is source eligibility, not build or playtest acceptance.

The combined profile binds one complete source set: September Warden, Map/Pause,
acquisition and title art together with V6 frame pacing, Airworks/grace callbacks
and the title score. It retains the owner interfaces, collision patches, title
alternatives and inactive source backup. Both stock collision and tile-copy
implementations are required compiler inputs. Its reviewed Warden RAM packing
changes private storage while preserving exports, timers, VM accesses and ordered
render effects. Earlier shipped profiles keep their original bindings.

The combined contracts use `-native-combined-v1`, version 3, and require the note
`Native save compatibility revision: wrecklight-sep17-v6-engine-2`. Only string
name/author changes are allowed in the descriptor; older save markers and partial
source mixtures remain unreviewed. Complete dependency coverage establishes
source eligibility. Linked RAM/stack use, timing, save behavior and game acceptance
require separate checks on the resulting ROM.

The sampling successor retains the complete scroll profile and reviews the
Warden's `sample_and_tick` operation. It binds the VM budget patch, native helper,
header and event compiler together. Only the exact Deck actor's direct root
update can use this operation, with the reviewed actor and scene ordinals and
five uniquely owned, typed local captures. Its dependency record includes the
sampled player and boss positions, the five captures, the tick's existing
effects, and both authored `shot` and `move` branches.

This operation batches the sampling prefix only when the remaining VM command
budget permits it, charges the original command count, and otherwise executes
the original prefix. The tick and branch instructions keep their own scheduler
positions. The source contracts use `-native-sampling-v1` and
`-native-sampling-curated-v1`, version 3, and the descriptor note
`Native save compatibility revision: wrecklight-sep18-sampling-budget-engine-1`.
Older profiles reject the new operation and retain their original bindings.
The sampling catalog's 276 contracts fit a 512-contract limit; the per-contract binding
and effect limits are unchanged. Runtime equivalence, stack use and performance
still require separate measurements.

The chamber-cache successor retains the complete sampling profile and changes
only the reviewed chamber-renderer binding. It reuses two resident source-cell
values within one call while preserving destination-priority reads and ordered
map writes. The descriptor note is
`Native save compatibility revision: wrecklight-sep18-chamber-cache-engine-1`.
The maintained exports are `CHAMBER_CACHE_NATIVE` and `CHAMBER_CACHE_CURATED`,
with `-native-chamber-cache-v1` and `-native-chamber-cache-curated-v1` contracts
at version 3. The chamber-cache 850-file bundled and normal-source fixtures both use
the curated profile, which omits the inactive source backup. Historical
sampling bindings remain unchanged. That release has 302 contracts within
the same 512-contract limit. This source review does not establish runtime
equivalence, stack bounds or a performance improvement for every input.


### Historical flat-collision/projectile profile

The flat-collision/projectile successor retains the released chamber-cache
profile and replaces two bindings: `project/engine_field_values.gbsres` disables
the unused slope feature, and the projectile patch avoids a second render scan
when the first scan finds no wings. Calls with wings retain both passes. The
descriptor note is
`Native save compatibility revision: wrecklight-sep18-flat-projectile-engine-1`.
The maintained exports are `FLAT_PROJECTILE_NATIVE` and
`FLAT_PROJECTILE_CURATED`, with `-native-flat-projectile-v1` and
`-native-flat-projectile-curated-v1` contracts at version 3. They contain 110
and 109 project bindings respectively and 13 contracts each. Both 850-file fixtures from that release use the curated profile. Released historical bindings remain
unchanged; the unshipped slope-only trial is not a supported profile. That release's
catalog contained 328 contracts within the same 512-contract limit. Source
binding, runtime equivalence and performance remain separate checks.

### Drive performance profile

The Drive performance successor preserves the flat-collision/projectile and
earlier profiles. It replaces eight source bindings covering chamber tile
reuse and packed cache storage, scroll invalidation, Drive sampling, and
projectile rendering. The emitted registry retains all `13` current curated
version-3 contracts. The normal build's public dependency query qualifies
the `12` command IDs used by this source, sharing `110` exact source bindings.

`DRIVE_PERFORMANCE_NATIVE` and `DRIVE_PERFORMANCE_CURATED` use the
`-native-drive-performance-v1` and `-native-drive-performance-curated-v1`
contract suffixes. Their fixed descriptor carries
`Native save compatibility revision: wrecklight-sep18-drive-performance-engine-1`.

The Drive Hall skimmer actor resource is an explicit exception to the usual
actor-edit rule: its eight-command sampling order, dead guard, typed captures,
global aliases and native handler belong to this profile's exact source
closure. Editing that schedule requires requalification; it is not accepted
by changing a source hash alone. No graph-contract or historical-profile
relaxation is part of this update.

### Three-phase boss profile

`BOSS_THREE_PHASE_NATIVE` and `BOSS_THREE_PHASE_CURATED` add a separate source
family with the `-native-boss-three-phase-v1` and
`-native-boss-three-phase-curated-v1` contract suffixes. They preserve the Drive
profiles, replace twelve native/source bindings, and add the Dynamo Colossus
sprite metadata, Crown countdown helper and Brakemaw guard helper bindings. The fixed descriptor carries
`Native save compatibility revision: wrecklight-sep18-three-phase-bosses-engine-1`.
The bound engine configuration provides 780 VM words. The existing 13 event
commands cover this source; it adds no public tool or event command.

Warden `tick` and `sample_and_tick` require four nonempty authored paths:
`shot`, `move`, `lowShot`, and `highShot`. The graph includes all four possible
paths and refuses incomplete arguments. Older profiles retain their two
optional action paths. The new sprite has 18 frames in its first fixed
animation; the exact Deck actor, slot, scene order, typed local captures and
sampling-prefix constraints still apply. The old Warden metadata remains
bound because that loaded asset can still contribute compiled state names.

Brakemaw's native hit consumption can advance phase variable 141 at the HP
floors, so slot-5 `hit` effects include its read/write access. The extractor
keeps the union of targets sharing a compiled slot, since an event's owner
does not establish the runtime scene. Crown's left native target reads the
cleared flag 98 and has no native HP field. Its authored admitted-hit path
consumes core health 97; those effects belong to the child script. The source
binds the new aliases for GuardianActive (96) and GuardianCoreHealth (97),
while retaining GuardianCleared (98) once.

Only this family accepts `COMBAT crownWaitTick`. Its explicit integer
phase/maximum pairs are `1:32`, `3:40`, `2:80`, `4:28`, `6:12`, `6:40`,
`5:72`, `7:24`, `9:16`, `9:40`, and `8:80`. The direct Relay-machine update
owner must retain compiled scene 11, actor index 8 and its six local aliases;
reusable-script contexts and ambiguous owners are rejected. The helper reads
Crown state, health, service, encounter epoch and L0–L4, then decrements L5 or
writes maximum + 1 on cancellation. Core health 97 is read only for phases
7–9. L5 is the only direct write. The four preceding stock captures retain
their own graph effects; this operation adds no actor, projectile, phase or
waitable-flag write and compiles no child path. The handler and helper must
both match the reviewed source closure. This contract does not establish a
performance gain or completed-fight acceptance.

The five private `ENEMY_CONDITION` kinds for Brakemaw use the direct Turbine
Vault update owner at compiled scene 9, actor index 4 (slot 5).
`brakemawSoft` reads captured camera L0/L1 and player coordinates 0/1.
`brakemawHardFloor` reads health, dead/Cutter/service flags, the captured
HUD/death state L4/L5, boss coordinates 138/139, and captured/current epoch
L2/150. `brakemawHardEndpoint` also reads facing 140;
`brakemawHardPending` additionally reads the remaining opening L3.
`brakemawHardEitherEnd` uses the floor read set without facing or L3.
All five only read game variables; the immediate conditional consumes their
temporary stack result. Their true and false branches remain authored, and
`__disableElse: true` excludes the false branch. The contract rejects malformed
branches, non-boolean else controls, extra arguments and changed owner/alias
bindings. The 24 authored sites exercise all five kinds; together with the
Crown countdown they make all 13 registered event commands used by this sample.
Globals 138/139 already exist in the game; adding their source aliases to the
profile does not allocate new VM variables or change the 780-word heap.

The acquisition cleanup also restores the stock dialogue frame and cursor
tiles. Its added `ui_load_tiles()` call uses the already-bound stock UI code
and assets; it adds no direct VM-variable access to the acquisition contract.

The `native-engine-contact-read` structural relation records globals read by
physical projectile admission, including the Warden damage cap. It is
separate from the later `COMBAT hit` and `WARDEN contact` event effects: the
cap is sampled at contact and is not evaluated again during hit consumption.
Private pending-hit storage and encounter flags are not VM-variable edges.
These source contracts do not establish ROM, gameplay or release acceptance.

Ordinary actor-event edits, actor positions and scene collision edits do not
require a new native-source hash. The index reads their current authored data
and checks the existing identity and layout constraints. Changes to native C,
headers or custom-event helpers need review because they can introduce hidden
dependencies. A successful build or playtest does not establish those effects.
Reusable rules may cover a specifically reviewed class of edits, but a checker
that accepts only two exact files offers no more flexibility than two reviewed
bindings. There is no general safe "accept changed C" switch.

### Opening direction profile

The curated opening successor adds one reviewed source family with the
`-native-opening-direction-v1` suffix. Its fixed descriptor uses
`Native save compatibility revision: wrecklight-opening-direction-1`. It
retains the historical profiles and requires one coherent handler, compiler,
native source, descriptor, and actor-layout match; bytes from other profiles
cannot be substituted.

Bay, Rivet, and Drive each allow their reviewed original background or one
specific additive background ID, metadata path, and dimension. These alternatives
belong to the same source family and can be selected independently. Another UUID,
another room's background, a changed path or dimension, or added parallax does
not acquire coverage. The successor also reviews Bay and Rivet's exact native
enemy ownership and new health/dead globals, and four Turbine continuation
graphs that may read and write the owning actor's local `L3`. Editing those
optimized graphs, their fallback branches, or their owner requires a new review.
Source coverage here does not establish a successful build, gameplay behavior,
or installation.

## What a review must establish

A `ReviewedEventContract` in `src/custom-event-dependencies.ts` records:

- A review ID and version, the reviewed loader profile, and the exported command.
- The complete handler's project-relative path, byte count and SHA256.
- The complete required helper/definition bindings, including data that affects
  exports, field handling, defaults, nested branches and resource resolution.
- The fields accepted by the handler, distinguishing editor defaults from values
  actually supplied to compilation.
- A maintained extractor that enumerates all relevant project variable and
  resource effects, plus only the child branches actually compiled.

Review the complete handler and the relevant helper/definition closure. Hashes
identify that reviewed source; they do not prove what it does. Bump the review
version when its interpretation or extractor dependencies change. The registry
fingerprint includes descriptor metadata and extractor function text, but it
cannot authenticate mutable state captured by a JavaScript closure. Extractors
must therefore use only their supplied immutable input/context and reviewed
maintained constants.

The current binding domain is the existing indexed project snapshot:
`project/**`, `assets/**` and `plugins/**`. A dependency on an external compiler,
SDK, patched engine materialization, emitted actor layout or an unindexed file
does not become verified merely by recording its path or a past build hash.
If those semantics cannot be established within the bound context, the entry
must remain absent or return `status: "incomplete"`. Do not add a broad path
exception, an arbitrary first-seen baseline, or execute a plugin to fill the gap.

## Resolving the handler

The reviewed GB Studio 4.3.2 source loads core handlers before project exports
from `plugins/*/**/events/event*.js`, keyed by exported ID. The registry requires
the exact handler and all dependency hashes/sizes from the complete index. It
does not infer export IDs with a text regex or depend on glob ordering to choose
between competing exports.

Missing or changed bindings, multiple matching exports, multiple reviews
claiming the selected handler, or another unreviewed export make the selected
review uncertain. An unreviewed export can also override a familiar core event;
an indexed graph cannot borrow that event's native semantics in this case.
Direct graph callers without the indexed binding map cannot establish reviewed
custom-event coverage.

`ReviewedEventRegistry` is injected only through the maintained graph/index
constructor options. The ordinary MCP uses the maintained default catalog; it
does not deserialize registry objects or executable extractors from a project.

## Extracting effects

Compilation receives event arguments merged with child fields, with child fields
taking precedence. The extractor follows that behavior and does not automatically
apply editor defaults. Unknown input fields, malformed children, unresolved
targets, unsupported access types, excessive results, thrown exceptions or an
explicitly incomplete effect result keep coverage incomplete.

An extractor receives a cloned, frozen input and context. Its complete result
can describe `read`, `write`, or `read-write` variable effects and typed resource
relationships. Resource targets must resolve uniquely, including scene context
for actor identities. Formal/local variables use the graph's existing binding
rules; an unresolved formal is not a global variable.

Only returned `events` branches are expanded. A declared but uncompiled branch
is not promoted to executable behavior. Authored structural preservation still
retains the underlying data, including opaque and commented content.

Results are bounded to 4096 effects, 256 child branches, 256-character target and
scene IDs, and 128-character relation names. The registry admits at most 697
contracts and 256 dependency/field rows per contract. These are ceilings, not
permission to omit a required dependency or truncate an effect set into success.

## Freshness and destructive changes

The existing plugin semantic generation remains separate from the public
project revision. Handler/helper/export changes invalidate that generation and
the reviewed graph fingerprint. An extractor may depend on other indexed
resources, so nonempty registries conservatively rebuild the semantic graph
instead of taking the optimization that revisits only a changed actor. They
also bypass the opaque-file shortcut: ordinary committed-path updates to helper
files publish new coverage, review evidence and semantic freshness immediately,
including when a helper is deleted, without waiting for a strong refresh.

Prepared transactions retain their existing strong refresh and semantic-generation
comparison immediately before publication. A helper changing after preparation
therefore refuses the write even if the public authored revision did not change.

Hidden variable and resource effects also become structural references, tagged
with their review identity. They protect native background ownership and
destructive resource operations. Same-scene deletion cannot discard a hidden
reference merely because the final authored-argument scan cannot see it. It
remains conservatively in use while its owner survives the transaction; removing
that owner removes the reference. The pre-edit index cannot prove dependencies
introduced by a proposed owner. Until proposed overlays are semantically
evaluated, indexed destructive batches conservatively refuse any simultaneous
creation or change of a surviving scene, actor or trigger, including non-script
field changes. Pure owner removal remains allowed when the remaining reference
checks pass. This guard applies even if no reviewed event was used before the
batch; it does not infer safety from an empty pre-edit reference set.

## Verification boundary

Focused inert fixtures exercise accepted bindings, real-versus-editor defaults,
compiled children, hidden variable/resource preservation, unreviewed/changed/
ambiguous exports, unresolved or incomplete effects, and stale pre-write refusal.
Fixture handler files are read as data and never loaded. The fixtures do not
certify Wrecklight's native closure, a compiler installation, an emulator run or
runtime gameplay.

SHA-256: a5d29014a902593a48c5c84da3110af6e89638514cb00d9d0d5ed44cef34aaa7