# v2: entity I/O, the forge, missions, mods and dialogue Index: `agents/world-format-v2.md`. Schemas: `agents/v2-formats.md` sections 3 (overlays), 4 (I/O and logic entities), 5 (mods), 6 (missions), 15 (dialogue). Briefs: `agents/v2-h-forge-mvp.md`. Built: `v2/forge/` + `v2/client/edit/` (forge MVP stage 1, goal 7, formats v1.3), `v2/sim/missions/`, `v2/sim/dialogue/`, logic entities in `v2/content/core/class/logic/`. ## Entity I/O (Source-style) The owner made Source maps; the power there was wiring events without code. v2 copies it. - Every entity has named **outputs** (`OnTrigger`, `OnBroken`, `OnPlayerEnter`, `OnUse`, `OnTimer`) and **inputs** (`Enable`, `Open`, `Break`, `SpawnAt`, `PlayVoice`, `SetState`). - A connection is data: `output -> target entity (id or name/wildcard) . input (param) after delay, once?`: exactly Hammer's I/O model. Logic entities (relay, counter, branch, timer, case; built with trigger and speaker) give mappers control flow without scripting. - Scripts (sandboxed, below) are for what I/O can't express; I/O stays the default so maps stay inspectable by agents and humans alike. - One system for official content, missions, player builds and mods. ## The forge (editor) - **The editor is the game client in edit mode**, not a separate app: walk round Heaton, press a key, place a bench, wire it to a trigger. Edits write to the layer you're in (personal / proposed / session). In-game building is the same tool. An agent's facade or prop placement is just an overlay. - **One rule: every wire is visible, readable as a sentence, and undoable.** ### Showing I/O in the world - Wires drawn in 3D in edit mode only (a curved labelled cable per connection, "OnUse -> PlayVoice"); play mode hides them (Dreams, LBP, UEFN). - **Signals pulse along the wire when they fire** (Blueprints debugging). - Wildcard and `!activator` targets draw to their current matches; a dangling target is a red stub ending in "?" (Hammer's worst silent failure, removed). - **Inspect mode reads connections as sentences:** "When someone **uses** the bench, the speaker **plays** 'Why aye man' after 0.5 s, once." Each word is a picker. The Hammer table (output, target, input, param, delay, times) is the advanced view of the same data. ### Forge MVP (stage 1 built, goal 7) 1. Instant play/edit toggle where you stand, no reload (Halo Reach's Monitor). 2. Tool gun with a radial picker: Spawn (catalogue browser, ghost preview), Move (gizmo), Remove, Wire, Inspect/Edit, Weld/parent (weld is an overlay entry, formats v1.3). 3. Wire tool in two clicks, source first; only inputs that make sense for the output. 4. Logic set: trigger volume, relay, timer, counter (case and branch later). 5. **Per-author undo/redo:** each action is one inverse `OverlayEntry` group; nobody can undo someone else's work in a shared layer (gmod). 6. A **budget thermometer** per layer (entities, connections, fires per second): limits as a game mechanic, not an error. 7. The AI assistant (below). Not in the MVP: scripts, terrain stamps, duplicator, graph view, live co-editing by more than 2. Built check: a scripted session builds a bench and a trigger zone that play Geordie barks, validates, fires through the kernel, and undo/redo restore hashes. ### Progression - v1.5: duplicator, case and branch, a debugger showing each entity's last output and value, a history panel with scrub and revert. - v2: live co-editing in session and personal layers; a graph view of the same `Conn` data with **microchips** grouping logic behind their own ports (Dreams/LBP); proposed to canonical review. - v3: Python-flavoured scripts, then WASM, shown as entities with named I/O so they stay wireable and inspectable. ### Duplicator and prefabs A selection saves as an `OverlayFile` fragment relative to an anchor; internal connections are rewritten to local names; outgoing ones are listed and dropped unless re-targeted. Pasting shows a ghost first. **A paste passes exactly the same checks as single placements** (class allowlist, budget, loop check): dupe files were a gmod exploit route. Shared prefabs are mod packages carrying author and remix credit. ### Collaboration, permissions, kids - Other people's layers are read-only to you, with prop protection and a buddy list. - Session layers broadcast ops live; conflicts follow the merge rule and show the losing edit as a toast. - Kids' accounts: catalogue parts only, voice lines from the catalogue (no free text or TTS), minimum timer interval 0.1 s, a cap on fires per tick. **Zero-delay loops are detected when wired** and drawn red, never left to hang at runtime (built: wire-time loop, budget and kids-account checks). - Proposing to canonical is a diff view: ghost adds, red removes, changed wires. ### AI assistant: ops only, no back door "Make this bench a trigger that plays a Geordie voice line": the selection is context; the agent returns `OverlayEntry[]` ops plus a one-line plan; the forge shows ghosts and wires with Accept / Tweak / Discard; nothing applies until Accept (Roblox Assistant's planning mode); accepted ops are **one undo group** tagged `author: agent:`. External agents use the same introspection API (like Roblox's Studio MCP server): `query_entities`, `get_io_graph`, `propose_ops`, `fire_input`, `screenshot`, and **deliberately no raw code-execution tool**: ops are the only write path. ### Browser and touch three.js `TransformControls` covers Move (translate/rotate/scale, world/local, snapping, `dragging-changed`) but handles **one pointer only**, so iPad multi-touch is ours: one finger drags a gizmo or selects/orbits, two fingers pan and pinch, long-press opens the radial, 44 px targets, snapping on by default; the wire tool on touch is tap source, pick from a sheet, tap target. ## Missions - A mission is data (entities, I/O graph, objectives, dialogue refs) plus optional script, placed by registry id, running on **a modified world**: the base plus the mission's own session overlay. Same system, different host: shared world, private lobby or dedicated instance. - **Kinds:** **Rails** missions (authored set pieces: the bank job, story beats); **generated** missions and events from templates over the real map (races between two registry points, deliveries to an address, chases, bounties); **private-only** missions (big heists, anything that would wreck the city for others, story content). Real recurring events (match days at St James' Park, the Toon crowd) suit the generated events system. - **Placement (decided 2026-09-26): private is the safe default; shared is a bonus.** - A private-only mission always gets its own instance. - Any other mission asks for its leases, all or nothing. If everything is free it runs in the shared world and others can drive past it; if anything is busy (the bank is leased) it goes private. No waiting, no contention. Generated events are the natural shared-world content; rails missions lean private. - **Pressure valve:** the server can move a running mission and its participants into an instance when the shared world gets too busy or chaotic, so mission state is serialisable and host-agnostic from day one (built: evacuate with serialised state). - Flow (GTA Online heists, Roblox reserved servers): start, reserve instance, move the party, return them on finish or fail. Prep can stay in the shared world. - **Coupling rules** (the owner is uneasy here; these are the guard): - A mission touches the world only through its own session layer and I/O inputs on entities; no direct references into traffic, peds or other systems' state. - Anything a mission spawns belongs to its layer and dies with it. - A mission **leases** the shared entities it changes (the bank, its doors, the vault); two missions never fight over one entity; the loser goes private. - Persistent consequences (a wrecked bank front) are an ordinary overlay with a reset policy, not mission state. - CI runs every mission headless in a private instance; if it only works in the shared world it is coupled and fails (built and tested for the samples in `v2/content/ncl/mission/`). - **Cutscenes:** later, possibly rotoscoped (live footage traced into the game's style), which suits a real city and real Geordie actors. ## Dialogue and voice - **Voice lines are real Geordies recorded, not AI voices.** AI writes code and pipeline; humans write stories and do voices. The sample Geordie pack is AI-drafted and must be picked and edited by a Geordie speaker before recording (owner task). - **Response Rules** (Valve, Ruskin GDC 2012): pick the line whose criteria best match world facts (components and field queries). Only the line id is networked. Built: `v2/sim/dialogue/` (12-rated worlds never pick strong language). Recording pipeline and rights: `rendering-and-audio.md`, `platform-and-community.md`. - **LLMs are an authoring tool, not runtime.** No runtime LLM in the shared world or for under-18s: generated text can't be voiced by real Geordies; Ofcom (8 Nov 2024) treats shareable chatbot output as user-to-user content; cost (~$0.001 a turn on Haiku 4.5, ~$300/day at 10k players x 30 turns, estimate) and latency. LLMs draft Response Rules lines offline; humans pick; actors record. Later, adults-only and age-assured in private worlds, an LLM may only choose an authored `line_id` and fill typed slots, never write free text. ## Private worlds and mods - Players can run a **private world with their own mods**: the base city + their overlay stack + their mod set, hosted by them or by us. The shared canonical world runs a curated mod set; anything goes in private worlds. - A mod is a package: catalogue entries, overlays, entity classes, I/O-wired maps, scripts, assets. Versioned, with a manifest of what it touches (`world-and-content.md`). Layout after Garry's Mod: folder per content type; a gamemode is a mod active only while played. - **Why mod code is sandboxed:** a mod is a stranger's code run on every player's machine in the world, many of them kids. Unsandboxed it can read the login token, post as the player, mine crypto, snoop on other tabs' data it can reach, or crash everyone's game. The sandbox gives it only what the game hands it (entities, I/O, its own storage) with a CPU budget, so a broken or malicious mod hurts only itself (gmod's Lua backdoors in Workshop addons). - **Mod languages, in tiers:** (1) **I/O wiring**, no code: most mods and missions; (2) **a simple Python-flavoured scripting language** (later), for kids and vibe coders, inside the same sandbox; (3) **Rust (or anything compiling to WASM)**: the official SDK, same language as the simulation, for heavy mods (vehicles, systems). WASM as the sandbox is the lean, not decided (open question in the index). The bar for the dev loop is s&box's millisecond hotload. - Mod UI: `platform-and-community.md`. Contributions, the mod hub and moderation: same file. ## Source feature checklist What Source gave mappers and modders that we want an equivalent of. Ticked where v2 has a first version. - [x] Entity I/O with logic entities (relay, case, branch, counter, timer) - [x] Triggers (volumes: once, multiple, hurt, push, teleport): `core:logic/trigger` (volume kinds beyond enter/exit not yet) - [x] prop_physics: physics props with mass, material and health (`core:prop_physics`) - [x] Physics materials (surfaceprops): sounds, decals, particles, friction (`v2/content/ncl/phys/` entries) - [ ] func_breakable and gibs - [ ] Constraints: weld, hinge, ball socket, slider, rope, pulley, keep-upright (weld only) - [x] Ragdolls and per-bone hitboxes (ragdoll fit; per-bone damage not yet) - [x] Vehicle scripts (data-defined handling: `v2/content/core/handling/` presets) - [x] Response Rules (context-driven NPC barks and dialogue) - [ ] Choreography (scripted scenes: lip sync, gestures) - [x] Soundscapes and reverb zones (generated acoustic zones; soundscape entities not yet) - [ ] env_ entities (fog, wind, sun, fire, sparks, shake, explosions) - [ ] Cubemaps / reflection probes and baked lighting - [x] AI nodes, hint nodes, navmesh (navmesh only) - [ ] Decals (bullet holes, graffiti, scorch) - [ ] Developer console and cvars (tune anything live) - [x] Demos (record and replay a session: great for bug reports and cinematics) - [ ] Workshop (publish, subscribe, update mods)