Dev
Architecture
How the code is laid out, the rules every system follows, and the pipelines that aren't a feature of their own (voices, decoration). What syncs in co-op and how is the co-op spec's: Co-op: the siblings together (CO1-CO6, and "The code" in its Tech). Every new feature answers the golden-rule checklist there before it's written.
Sim and scene
Scripts/Sim(assemblyGameMower.Sim) holds all game state and rules, with no scene dependencies: definitions (ScriptableObjects),Company+SaveData,ToolInstance,LawnGrid,MowerSim,MissionResult. The assembly can't reference presentation code: the boundary enforces it, not discipline.- Every company change is a command:
ICompanyCommand(Validate+Apply) run throughGameSession.Execute. In co-op, guests send the same commands to the host, which validates and replicates (CO1). - Commands know who ran them:
Company.Execute(command, actor)setsCompany.Actor(a player id;Company.NoPlayer= 0 outside commands,Company.HostPlayer= 1), and every bank-statement line records it (LedgerEntry.by). Bills and rent are on the company. The "who forgot, who broke it" blame is built on this. - Players vs company:
SaveData.players(PlayerData: id, name, body, look) holds what belongs to one sibling; the host is id 1 and always exists. Everything else is shared by the company. - Tools are instances with a stable uid and their own condition, so two siblings can share one car and a job can say exactly which tool broke.
- Scene components host a sim object:
Lawn,MowerControllerand the UI feed it world input (cuts, hits) and read it back for visuals, audio and the HUD. The sim never knows about the scene. - Randomness comes from
SimRandomwith a seed from state and a named salt (Seeds: how the game rolls its dice,Salts.cs). - Tests: EditMode tests for the sim live in
Assets/_Game/Tests/EditMode(assemblyGameMower.Sim.Tests). See Testing.
Code folders
| Folder | Holds |
|---|---|
Scripts/Sim | State, rules, commands, data definitions (no UnityEngine scene types) |
Scripts/Net | FishNet: NetCompany, NetPlayer, NetAvatar, the sync areas |
Scripts/Core | Session, input, Voice, shared helpers |
Scripts/Garage | The hub: grandma's house, HomeLawn, HubStreet, the stations |
Scripts/Garden, Lawn, Mower, Tools | A job's scene: the garden generator, the lawn, the mower, hand tools |
Scripts/Town, Ambiance | Streets, traffic, pedestrians, ambient sound |
Scripts/Store, UI, Characters, Sandbox | The store, screens and HUD, bodies and looks, the sandbox (Sandbox) |
Editor | The setup scripts behind the Game Mower menus (Tools & MCP) |
Saves and data versions
SaveData.CurrentVersion is 14. Company migrates an older save step by step on load. The steps worth knowing:
| Save | What changed |
|---|---|
| v6 | Story fields: playerName, playerBody, introSeen, dreams, story marks, netWorthYesterday |
| v7 | playerName moved into PlayerData (the players list) |
| v8 | Grandma's starter kit: dads_car → grandmas_car, the lowest-uid push → grandmas_mower (a bought Classic 46 stays) |
| v9 | Grandma's sticky notes (old saves: every note read) |
| v10 | Brother or sister (PlayerData.body, picked): older saves ask each sibling once |
| v11 | Street standing (streetStanding, starts at 40) |
| v12-v14 | Lawn memory (MO1), mower parts (MO4), mower care (MO5b) |
Data assets carry GameDatabase.dataVersion: v10 made m00 grandma's garden (25 cm) with the new tool and vehicle ids,
v11 added the street clients, v12 the districts (GameDatabase.districts).
The hub's house
GrandmasHouse (renamed from DadsHouse, same GUIDs; room ids stay house) is modular: Core, Garage, BackWing
(grandma's locked room) and FrontGarden (decor, no collider). Joint walls come in Solid/Door pairs (Join_Back_*,
Join_Garage_*) and Socket_* empties mark where extensions attach (EC7). HouseArtTests guard the child names the
code relies on. Game Mower › Rebuild Hub rebuilds the house, grandma's car and mower prefabs, the company and base
data assets and the Garage scene, reusing the materials already on disk.
Voices
What is voiced, by whom, is in Characters: the family, the street, the clients (the cast) and Sound: every sound comes from something. How it works:
- Only fixed lines are voiced. A line with runtime values (a name, a price, a day) keeps its text but plays a
fixed variant: dad says "kiddo", a dated voicemail plays a short greeting clip while the full text shows. Templated
lines get a fixed
*Voicescript (DadProudVoice,DadRegisteredVoice...). Mail, the paper and the bank stay text. - Scripts carry audio tags (
[sighs],[chuckles]) thatVoiceLines.Striphides on screen. - A clip's key is the speaker plus an FNV hash of the script (
VoiceLines.Key), so editing a line makes a new clip.VoiceLines.All()lists every voiced line. - Export: Game Mower › Export Voice Lines writes
ArtSource/voice/lines.json(cast, model, key, has a clip). Missing clips are generated with ElevenLabs (Tools & MCP) intoAssets/_Game/Audio/Voice/Resources/Voice/<key>.mp3. - Playback:
Core/Voice.csloads the clip by key (a missing clip is silent, the text still shows), one line at a time. Voicemails carry their clip key (MailMessage.voice, posted withCompany.PostVoice) and play through a telephone band-pass on the answering machine. The intro and subtitles wait for the clip's length when there is one. - Co-op takes: lines that talk to the siblings have a solo and a co-op version, both voiced (
players.Count > 1). - Client voices come from a small pool, picked per client with the same rule as the body (gender + seed).
Decoration
- Props use the shared palette texture and GPU instancing.
- Props outside the garden fence have no colliders and no lawn blockers.
- Ambient sounds are pooled and positioned by the garden generator.
Old step numbers in code comments
Comments written before the wiki say "EARLY_GAME step N". The old build plan is retired; its steps now live here:
| Step | Now |
|---|---|
| 0, 0b | Co-op foundations (CO1-CO6), the title and joining (MN1) |
| 1, 1a, 1b | Grandma's house and the drop-off (ST3), the house modules (above) |
| 2 | Grandma's notes and calls (TU2, TU3) |
| 3, 3b | Bedtime (TU4), brother or sister and the closet (Siblings: who you are) |
| 4 | Grandma's lawn and street standing (TU5) |
| 5, 5a | The walkable street, districts, street jobs on foot (TU6) |
| 5b | Arrive, knock, unload (TU7) |
| 6, 7 | Neighbours (CH5) and canvassing (J37b); the rest is in Leftovers from the old plans |
| 8 | Chad crashes the tutorial (ST9) |
| 9 | Wallets and getting paid (EC2, EC8) |
| 10 | Skimming clues and grandma's treasures: Leftovers from the old plans |