Skip to content

The adapter architecture

vgai’s editor and host don’t depend on any one game’s internals. They depend on interfaces, and games — first-party .vscn scenes or unmodified third-party three.js games — are peer implementers of those interfaces.

Host and editor depend on interfaces; first-party scenes and ingested games are peer implementers
The adapter seam.
  • GameAdapter (packages/engine/src/adapter/game-adapter.ts) — the host⇄runtime lifecycle. A “game” is anything that mounts via mount(host): Promise<MountedGame>. The MountedGame exposes the live scene + camera and lifecycle hooks (update/fixedUpdate/ setPaused/step) plus optional authoring/systems providers.
  • HostContext (host-context.ts) — the neutral primitives the host provides (the three instance, canvas, renderer, loop, assets, UI). Rapier/Colyseus are kept behind system adapters, not baked into the host.
  • AuthoringAdapter (authoring.ts) — the editor’s authoring contract: hierarchy / selection / transform / inspector / structure / persistence, keyed by opaque string node ids. The editor UI never branches on which implementer it’s editing.

vgai’s own content plugs into the same seams:

  • VgaiSceneGameAdapter wraps .vscn loading + setup() as a GameAdapter; fromSetup() adapts every existing example with zero edits.
  • VgaiSceneAuthoringAdapter implements AuthoringAdapter by delegating to the editor’s existing store/scene logic — so the hierarchy/inspector/gizmo/save all route through it.

Optional subsystem capability providers hang off MountedGame.systems (system-adapter.ts) — the editor coordinates with a game’s systems without owning them: Physics, Networking, Input, Asset, Animation, Navigation. First-party implementers wrap Rapier, Colyseus, the input manager, the asset cache, AnimGraph, and the navmesh manager.