Skip to content

packages/missions ​

The game document and the mission language. Isomorphic and deterministic, like the simulation: the server runs the interpreter, the tools and the platform validate documents with it. The language is explained in the Missions guide; the design is in the Game design document §9 and the Technical specs §9.5.

FileWhat
schema.tsThe zod schemas, strict (an unknown key is an error): GameDoc (a level by name, its named places and zones, the game's rules, its missions), Mission (how it starts, its own items, its actors: vehicles, groups of enemies (chasers), items on the ground, containers, the level's doors (a keypad's code) and cameras, NPCs (npc: the contact role, a person to talk to; guard and civilian, of stealth) and terminals, its counters, its objectives goto, steal_vehicle, deliver (a vehicle or items), pickup, collect, use, give, survive, defend, lose, escape, eliminate, destroy, talk, unlock, incapacitate, sneak, race, escort, chase, photograph and wait with their branches (next), several at once in a parallel group (LeafObjective, GroupObjective), its rules, its stealth hooks, its reward, and its phone's contacts, dialogues and apps), Rule (when an event happens, if a condition holds, do the actions; or while a condition holds, enter, every and exit), Condition (flags, comparisons, exists, hasItem, near, hasApp, formIs, all, any, not), Value (numbers, counters, clocks, the queries count (the player's items by tag among them), distance and health, the player's wanted stars, an app form's form field, the alert phases, the kills, alarms and sightings), Action (setWanted, give, take, lock, unlock, spawnItem, alert, calm, cameraOff, cameraOn, and the phone's message (with its Replys), call, addContact, removeContact, installApp, removeApp, waypoint, clearWaypoint among them), the event names (EVENT_PATTERN with prop:<id>.destroyed, message:<id>.read and wanted:…, GROUP_EVENT_PATTERN, STEALTH_EVENT_PATTERN), the prop actor (a light piece of the level), and the ids (ID_PATTERN). The city: zones of a kind (ZONE_KINDS, a restricted zone's raises, a spawn area's role), places with a spawn role, paths (a race's gates, a patrol), the NPC roles driver, target and VIP, schedules, the shop actor, the race objective, the time value and condition, the actions setClock, setPace, setSignal, and the rules prices and clock.
migrate.tsThe game document's format across releases: GAME_SCHEMA_VERSION, the steps from one format to the next (GAME_STEPS: 1 → 2, a mission's play), migrateGame and parseGame, which every reader of a document goes through; a newer format is refused (SchemaTooNewError).
play.tsHow a mission is played, its defaults filled in (playOf: solo, co-op or versus, its players, its teams (a free-for-all's one a seat, eachTeams), lives, what a death does, retries, friendly fire, the run room's ambient life; isSolo, runAmbient). A mission without play is solo. The seats a live run may fill under its joinInProgress (openSeats: the seats it lost until its first checkpoint, or up to every team's most).
expressions.tsThe values and conditions evaluated against a Scope (what a player's mission knows on a step), and the walks the validator and the moderation share: the sub-conditions, the values compared, the queries, every action of a rule and of a mission (its dialogues', apps' and replies' too), the counters a text shows ({counter:<id>}).
runtime.tsMissionRuntime, the interpreter: fed the facts of a step (the tick, where each player is, how healthy and how wanted, where each mission vehicle is, its health, who drives it and whether it was carjacked, the members of the mission groups, what the players carry, the missions' pickups, containers and doors, the item events), it answers with commands for the host (spawn or despawn a mission vehicle, spawn some of a group, despawn a group, set a player's Wanted level, lay items out, spawn a container, bind, lock or unlock a door, spawn an NPC, bind or switch a camera, raise or call off the alarm, give or take items), each player's tracker view when it changed (with the hold clock of survive, defend and lose), their notices and their phone when it changed (the facts carry the people, the terminals and what the players asked of their phones). Missions run per player, one at a time; when rules run in document order on the step's events, then each while condition is checked once; the events an action causes wait for the next step; at most 50 actions a player a step. The city: the clock from the facts (time:HH:MM), a zone's trespass, a race run (race commands for its rivals, its gates counted, raceView on the tracker), the roles' events, setClock/setPace (clock commands), setSignal (setSignal commands), shops spawned, rewards paid into the player's Cash (pay). The verbs past v1: an objective's progress kept per objective (a parallel group's members each their own), the handOver, flee and bindProp commands, the photos' facts and the camera's notes, the arrests, the props, the sightings; the tracker's members, targets, escort, chase, hand-over spots, photo subject and party. A room is a hub (solo missions only) or a run (RunOptions: one mission held by the stand-in holder 0 for every seat; rebind on a reconnect, lives per seat or team, retries from the last checkpoint, each seat's book, downs and credit, its sabotage (an attempt failed by its hit on an escort's VIP or a non-lethal target within 10 s), runView, runEnded once). Versus: an objective's team (only its members advance and see it), a winner (win:<team>, the action win, the last team left, a forfeit) or a draw, catch (the respawn and spectate commands), eliminate a team, {team} refs and queries, the team:<id>.… events, a race between the players scored per seat and placed, players out to watch.
phone.tsEach player's phone, as the interpreter keeps it (the Phone guide): its entries (contacts, messages with their replies, apps, the call log, the waypoint), the conversation ringing or under way and the screen open; what a player asks of it (phoneInput, every reply, choice and button checked when picked), the phone's actions (phoneAction), what time and distance do (phoneTick), a run's end (endRun) and what it shows (phoneView).
(parties)MissionRuntime.join(player, party): a party's members play one mission, held by its first member and stepped once with all their facts (anyone of them advances it, a hold lasts while any stands, the stealth book and the garages count every member, the tracker, notices and phone messages reach everyone, the reward whole or split by rules.partyRewards, the next member takes over when the first leaves); the checkpoint command for rules.respawn: mission. See Missions.
validate.tsvalidateGame: every reference resolves (places, zones, vehicles, groups, counters, where objectives lead, items against the common ones the context names, item actors, containers, doors, NPCs, cameras, the phone's contacts, dialogues, apps, nodes, screens, buttons and form fields), every line of a dialogue can be said, ids are unique (items across the game), the objectives form no loop and some path completes the mission, the time limits along the longest path fit in 20 minutes, every repeating spawn is capped, the budgets hold (12 enemies a mission, 8 while rules, 24 queries checked every step), the timers a rule waits for are started and the flags it tests are set; with the level, every place lies on it, every vehicle's, enemy's, NPC's (and its patrol's) and container's place is open ground and every door or camera actor has a door or a camera of the level within 3 m. Issues are paths into the document with a message and a severity. validateReach: every place of the game it is given can be reached from the spawn points (it builds the navigation grid, so the builds run it, not every load). placesUsed: the places a game names somewhere (a zone's, an actor's, a patrol's, an objective's, a marker, an action's), which the platform's builds check for reach on a generated level, whose other places are only offered. The city's checks: zone kinds and their fields, race paths and their gates, rivals that are drivers, schedules, prices of known items, setSignal places. A mission's play: its players, its one co-op team or a versus mission's two or more (their spawns, their players adding up), joining under way not built yet; every versus team with something to do and something that ends the run for it; the teams' language (team, win, catch, {team}, team: events) naming the mission's teams, where it belongs.
content.tsThe bundled games by level name (@foi/missions/content): the server plays a bundled level's game unless FOI_GAME names another file.
content/*.jsonThe bundled game documents, one per level that has one: main-riverbend (Smart City Pilot: a rental across town against the clock, a race once round the parkway, a consultant escorted to the stadium, the market's fountain photographed; and in runs of their own a co-op heist, Series A Withdrawal, and robbers and chasers, Hostile Takeover), test-compound (Zenful Campus: the night's clock and a non-lethal loadout, no missions), test-mission-basics (the objectives of v0), test-mission-logic (waves, counters, branches, enemies), test-inventory (Parcel Run: collect and deliver items), test-interaction (Office Hours: a mission item, a door actor, use), test-phone (Day One: messages, calls, a contact in person, the RentaCar app and its locked car, a keypad door, a kiosk), test-locks-garages (Repo Season: a locked vehicle, giveKey, unlock of a vehicle, deliver to a garage; the keys of the level's parked cars) and test-stealth (Clean Exit: a camera actor, a civilian NPC, incapacitate, sneak, the hooks unseen and withoutKills) and test-safe-zones (the griefing controls' rules: the plaza a safe zone, four seconds a ghost) and test-mission-verbs (give, escort, chase, photograph, wait, escape, destroy, a parallel group, a message read, the Wanted level's rules) and test-versus (Versus basics: robbers and chasers, on a short clock and with a caught robber out to watch, and a race of every player on their own).

The server side is apps/server/src/mission-host.ts (facts from the simulation, commands carried out, the groups of enemies spawned as chasers of the AI, the tracker, the notices and the phone sent as text frames); the client draws the tracker and the notices (apps/client/src/gui/mission-blocks.ts), each target as a marker in the world and a ring on the minimap with the route line to the nearest (apps/client/src/ui/mission-route.ts over @foi/world's roadRoute), and the phone (apps/client/src/gui/phone-blocks.ts). The mini levels test-mission-basics, test-mission-logic and test-mission-verbs and their end-to-end specs play missions through.