At a glance

MechanismCarrierStepperWhat it animates
Walker tablescene bundle type-6 slotFUN_8001ADA4 case 0xBpalette-cell cycling: water, waterfall shimmer
Ambient move-VM treeprescript stager records + MAN partition-1 scriptsmove VM + render tail FUN_80021DF4palette pulses, texel scrolling, lightning, ambient sound
Strips and morphsmove records / bundle type-7 packmorph stager FUN_8001C604texel strip frames, vertex deformation
Particle emitterfield-overlay template + MAN section-4 regionsFUN_801D6058 + pool FUN_8003F348drifting fog and mist

The four carriers

Scene load Bundle type-6 slot palette-walk table MAN partition-1 one field-VM slice each Bundle type-7 slot VDF morph pack Field init spawns one emitter Walker actors park row onto a cell Water shimmer palette cycling Ambient move-VM tree op 0x34 sub-3 installs Mode 3 HSV cycler Mode 4 rect scroller Pulses lightning Waterfalls energy columns Morph lanes envelope per actor 0x0A Vertex morphs substituted at draw time Emitter 24 draws a frame gate: op 4C 30 Fog pool 80 additive half-sheets Ground mist view-space billboards
Four carriers, all authored per scene on the disc and started when the scene loads. None of them is animated vertex data in the environment pack: the walkers and the effect tree repaint VRAM (palettes or texels) under meshes that never move, the morph lanes substitute vertices at draw time, and the emitter draws additive sheets.

Palette walkers

The world map’s ocean animation is not kingdom-only. The asset dispatcher installs any bundle’s type-6 slot, and field init spawns one walker actor per entry. Each walker copies successive frames from a “park” palette row onto a destination cell, so the palette - and every texel drawn through it - cycles.

Twelve bundles ship a populated table: the three overworld maps (eight entries, byte-identical), two single-entry scenes, and a seven-scene family sharing one two-entry waterfall table. Every other scene’s slot is a four-byte placeholder. Resolution is by type byte, not slot position.

The ambient effect tree

Most ambience is a tree of small invisible actors running move-VM bytecode out of the scene’s prescript bundle. A part draws no mesh; its render tail edits VRAM every frame, or it fires sound cues.

Scene entry is not a second mechanism. The placement installer runs each partition-1 placement through the field VM for one frame slice, and every op 0x34 sub-3 that slice reaches installs one stager record - the same instruction a script reaches at run time. The part is seated at the executing actor’s position, not the player’s.

Render modeWhat it doesSeen as
3 - palette-cell HSV cyclercaptures a VRAM rect, then every frame converts each texel to HSV, adds the running H / S / V offsets and an optional white blend, and writes the row back (FUN_80019D50)pulsating flesh, lightning flashes
4 - VRAM-rect scrollerrotates an authored texel rect in place on a period countdown; no vertex, UV or palette changesfalling water, energy columns

The pulsating ground never moves a vertex: it is palette-space colour cycling under a static mesh. The bytecode vocabulary these trees are written in is the move VM’s overlay extension. Record 0 of the stager bundle is not an effect at all - it is the scene’s sound-effect descriptor bank.

Strips and vertex morphs

The bundle’s type-7 slot is a vertex-delta pack. A morph lane holds an envelope per actor, and the renderer substitutes the blended vertices at draw time - the source mesh is never rewritten. Move-VM op 0x0A drives the lanes from the ambient tree; a few scenes install theirs from a placed actor instead.

The fog pool

The fourth carrier is a single actor spawned at field init. Each frame it takes twenty-four independent draws, each with a one-in-sixteen chance of bursting one to four particles at a point inside the camera’s visible-tile span.

  • The gate is script-driven, not per-scene data. _DAT_8007B854 is raised by op 4C 30 and cleared by 4C 31 (see op 0x4C). It is the ambient-particle master gate; it is not an input lock.
  • The emitter names tiles and draws nothing. Each burst goes to the spawner, which checks the walk box, the region enable and the cap, and fills the pool at _DAT_8007B7E0 - eighty records.
  • Each record draws as two additive half-sheets, and a sheet is a view-space billboard, not a world-space quad.
  • The pool ages once per game frame, by the frame step. The field render pass walks it once a frame and ages each record by its rate times the VSyncs that frame took (0x1F800393), so a 30 Hz frame ages it by two VSyncs at once. The walk draws no random numbers; only the spawner does. The port steps it once per sim tick on both hosts.
  • A warp entry - a return from battle, a minigame or a movie - skips the spawn, so the emitter exists only after a real field entry.

Photosensitivity guard

An engine enhancement, not retail behaviour. The casino dance venue’s entry tree runs twenty-one palette cyclers, and one row re-keys its brightness offset between full black and neutral on consecutive ticks - a full-swing strobe far above the three-flashes-a-second guideline. The port’s reduce_flashing option (default on) slews only the applied brightness and white blend toward the simulated target; hue and saturation pass through untouched, and the parts themselves always advance retail-exact. Turning it off restores the retail steps.

In the port

Walker tables decode in scene-formats::clut_walk and animate in engine-scene::clut_walk_anim. The tree is engine-core::world::ambient, installed by the scene-entry pre-run that executes each op 0x34 sub-3 once; its render tails are engine-field::clut_cell_fx and engine-field::vram_scroll. Fog is engine-field::fog_particles and ambient_emitter. The separate volumetric ground fog is an enhancement and never touches this pool.

See also

The install chain instruction by instruction, the part pool and its control block, both render tails, the morph pack format, the fog records and the overworld draw order are in docs/subsystems/field-ambient-fx.md.