@vforsh/tekton-runtime
v0.1.0
Published
Shared runtime primitives for Tekton Editor and Phaser games
Downloads
57
Readme
@vforsh/tekton-runtime
Shared runtime primitives for Tekton Editor and Phaser games. The package exposes contract types, prefab resolution helpers, Phaser object/component factories, and layout utilities without editor-only dependencies.
Contract types
Prefab JSON types and component JSON types are exported directly from this package.
import type { PrefabFile, EditorObjectJson, LayoutComponentJson } from '@vforsh/tekton-runtime'Phaser layout helpers
createPhaserLayoutSystem
A convenience adapter for Phaser containers + runtime layout components.
import { createPhaserLayoutSystem } from '@vforsh/tekton-runtime/phaser/layout'
import { LayoutComponent } from '@vforsh/tekton-runtime/phaser/components'
const layoutSystem = createPhaserLayoutSystem({
scene,
getChildren: (container) => container.list,
getLayoutComponent: (child) => {
const layout = child.components.get('layout')
return layout instanceof LayoutComponent ? layout : null
},
logger: console,
})You are responsible for:
- Wiring invalidation calls when objects resize or hierarchy changes.
- Ensuring layout components are attached to objects (see Components section).
installPhaserLayoutAutoInvalidation
For Phaser games that don’t have editor-style size-changed / hierarchy-changed events:
import { installPhaserLayoutAutoInvalidation } from '@vforsh/tekton-runtime/phaser/layout'
const { uninstall } = installPhaserLayoutAutoInvalidation(rootContainer, {
invalidate: (container) => layoutSystem.invalidate(container),
})
scene.events.once(Phaser.Scenes.Events.SHUTDOWN, uninstall)What it patches:
add,addAt,remove,removeAll(hierarchy changes)setSize(size changes)
Caveats:
- It won’t catch direct mutations like
container.list.push(...). - If your game already centralizes prefab mutations, explicit
layoutSystem.invalidate(...)calls can be simpler.
Runtime objects + components
Objects
import { createObjectFactory } from '@vforsh/tekton-runtime/phaser/objects'
import { createComponentFactory } from '@vforsh/tekton-runtime/phaser/components'
const componentsFactory = createComponentFactory()
const objectsFactory = createObjectFactory({ scene, componentsFactory })Components
import { ComponentsFactory, ComponentsManager, createComponentFactory } from '@vforsh/tekton-runtime/phaser/components'
const componentsFactory = createComponentFactory()
const manager = new ComponentsManager(hostObject)
const component = componentsFactory.create('layout', hostObject.id)
manager.add(component)For custom component types, subclass and override the protected hooks:
import type { ComponentJson } from '@vforsh/tekton-runtime'
type MyCustomComponentJson = ComponentJson & { type: 'my-custom' }
class GameComponentsFactory extends ComponentsFactory {
protected override isSupportedType(type: string): boolean {
return super.isSupportedType(type) || type === 'my-custom'
}
protected override createComponent(type: string, id: string) {
if (type === 'my-custom') {
return new MyCustomComponent(id)
}
return super.createComponent(type, id)
}
protected override createComponentFromJson(json: ComponentJson) {
if (json.type === 'my-custom') {
return new MyCustomComponent(json.id, json as MyCustomComponentJson)
}
return super.createComponentFromJson(json)
}
}
const componentsFactory = new GameComponentsFactory()Prefab runtime
Prefab resolver (framework-agnostic)
import { createPrefabResolver } from '@vforsh/tekton-runtime/prefabs'
const resolver = createPrefabResolver({
loadPrefabFile: async (prefabId) => {
const response = await fetch(`/prefabs/${prefabId}.json`)
return response.json()
},
})Phaser prefab runtime (resolve → load assets → create → attach components)
import { createPrefabFactory } from '@vforsh/tekton-runtime/phaser/prefabs'
const prefabRuntime = createPrefabFactory({
scene,
resolver,
objectsFactory,
logger: console,
})
const root = await prefabRuntime.loadAndCreate({ prefabId: 'button-primary' })
scene.add.existing(root)Preload assets separately:
await prefabRuntime.loadPrefabAssets('button-primary', { assetPack: { namespace: 'ui' } })
const root = await prefabRuntime.create({ prefabId: 'button-primary' })Public API review checklist
Before exporting anything new from @vforsh/tekton-runtime:
- Is this export intentional and documented?
- Does it avoid editor-only imports (
@state/*, renderer services, app commands)? - Is it stable enough to be relied on by both editor and game runtime?
