import { randomUUID } from "node:crypto"; import type { Action } from "../contracts/action"; import type { ValidationResult } from "../contracts/validation"; import type { Entity } from "../contracts/entity"; import type { WorldState } from "../contracts/world"; function cloneWorldState(worldState: WorldState): WorldState { const entities: Record = {}; for (const [id, entity] of Object.entries(worldState.entities)) { entities[id] = { ...entity, attributes: { ...entity.attributes }, }; } return { ...worldState, entities, metadata: { ...worldState.metadata }, }; } export function applyActions( actions: Action[], results: ValidationResult[], worldState: WorldState ): WorldState { const nextState = cloneWorldState(worldState); for (const result of results) { if (!result.success) { continue; } const action = actions[result.actionIndex]; if (!action) { continue; } const actor = nextState.entities[action.actorId]; const target = action.targetId ? nextState.entities[action.targetId] : undefined; switch (action.type) { case "move": if (actor && action.targetId) { actor.attributes.location = action.targetId; } break; case "take": if (actor && target) { target.attributes.location = `inventory:${actor.id}`; if (target.id === "key_1") { actor.attributes.has_key_1 = true; } } break; case "open": if (target) { target.attributes.open = true; } break; case "inspect": default: break; } } nextState.id = randomUUID(); nextState.createdAt = Date.now(); return nextState; }