Typical workflow
Your schemas are the contract between server and clients. You author entities, commands, and related types in YAML, golem-bake turns that into typed integration code, then you write game logic against the generated imports. Day to day, that loop is what you repeat as the game grows.
Author, bake, run
Section titled “Author, bake, run”Start with a project config and at least one entity schema:
entity_schema: schemas/entities/
integrations: go-server: out: internal/synced/entity: Player
vars: health: { tag: 1, type: double, sync: tick } display_name: { tag: 2, type: string, sync: once }From the project root:
golem-bakego run ./cmd/serverAfter the first bake, wire the generated package into main (see Minimal server wiring). From then on the loop is the same:
- Edit YAML when the shared protocol changes (entity fields, commands, world types, events, or
golem.yamlitself). - Run
golem-baketo regenerate the integration outputs you configured. - Run your server (and clients) against the updated generated code.
What you edit vs what you don’t
Section titled “What you edit vs what you don’t”| You author | Protocol output (read-only) | No bake needed |
|---|---|---|
golem.yaml, schema YAML under schemas/ | Integration out: dirs for go-server, go-client, js-client, and similar | OnTick handlers, entity methods, startup wiring, gameplay Go/TS/C# |
Protocol integrations are fully reproducible from your schemas. Do not hand-edit those files, since the next bake will overwrite them. Whether you commit that output or regenerate it in CI is a project choice.
The ebiten, phaser, and unity integrations are different. Each targets a full client game engine and generates a per-entity bridge that plugs your synced entities into it, with hooks for spawn, removal, incoming state, per-frame updates, and drawing. Keep your own game code in separate files that import or embed the generated types, because bake will overwrite them too. See Ebiten, Phaser, and Unity.
When to re-bake
Section titled “When to re-bake”Re-run golem-bake when you change:
- An entity field (
vars): add, remove, or change type or sync mode - A command under
command_schema(defaultschemas/commands/): new commands, renamed fields, changed targets - A world type under
world_schema(defaultschemas/world/): new types, fields, orsource:config - A server event under
event_schema(defaultschemas/events/): new events, renamed fields,entity_type, orfoi_only golem.yaml: output paths or integration settings
You do not need to re-bake when you only change game logic.
Project layout after bake
Section titled “Project layout after bake”A typical project looks like this once schemas and integrations are in place. Paths follow the defaults and the sample golem.yaml above; override them with the keys in the golem.yaml reference.
mygame/ golem.yaml # project config: schema dirs, output dirs, integrations schemas/ entities/ # entity YAML (default entity_schema path) player.yaml enemy.yaml commands/ # optional: command YAML (default command_schema path) move.yaml world/ # optional: one file per world data type (default world_schema path) zone.yaml types/ # optional: custom types for collections (default types_schema path) item.yaml events/ # optional: server event YAML (default event_schema path) chat_message.yaml internal/ synced/ # go-server output (generated, do not edit) client/ # go-client output (optional, generated, do not edit) client/ src/synced/ # js-client output (generated, do not edit) cmd/server/ main.goNext steps
Section titled “Next steps”If the CLI is not installed yet, start with Installation. When you are ready to construct golem.Server and call Run, continue to Minimal server wiring.