This folder holds The Broken Seal's code for a field scene and what plays in it: the main loop that moves between scenes, random encounters, a scene's actors and events, the leader's steps, using items and Psynergy on the field, the commands scene scripts run, Djinn joining the party, the world map screen, and the slot machine.
See also: Field, the engine these scenes run on; Scenes, the overlays that give each place its events; and Maps.
| File | What it holds |
|---|---|
| object.c | the guide to the field object; it includes object_internal.h, then the parts under object/ in ROM order |
| psynergy_effects.c | the guide to the field Psynergy and event object; it includes psynergy_effects_internal.h, then the parts under psynergy_effects/ in ROM order |
| *_internal.h | each object's includes, and the macros, types and inline helpers two of its parts use; they place no bytes |
| colorfx.c | the slot machine (the reel game) and an LZ packer, linked in another bank |
| fxdata.c | the objects' constant tables: object scripts, curves and lookups |
| battle_cue.c, zonedata.c | the battle music of each encounter, and the world map's encounter zones and Djinni battles |
| location_rules.s, scene_rules.s | the encounter zones, music and place names of field scenes |
| scripts.s, arcspark.s, swatch.s | object scripts and pictures |
| encounter.tsv | the 104 encounter zones: rate, level, enemy groups and their weights, each row named by its place in the zone column |
The prototypes are in games/tbs/include/unit/object/. Each part opens with a line saying what it holds: head -2 object/*.c psynergy_effects/*.c lists them all. The link order of the folder's objects is in games/tbs/objects.tsv.
The same locals carry the same names: work for the field work (or a part's own work block), scene for the effect scene, object and actor for an actor, leader for the party's leader.
Functions are named for what they act on: Scene_, Encounter_, Field_, Event_ and FieldEvent_ (scene script commands), Object_, ObjectMotion_, ObjectTable_, Marker_, Camera_, Djinn_, DisplayTransition_, WorldMap_ (entering and leaving world map events), EffectSlot_, ReelGame_, and the prefixes of the engine's other families. Field Psynergy effects are FieldFx_, a kind's runner named for its Psynergy (FieldFx_RunCatch). BattleFx_, BattleEffect_ and RunBattleEffectNN here are older names for field Psynergy code that other folders or ⚓️'s twins also use; they keep them until a rename across folders.
The spellings some sites keep to match (the field work, the effect scene and the map's view are each reached three ways), and the comment markers, are in Matching.
Field_RunScene (object/run_scene.c) sets a scene up, runs its initialization, fades it in, and then alternates between two states. While nothing is pending, it hands the leader to the player and calls Field_ProcessStep once a frame. Anything that should interrupt walking (the leader stepping on a cell with an event, a random battle, the A button, the menu, an exit) does not act at once: it raises a request, which is a field of the field work (work->exit, work->event, work->battle and the rest), and walking stops as soon as Field_CountRequests is not zero.
The loop then handles the requests one at a time, in a fixed order: the exit (exit), a raised event (event), a random battle (battle), a touched or exit cell (action), a pushed tile (input), the A button (examine), the menu (menu), talking to an actor (descriptor), searching a tile (tile), Psynergy (command), an item (item) and the pause menu (start). After each one it starts again from the top, so an exit always wins: when an event's script takes an exit, the scene ends before any other request that was raised with it is handled. The exit's kind is what Field_RunScene returns, and Scene_TakeExit loads the next scene from it.
A random battle is an exit too. Its handler snapshots the actors (ObjectTable_Snapshot), sets the next scene to SCENE_BATTLE and raises the exit EXIT_NONE (999), so the next pass of the loop leaves the scene; the battle runs as a scene of its own, and the field scene is loaded again afterwards, with the party where it was.
The saved actors and their parallel slot, animation, sprite-flag and priority arrays form ObjectTableSnapshot in object_runtime.h. The slot list ends at an empty entry, or at the snapshot's capacity when full. Restore keeps aside each current actor's sprite before copying its saved state, then reinstalls that pointer: the old actor state must not replace the new scene's sprite ownership.
Because requests are fields, not a queue, each kind holds at most one, and raising one twice before it is handled is the same as raising it once. An event's value is the event to run, or a negative code: -1 when characters fell to poison or hazardous ground, -888 to show the world map picture (Map_ShowWorldMap) and -889 for BattleFx_RunVisibilityTransition.
This shape is why scene code can be written as straight-line cutscenes: a handler runs a script to its end, waiting with WaitFrames as it goes, and the walking loop resumes only when every request is done. What must move during a cutscene runs as tasks and object scripts (see Runtime and Field).
Map_ShowWorldMap copies the decoded picture into background VRAM before psynergy_effects/world_map.c uses gMapCellBuffer for its cursor, markers and place-name window. Its marker task owns that work until the screen removes the task and releases its window and tile-cache entries. Map_LoadAreaGraphics can then reuse the scratch to restore the field graphics.
Visible markers are packed into the sprite list, independently of actor slots. The nearest-place frame follows them, while the cursor keeps the last entry. This lets hidden places consume no sprite entries without changing which actor each place-table row describes.
Field_UsePsynergy (object/psynergy.c) pays the PP, runs the scene's Psynergy events and plays the effect of the ability's field kind: psynergy_effects/dispatch.c runs the kind's handler, cast with no target (BattleFx_Run) or on one (BattleFx_DispatchRequestKind). Each kind's effect is the part named for it, such as psynergy_effects/reveal.c, and each of its entry points opens with the abilities that reach it:
A field scene's zones come from gBattle_LocationRules (location_rules.s): the first rule matching the scene and entrance gives the zone of ground 1, and grounds 2 to 7 take the zones after it. The world map's come from gWorldMap_EncounterRules (zonedata.c), by the terrain under the leader. The zone is a row of encounter.tsv, whose zone column names the place:
Zones with rate 0 are fought only by slot: the scripted battles a scene asks for (Field_RequestBattleFromEncounterTable), the mimic chests (zone 99) and the Djinni battles (zones 100 to 103, gEncounter_AreaEntryTable).
The field kinds are named from the type column of actions.tsv and the Psynergy the English release gives each; the requests from what the loop does with each; the encounter columns from what Encounter_SelectEnemyGroup computes with them. The zone names in encounter.tsv are the places whose rules select them.
Still unknown:
Source: src/object