World
Everywhere the party walks, a town, a dungeon or the
World Map, is run by the same four parts. The loop in src/ lets the
party walk and deals with whatever interrupts it. The engine in src/field
moves everything that moves and draws the map, and the
map's own data, in src/map, says what the ground is like. And each
scene's own code, its overlay in src/scene, says
who is there and what happens; only that part knows anything about one scene.
The two engine folders take the names of the banks they
fill, not of what they do. How scenes and overlays fit into the whole game is on
the front page.
The field loop and its requests

While the party walks, the game asks once a frame whether something should happen. Stepping into a doorway, pressing A beside someone or a random battle starting does not act at once: it only raises a flag of its own, a request. The walk then stops, the game deals with the requests one at a time in a fixed order, and the walk starts again. Each kind of request has one flag, so at most one of each can wait. Leaving the scene comes first, so an event that ends by taking an exit, like this door, simply ends the scene.
A random battle is a way out of the scene too: the game remembers where everyone stood, loads the battle as if it were the next scene, and afterwards loads the scene again with everyone put back where they were.
SceneManager_ runs one scene and struct FieldWork holds the
requests. Running a
scene lists
all twelve requests in the order they are handled.
Scene entries

The engine knows nothing about any one scene. It asks the scene's code six questions: what can happen here, where the party arrives, who stands where, whether anything needs setting up, whether the leader stands in an exit area, and where an exit leads. Each answer comes from a function, so a scene can answer differently as the story moves on without the engine knowing any story: Vault gives one list of what can happen before its thieves are jailed and another after.
What can happen is a table of triggers. Each row says what starts it (talking to someone, stepping on a spot, searching, using Psynergy), whom or where it answers, when it holds, and what it runs. This is the row for the young man above:
{ TRIGGER_TALK, ACTOR_WELCOMING_YOUNG_MAN, CONDITION_ALWAYS, MSGNO(MsgVaultWelcomeToVaultTheTownAt) },The game runs the first row that fits, so a scene lists its rows from the latest point in the story down to the default.
The six questions are struct SceneEntryPoints at the start of every
overlay, and the rows are struct Trigger. Scenes
describes the entry table and its
tables, and Engine how an overlay is loaded. The front
page describes how scenes depend on the story,
and Places lists every scene in
story order.
Scene and area flags
A scene never undoes what it changed. The game keeps two ranges of game flags for scenes to use and clears them as the party moves on: scene flags whenever the party enters a scene, and area flags when it enters another area. Neither is cleared on a return from battle. A pushed stone pillar kept in a scene flag is back in place the next time the party comes in; logs floated in one room of a cave, kept in area flags, stay floated while the party moves between the cave's rooms. The front page gives the ranges, and Scenes says how a scene uses them.
Actors and their actor scripts

Everything on the field that moves or changes by itself, the party, the townspeople, the camera, even each footprint in the snow, is an actor running a small actor script. Every frame each actor runs the commands of its script until one says to wait. A footprint's whole script is "wait 120 frames, disappear". The player's control is itself a command of the leader's script, run once a frame: "move by the pad, wait a frame, repeat".
The actors are the 64 places of gActors, and the commands are
the SC_ macros of actor_, run by Actor_.
Field covers the
commands, the sprites and the views of one
actor.
Movement

The leader walks at one pixel a frame and runs at one and a half with B held. Each frame of walking, the game tests the ground just ahead. When the way is blocked it tries headings a little to either side and takes the first that is open, so the leader slides along a wall instead of stopping dead. Ground more than 8 pixels higher, or more than 12 lower, blocks the way as surely as a wall.
Actor_ steers the leader and
MapGrid_ judges each point it tests.
Field has the speeds on each kind of ground and how high a step can go.
Cells and metatile behaviors

