sm64.sql

The entire game, as a database you can query in your browser.

Pick an Area to see just that area on its own map, or All areas to overlay them. Hover a dot for details; scroll to zoom, drag to pan, double-click to reset. The top-down Level map background uses per-area level images from STROOP (MIT) registered to world coordinates. Camera zones overlays the level's CameraTrigger boxes from camera.c — the invisible volumes that change the camera's behaviour while Mario is inside (hover a box for its event function and the decomp's own note). Only nine courses define them; the boxes have real height, so they show in the side views too.

Rows are the game's object lists (behavior.obj_list); click one to expand it into its behaviors. Each cell counts placements in that level/course (object JOIN behavior JOIN level); darker = more. Click a cell — or a row/column label — to copy the JOIN behind it to the clipboard.

All three tiers at once, sized by placement count and coloured by object-list type. Every placement counts: object, macro_object and special_object are each resolved to a behavior. Use the toggle to flip the grouping — level ▸ type ▸ object, or type ▸ object ▸ level to see how each object is spread across levels. Click a region to zoom in; use the breadcrumb to come back out. Click a leaf tile to copy its placements query.

Every object is a node; edges are relations mined from the behavior code — spawns, morphs into, seeks. Node size is how often the object is placed in the game; the small dashed-ring nodes are ghosts — spawned at runtime but never placed. Toggle a relation in the legend, hover to focus a node's neighbours, and click for its full dossier (with links to the decomp source). Scroll to zoom, drag the background to pan. Highlight code-only spawns lights up the spawns that live only in the C (literal calls or data tables) and are invisible to the bytecode.

Mario is a state machine: each frame he is in one action (ACT_*) and transitions to another by calling set_mario_action. Every action is a node, clustered and coloured by its group (stationary, moving, airborne, submerged, cutscene, automatic, object); each arrow is a transition mined from the action's handler and the helpers it reaches. Node size is the transition degree, so the hubs (FREEFALL, IDLE) are biggest; dashed-ring nodes have no handler of their own (the zero state and engine remap targets). Toggle a group in the legend, hover to focus an action's neighbours, click for its dossier — id, flags, handler, and the transitions in and out (each with the trigger condition and a link to the decomp source). Selecting an action also labels its outgoing arrows with the condition that fires them (e.g. m->input & INPUT_Z_PRESSED); hover any label for the full text. Scroll to zoom, drag the background to pan.

Super Mario 64 saves to a tiny 512-byte EEPROM, and the whole thing is one nested struct. The colourful minimap at the top is the entire chip at once — every block coloured by type, so the four files (and their backups) show as a repeating pattern — with a box marking where you are; click any block to jump straight there. Below it, a ruler maps each level you've opened onto the whole chip, so you can see how big a region really is (a 4-byte word vs. a 56-byte file) and how far you've zoomed in. Each bar below that divides its parent in byte order, sized to scale; click any tile to drill in — the level you open is appended below (ancestors stay put, a funnel links them), and the breadcrumb or an ancestor tile drills back out. Drill down through SaveBuffer → the four files (A–D, each stored twice — a primary and a backup so a corrupt copy can recover) → one SaveFile → its courseStars (one byte per course — drill a course to see its six named stars, its 100-coin star, and the cannon bit, which by an SM64 quirk actually unlocks the previous course's cannon) or the flags word (its 32 progress bits: caps, keys, doors, cap-thieves, secret stars — with the gaps where no SAVE_FLAG_* is defined). It's all computed from save_struct / save_field / save_flag, and provably tiles every byte (see save_struct_coverage). Hover a tile for its offset and the decomp's own note; click a leaf to copy its query.

Loading the database…