| notes | ||
| traces | ||
| LICENSE | ||
| README.md | ||
Alien Front Online: reverse-engineering notes and reference traces
The working material behind alien-front-online-browser, the browser rebuild of Alien Front Online (Dreamcast, 2001): what was learned about how the original game works, and recordings of the original that the rebuild is checked against.
There is no game code or data here: no disassembly or decompiler output, no memory dumps, no save states, no files from the disc. The notes describe behaviour (rules, formulas, constants, data layouts, where things are in the retail USA executable) in our own words. The traces are numbers measured from the running game.
What is here
notes/re-notes.md: the notes, section by section as each system was worked out (vehicles and ground contact, guns and shells, damage, special weapons, pickups, AI, the mission script language, game modes, cutscenes, HUD, sound, effects, the online protocol, file formats). Addresses are for the retail executable loaded at 0x0C010000.notes/decisions.md: the design decisions of the rebuild and their reasons.notes/asset-plan.md: the disc's file formats (models, textures) as decoded.notes/trace-format.md: the format of the trace files.traces/*.csv: the reference traces. Each records, for one scripted scenario played in the original, chosen values every frame (positions, speeds, angles, health, timers, random seed...). The header lines name the save state and the scenario.
How the rebuild is checked
The original runs in the Flycast emulator with a Lua probe that loads a save state, plays scripted controller
input and writes values from the game's memory each frame. From a save state the game is deterministic: the
same inputs give the same values every time. A test then gives the rebuild's simulation the same starting state
and inputs and compares its values with the recording. The probe, the recorder and the tests are in the main
repository (tools/probe.py, tests/record_references.py, tests/replay_*.py); to run them, clone this
repository beside that one and run python tools/get_traces.py there.
What runs from these two repositories and a disc alone: every comparison but one.
- From traces: tank driving and terrain (
replay_drive,replay_vehicle,replay_terrain), the main guns and combat (replay_gun,replay_combat,replay_alien_gun), the Alien vehicles (replay_alien,replay_walker,replay_spwalker,replay_hover), breakable scenery, the special weapons (replay_special,replay_special_fire,replay_special_damage,replay_airstrike), pickups, hit sway, computer players' turning (replay_ai_turn), and the whole-simulation runs (smoke_game,smoke_rules,check_wasm_parity_game). - From RAM excerpts (
traces/ram/*.json): the computer players' world update, controller and path search (replay_ai_world,replay_ai_ctrl,replay_nav) and the two walker skeleton checks. These tests start from the game's state at one frame. A whole memory snapshot is the game's memory and can't be published, so each excerpt holds only the bytes the tests read from it (object and AI state: positions, timers, paths, bone matrices), at their addresses; the program's own image is taken from your disc. A test that reads a byte its excerpt doesn't hold stops with an error (tests/ram_snap.py). - Not runnable from the public material:
check_collision_build(it compares the collision world built from the disc with one exported from the game's memory). Tokyo's disc-built world differs from the running game's only in the order of a few walls within their grid cells; every Tokyo replay gives the same result with either.
Re-recording the evidence yourself
The published recordings are only as good as the claim that they came from the game. You can check that, and test the rebuild on recordings of your own, with Flycast (the project used 2.7), the game, and the main repository's probe.
Setting up the probe. In Flycast's flycast.lua (in the folder Flycast keeps its configuration; for a
portable install, beside the program):
AFO_REPO = "/path/to/alien-front-online-browser"
dofile(AFO_REPO .. "/tools/flycast/afo_probe.lua")
(On Linux that folder is ~/.config/flycast/.) The project's recordings were made with these Flycast settings,
and a re-recording should use the same: dynamic recompiler on, SH4 clock 200 MHz, 16 MB RAM (no 32 MB mod),
region USA, broadcast NTSC, real BIOS (not the HLE BIOS), DSP off, networking off, the game loaded from a disc
image named Alien Front Online (USA) (Flycast names save states after the image's file name). In emu.cfg:
Dynarec.Enabled = yes, Sh4Clock = 200, Dreamcast.RamMod32MB = no, Dreamcast.Region = 1,
Dreamcast.Broadcast = 0, UseReios = no, aica.DSPEnabled = no, [network] Enable = no.
Start the game in Flycast with networking off, and leave it running unpaused. python tools/probe.py ping
from the main repository should answer. The probe writes only under data/work/probe/ and never saves a
state.
Save states. Every recording starts from a save state (tests/record_references.py, SLOTS): slot 0 an
M1 Abrams and slot 1 a Walker on Washington DC, 2 an SP Walker and 3 a Hovercraft on Tokyo, 4 an MK2 and
5 an M1109 on Ancient Ruins (Flycast's own slot numbers are one higher), each in a free battle against
computer players. Object addresses in the recorder are for the project's own save states; with yours, the
player's vehicle will usually be at another address (tools/probe_fields.py, OBJ; python tools/probe.py snap NAME and search the snapshot for your position to find it).
Check that a recording is genuine. From the same save state the game is deterministic: the same inputs give
the same values on every run. With the project's save states, python tests/record_references.py ref_fire_02
(and any other scenario) must reproduce the published trace exactly; snap_nav, snap_ctrl, snap_drop write
the snapshots, and running the excerpt tests on them with AFO_RECORD_EXCERPTS=1 must reproduce
traces/ram/ byte for byte.
Test the rebuild on something new. With save states of your own, record scenarios with your own inputs
(add them to record_references.py; the existing ones show the form: fields to record, timed inputs, the
slot), then run the matching replay on your trace, e.g. python tests/replay_terrain.py data/traces/your_trace.csv (most replays take a trace path; a few, such as replay_gun, replay_combat and
replay_alien, are written around their published scenarios and need theirs named in the file). Your numbers
won't equal ours; what must match is the simulation against your recording. For the
excerpt tests, take a pair of snapshots one frame apart and pass them: python tests/replay_ai_world.py data/work/probe/a.bin:data/work/probe/b.bin. A scenario where the simulation and the game disagree is a bug we
want to hear about.
What is verified, what is approximate, what is missing
This is the state as we know it. "Exact" means the simulation's values equal the original's bit for bit over the recorded traces; it does not mean every possible situation has been recorded.
Exact against traces
- Driving for all six vehicles: speed, turning, strafing, heading, position; the tanks' body (suspension, tilt, ground contact) with heights within 1e-5 m; walls and sliding along them; both walkers' skeletons and leg placement; the hovercraft.
- Main guns of all six vehicles: firing rules, reload, turret and barrel, recoil, shell flight; shell hits on vehicles, scenery, walls and ground.
- Damage, friendly-fire and spawn-protection rules, wrecks, respawn-point choice.
- All 18 special weapons: launch, flight and guidance, firing rules; damage of the Army ones.
- Pickups: toss, flight, collection, what a kill drops.
- Breakable scenery: damage and collision removal.
- Computer players in battles: the path graph and search, line of sight, the per-frame world update, turning.
- The simulation gives the same results as WebAssembly and as native code.
Known small differences
- The computer players' controller matches 99 of 105 recorded steps; six differ slightly in aim or steering, cause not yet found.
- A walker's planted foot can sit up to 0.25 mm off the original's height.
- Where a test allows a tolerance it says so in its output:
replay_drive(1e-7 on speed),replay_walker(0.001 on the foot heights above; its other fields are exact). replay_vehicleonref_aim_01stops matching at frame 636 by design: that trace's tank hits a wall there, and this replay models the vehicle alone;replay_terrainonref_terrain_04(the same inputs, with the world) covers it.
Rebuilt from the code but not compared against recordings
- The match as a whole. Each part above is checked on its own; no complete match has been compared end to end with the original (its random numbers also feed effects and voice lines, so a free-running comparison drifts).
- The campaign: the mission scripts are the original's and all 60 run to the end here, but the missions were not compared with the original in play. Mission-only computer player behaviours, foot soldiers, turrets, cutscenes.
- Game modes' rules beyond their scripts, the Tokyo and Siberia trains, Fortress.
- The damage of the Alien special weapons.
Approximate
- The camera's collision with scenery; a few contact tests use a simple box where the original tests meshes (train cars, foot soldiers run over); fog density per map; some effects (stretch, a few muzzle effects).
- The HUD, menus and screens are laid out from the original's code and checked against screenshots, not pixel-exact.
Different on purpose
- Online play: the messages are the original's, but our server acts as the host console (in the original, the consoles share that work through a relay), with a few messages of our own (Fortress objects, text chat). It does not connect to the original's revival servers.
- Additions: text chat, a lobby in the browser, controller remapping, the ARCADE options, optional upscaled art, Fortress against computer players.
Missing
- Voice chat; the original's options and free-play ranking screens; the attract-mode demo; a few menu sounds.
License
The notes and traces are under the Creative Commons Attribution-ShareAlike 4.0 International license
(LICENSE): you may copy and adapt them, with credit, and share adaptations under the same license. The
rebuild's code is in its own repository under the AGPL-3.0.
Alien Front Online is a trademark of Sega. This project is not affiliated with or endorsed by Sega.