A map is a grid of 16-pixel squares, cells, and each cell says three things: what is drawn there, how high its ground is, and what standing there does. That last part, its metatile behavior, is a number that walls and triggers are keyed on. Most numbers belong to the scene, whose trigger table says what each one does, so the same number is a door in one town and a chest in another. A few mean the same in every scene: the jars, barrels and wooden boxes anyone can search, as in the recording, ledges, the desert's sand and walls.
A loaded cell is struct MapGridCell, and the behaviors are
enum MetatileBehavior. Maps gives every
behavior and how the build makes each
map.
Map layers

A town or dungeon is drawn as flat sheets stacked on top of each other: the ground at the back, then walls and edges, then the characters, then roofs and treetops in front. That is how Isaac can walk behind a roof. No code works out who is hidden: the console draws its background layers and sprites in the order of their priorities, and the characters are simply drawn between two of the map's layers. Where a character stands can move it between the sheets: the cells behind a house put whoever stands there behind its walls as well as its roof.
The three map layers are BG3, BG2 and BG1 (BG0 holds
messages and menus), and ActorSystem_ gives each sprite the
priority of the cell under it.
Field shows how the layers are put on screen, and Maps how they share one grid.
The World Map

The World Map is a flat map tilted into perspective, so the land near the party looks close and the land towards the top of the screen far away. The console can scale two of its background layers, and the game gives every line of the screen its own scale: each line shows one straight strip of the flat map, and lines higher up show strips that are farther away and wider. When a menu or an event opens, the game draws the current view into an ordinary still picture, so that the windows can use the layer the tilt was using.
WorldMap_ works out each line's scale and
WorldMap_ makes the still picture.
Field works through the
lines, Maps the World Map's
data, and Running a scene the
picture of the whole world R brings up. The World Map's own places and events
are on the front page.
Random encounters

As the party walks, a counter fills, faster when running and faster on some ground than on other, and a battle starts when it is full. Each kind of ground belongs to a zone, which decides how far apart its battles are and which enemies can appear. A party that has outgrown a zone meets its battles less often there, and with Avoid none at all.
Encounter_ fills the counter and
picks the enemies, and each zone is a row of gEncounterZones. Running a
scene has the roll step by step, and
Battle what happens once it starts.
Field Psynergy

Using Move on a stone pillar slides it; using it where nothing answers shows the same hand and moves nothing. What Psynergy does to a scene is decided by the scene's own events, and the cast only draws it. A scene can answer a Psynergy just before its cast plays and just after: in Vale, the event after Move notes where the pillar now stands and makes the ground under it solid.
Field_ runs a cast and FieldPsynergy_ plays
it. Running a scene
covers every moment a scene can answer and each Psynergy's cast.
Limits
- 64 actors, and 64 sprites sharing 64 sprite anims, up to four each.
- 66 actor places in the field work, the party's 8 and then 58 for the scene's actor templates, though only 64 actors exist to fill them.
- One overlay loaded at a time, in the 32 KB of
gOverlayArea. - 256 scene flags and 256 area flags, each range reused by every scene or area.
- 104 encounter zones of eight formations each.
- 47 script commands, of which the last 11 act as
SC_END; a jump finds only a label within the first 1,024 words of its script. - A battle snapshot keeps up to 32 actors.
Running a scene
While the party is in a town, a dungeon or on the World Map, this code runs the scene from the moment it loads until the party leaves: it sets the scene up, hands the leader to the player, and deals with whatever stops the walk, a doorway, a random battle, the A button, the menu.
Scenes
Everything that makes a scene itself is in its own code here: who stands where, what each person says, what happens when the party steps on a doorstep, searches a jar or uses an item or Psynergy, and the events the scene plays.
Field
The field engine runs everything outside a battle that moves or is drawn: it keeps track of the party, the townspeople, the camera and even footprints, moves each of them a little every frame, decides whether the ground ahead can be walked on, and draws the map, a town as three flat layers or the world map tilted into perspective.
Maps
A town or dungeon map is one big square grid of 16-pixel cells, 128 on a side, and each of its three layers is a rectangle cut from that grid; the map's header says where each one starts, and the rest of the grid goes unused.
Last updated on
