Skip to content

Validate scenes & regenerate schema

cli tutorial Intermediate ⏱ 6 min vgai 0.1.0

Prerequisites: Installed vgai and run the editor

What you'll learn

  • Run validate-scenes to check scenes against the component registry
  • Regenerate the JSON Schema from the Zod scene schemas
  • Understand when each runs (pre-commit, after schema edits)

What you'll build: A terminal walkthrough of the two schema-guardrail commands.

vgai’s scene formats (.vscn.json, .prefab.json) are defined by Zod schemas in the engine — the single source of truth. Two commands keep everything in sync: generate-schema regenerates the JSON Schema (which powers VS Code autocomplete) from those Zod definitions, and validate-scenes checks that scene files only use components/fields the registry defines. This is a terminal tutorial — the transcript below is real captured output (including a real, honestly-reported gotcha).

$ npm run validate-scenes

> vgai-game@0.1.0 validate-scenes
> npx tsx packages/editor/template/validate-scenes.ts packages/editor/template --components

Scene validation failed with 53 error(s):

  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "ArenaCharacterController" has unknown field "moveSpeed" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "ArenaCharacterController" has unknown field "jumpVelocity" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "ArenaCharacterController" has unknown field "gravity" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "ArenaCharacterController" has unknown field "snapToGround" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "OrbitCamera" has unknown field "distance" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "OrbitCamera" has unknown field "lookAtHeight" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "OrbitCamera" has unknown field "sensitivity" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "OrbitCamera" has unknown field "minPitch" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/arena.vscn.json: entity "LocalPlayer" component "OrbitCamera" has unknown field "maxPitch" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/fps.vscn.json: entity "Player" component "FPSController" has unknown field "moveSpeed" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/fps.vscn.json: entity "Player" component "FPSController" has unknown field "jumpVelocity" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/fps.vscn.json: entity "Player" component "FPSController" has unknown field "gravity" (valid: (none))
… (35 more lines) …
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/vehicle.vscn.json: entity "Vehicle" component "VehicleController" has unknown field "maxSteer" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/vehicle.vscn.json: entity "Vehicle" component "VehicleController" has unknown field "maxBrake" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/vehicle.vscn.json: entity "Vehicle" component "ChaseCamera" has unknown field "offsetX" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/vehicle.vscn.json: entity "Vehicle" component "ChaseCamera" has unknown field "offsetY" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/vehicle.vscn.json: entity "Vehicle" component "ChaseCamera" has unknown field "offsetZ" (valid: (none))
  /Users/yueranyuan/volter/vgai-engine/.claude/worktrees/tutorial-site/packages/editor/template/public/examples/scenes/vehicle.vscn.json: entity "Vehicle" component "ChaseCamera" has unknown field "smooth" (valid: (none))
↳ exit 1
# validates every template .vscn.json against the component registry
$ npm run generate-schema

> vgai-game@0.1.0 generate-schema
> npx tsx scripts/generate-schema.ts

Generating JSON Schemas...
  vscn.schema.json (169879 bytes)
  prefab.schema.json (113983 bytes)
Done. Schemas written to packages/engine/schemas/
# regenerates JSON Schema from the Zod scene schemas
Terminal — Validate scenes & regenerate schema · captured by site/media/capture-cli.mjs
  1. Regenerate the JSON Schema from the Zod source.

    Terminal window
    npm run generate-schema

    This writes vscn.schema.json and prefab.schema.json (into packages/engine/schemas/) from the Zod schemas — the transcript shows it completing cleanly. Run it after any schema change so editor autocomplete and the on-disk JSON Schema match the code; a pre-commit hook verifies it’s up to date.

  2. Validate scenes against the component registry.

    Terminal window
    npm run validate-scenes

    This is the scene guardrail: it walks the .vscn.json / .prefab.json files and checks each entity’s components and fields against the engine’s component registry + Zod schemas, exiting non-zero on a violation (so bad scenes can’t land in CI).

Recap

New functionality

  • Regenerated the JSON Schema from the Zod source (clean)
  • Ran validate-scenes and learned to read its output critically

New concepts & skills

  • Zod schemas are the single source of truth for .vscn/.prefab
  • generate-schema keeps the on-disk JSON Schema (and autocomplete) in sync
  • validate-scenes is the scene guardrail — but from the monorepo source layout it currently over-reports due to a cross-package GameComponent identity mismatch (false positives, not drift)

Next lesson → Scene schemas (manual)