Introduce `toJSON` and `fromJSON` methods to the `World` class to allow saving and restoring world states. This requires components and relationships to have human-readable names for stable serialization.
38 lines
1.1 KiB
TypeScript
38 lines
1.1 KiB
TypeScript
// ── Component ─────────────────────────────────────────
|
|
/**
|
|
* A component definition carries both the type shape (via TypeScript inference)
|
|
* and a unique key used for storage lookup.
|
|
*
|
|
* @example
|
|
* ```ts
|
|
* const Position = defineComponent('position', { x: 0, y: 0 });
|
|
* type Position = typeof Position.type;
|
|
* ```
|
|
*/
|
|
export interface ComponentDef<T extends Record<string, any>> {
|
|
/** Unique symbol used as the storage key. */
|
|
readonly _key: symbol;
|
|
/** Human-readable name, used for serialization. */
|
|
readonly name: string;
|
|
/** Default values applied when a component is first added. */
|
|
readonly defaults: T;
|
|
/** Phantom type for inference. */
|
|
readonly type: T;
|
|
}
|
|
|
|
/**
|
|
* Define a component type. The name is used for serialization.
|
|
* The defaults object provides both the TypeScript shape and initial values.
|
|
*/
|
|
export function defineComponent<T extends Record<string, any>>(
|
|
name: string,
|
|
defaults: T,
|
|
): ComponentDef<T> {
|
|
return {
|
|
_key: Symbol(),
|
|
name,
|
|
defaults: { ...defaults },
|
|
type: undefined as unknown as T,
|
|
};
|
|
}
|