The gamemanager.toml descriptor
<project>/.forge/gamemanager.toml is the single descriptor for your project’s systems. The Game Manager tab reads it, the per-system editors mutate it, and the agent’s scaffold tool registers new systems into it. If you want to know what systems your project has, this is the file to read.
Example
Section titled “Example”A freshly scaffolded Platformer bundle’s gamemanager.toml looks roughly like this:
schema = 1id = "01923456-789a-7bcd-8def-0123456789ab"createdAt = "2026-05-17T19:34:21Z"updatedAt = "2026-05-17T19:41:08Z"engine = "web-phaser"language = "typescript"startupOrder = [ "ProjectConfig", "EventBus", "ThemeManager", "StateMachine", "SaveSystem", "AudioManager", "InputManager", "SettingsManager", "CharacterController",]
[systems.ProjectConfig]templateVersion = "1.0.0"sourcePath = "src/systems/project-config.ts"dependsOn = []
[systems.ProjectConfig.config] entries = [ { key = "player.moveSpeed", type = "float", default = 220.0, range = { min = 0, max = 800 }, hint = "Walk velocity in px/s" }, # … the rest of the player feel constants ]
[systems.AudioManager]templateVersion = "1.0.0"sourcePath = "src/systems/audio-manager.ts"dependsOn = ["EventBus"]
[systems.AudioManager.config] voicePoolSize = 16 buses = [ { name = "Master", defaultDb = 0 }, { name = "Music", parent = "Master", defaultDb = -6 }, { name = "SFX", parent = "Master", defaultDb = -3 }, { name = "Dialog", parent = "Master", defaultDb = 0 }, ] duckingRules = [ { whenBus = "Dialog", duck = [ { bus = "Music", amountDb = -8, attackMs = 80, releaseMs = 250 }, { bus = "SFX", amountDb = -6, attackMs = 80, releaseMs = 250 }, ] } ]Fields
Section titled “Fields”Top-level
Section titled “Top-level”| Field | Type | What it does |
|---|---|---|
schema | int | Format version. Currently 1. A future loader will refuse mismatches loudly rather than silently corrupting your file. |
id | string | UUIDv7 unique to this descriptor. Stable across renames. |
createdAt / updatedAt | ISO-8601 | Timestamps. Forge bumps updatedAt on every mutation. |
engine | string | Detected engine: web-phaser / web-threejs / web-vanilla / godot / unity / generic. Determines which template variants the scaffold uses. |
language | string | typescript / gdscript / csharp. Picked by engine detection. |
startupOrder | string array | Canonical system names in initialization order. Validated as a topological sort of the per-system dependsOn graph before any source regen. |
systems | table | One table per registered system, keyed by canonical name. |
Per-system entry ([systems.<Name>])
Section titled “Per-system entry ([systems.<Name>])”| Field | Type | What it does |
|---|---|---|
templateVersion | string | Semver of the template that produced this system. Forge uses this to diff against the latest bundled template when you upgrade a system. |
sourcePath | string | Project-relative POSIX path to the canonical source file the spine instantiates. |
dependsOn | string array | Names of sibling systems this one depends on at startup. Validated as a DAG when reordering. |
config | inline table | Schema-validated config. Shape varies per system. Each system editor knows the expected shape and round-trips through here. |
Each system’s config shape is documented on its own page: see AudioManager, EventBus, ProjectConfig, StateMachine, SaveSystem, InputManager, SettingsManager, CharacterController, and ThemeManager.
Editing by hand
Section titled “Editing by hand”The descriptor is plain TOML. You can edit it by hand; the next time the Game Manager tab loads, the editors will round-trip your edits. Validation runs on save:
schemamismatch refuses to load (you’ll see an error banner in the Game Manager tab).- An unknown system in
startupOrderis dropped silently with a warning in the developer console. - A cyclic
dependsOngraph refuses to load and surfaces the cycle. - Invalid config (e.g. unknown bus parent in AudioManager) blocks the save and shows the validation error inline in the editor.
If you want to add a system the editors don’t know about yet, the file format is forward-compatible: extra fields in config are preserved across reads and writes.
Scaffold sidecars
Section titled “Scaffold sidecars”Every system scaffold also writes <project>/.forge/scaffolds/<scaffold-id>.json. The sidecars record which files the scaffold touched, with SHAs, so Forge can run conflict detection if you later re-scaffold or upgrade the same system. See The Game Manager spine for what that flow looks like in practice.
You don’t normally edit sidecars. If you remove a system via the Game Manager tab, Forge deletes the sidecar and reverts the files (asking first if any have changed).
Source of truth
Section titled “Source of truth”The descriptor is the source of truth. The system source files are derived from it: their config blocks (the AudioManager bus tree, the InputManager action map, etc.) are regenerated from config on save. If you edit a source file and then edit the descriptor, the descriptor wins for the config block; your other hand-edits are preserved.
If you don’t want this round-tripping, just don’t use the editor. Hand-edit the source file directly. The descriptor records the templateVersion and sourcePath, but it won’t fight you for code you wrote yourself.