import type { RenderPrototype, RenderTransform } from "../render/RenderScene" import type { Collider } from "../world/Collider" /** Open actor behavior and representation. Concrete definitions are ordinary game * objects referenced directly by instances. */ export type ActorDefinition = { prototype: RenderPrototype update: (state: State, dt: number, world: World) => void transform: (state: State) => RenderTransform collider?: (state: State, world: World) => Collider | null } /** Type-erased live actor. `create` captures concrete state safely, allowing one * level to hold unrelated actor state types without a content union. */ export type Actor = { readonly definition: object readonly prototype: RenderPrototype readonly updateState: (dt: number, world: World) => void readonly readTransform: () => RenderTransform readonly readCollider: (world: World) => Collider | null } export namespace Actor { export function create( definition: ActorDefinition, state: State, ): Actor { return { definition, prototype: definition.prototype, updateState: (dt, world) => definition.update(state, dt, world), readTransform: () => definition.transform(state), readCollider: (world) => definition.collider?.(state, world) ?? null, } } export function update(actor: Actor, dt: number, world: World): void { actor.updateState(dt, world) } export function transform(actor: Actor): RenderTransform { return actor.readTransform() } export function collider(actor: Actor, world: World): Collider | null { return actor.readCollider(world) } }