@sharpee/world-model 0.9.60-beta
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +61 -0
- package/dist/behaviors/attack.d.ts +52 -0
- package/dist/behaviors/attack.d.ts.map +1 -0
- package/dist/behaviors/attack.js +161 -0
- package/dist/behaviors/attack.js.map +1 -0
- package/dist/behaviors/behavior.d.ts +67 -0
- package/dist/behaviors/behavior.d.ts.map +1 -0
- package/dist/behaviors/behavior.js +80 -0
- package/dist/behaviors/behavior.js.map +1 -0
- package/dist/behaviors/index.d.ts +21 -0
- package/dist/behaviors/index.d.ts.map +1 -0
- package/dist/behaviors/index.js +39 -0
- package/dist/behaviors/index.js.map +1 -0
- package/dist/capabilities/capability-behavior.d.ts +112 -0
- package/dist/capabilities/capability-behavior.d.ts.map +1 -0
- package/dist/capabilities/capability-behavior.js +9 -0
- package/dist/capabilities/capability-behavior.js.map +1 -0
- package/dist/capabilities/capability-defaults.d.ts +67 -0
- package/dist/capabilities/capability-defaults.d.ts.map +1 -0
- package/dist/capabilities/capability-defaults.js +81 -0
- package/dist/capabilities/capability-defaults.js.map +1 -0
- package/dist/capabilities/capability-helpers.d.ts +76 -0
- package/dist/capabilities/capability-helpers.d.ts.map +1 -0
- package/dist/capabilities/capability-helpers.js +112 -0
- package/dist/capabilities/capability-helpers.js.map +1 -0
- package/dist/capabilities/capability-registry.d.ts +115 -0
- package/dist/capabilities/capability-registry.d.ts.map +1 -0
- package/dist/capabilities/capability-registry.js +136 -0
- package/dist/capabilities/capability-registry.js.map +1 -0
- package/dist/capabilities/entity-builder.d.ts +79 -0
- package/dist/capabilities/entity-builder.d.ts.map +1 -0
- package/dist/capabilities/entity-builder.js +116 -0
- package/dist/capabilities/entity-builder.js.map +1 -0
- package/dist/capabilities/index.d.ts +13 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +40 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/types.d.ts +35 -0
- package/dist/capabilities/types.d.ts.map +1 -0
- package/dist/capabilities/types.js +16 -0
- package/dist/capabilities/types.js.map +1 -0
- package/dist/commands/command-types.d.ts +30 -0
- package/dist/commands/command-types.d.ts.map +1 -0
- package/dist/commands/command-types.js +6 -0
- package/dist/commands/command-types.js.map +1 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +23 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/parsed-command.d.ts +204 -0
- package/dist/commands/parsed-command.d.ts.map +1 -0
- package/dist/commands/parsed-command.js +25 -0
- package/dist/commands/parsed-command.js.map +1 -0
- package/dist/commands/validated-command.d.ts +52 -0
- package/dist/commands/validated-command.d.ts.map +1 -0
- package/dist/commands/validated-command.js +8 -0
- package/dist/commands/validated-command.js.map +1 -0
- package/dist/constants/action-failures.d.ts +54 -0
- package/dist/constants/action-failures.d.ts.map +1 -0
- package/dist/constants/action-failures.js +68 -0
- package/dist/constants/action-failures.js.map +1 -0
- package/dist/constants/directions.d.ts +32 -0
- package/dist/constants/directions.d.ts.map +1 -0
- package/dist/constants/directions.js +53 -0
- package/dist/constants/directions.js.map +1 -0
- package/dist/constants/if-events.d.ts +5 -0
- package/dist/constants/if-events.d.ts.map +1 -0
- package/dist/constants/if-events.js +10 -0
- package/dist/constants/if-events.js.map +1 -0
- package/dist/constants/index.d.ts +9 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +25 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/entities/entity-store.d.ts +66 -0
- package/dist/entities/entity-store.d.ts.map +1 -0
- package/dist/entities/entity-store.js +116 -0
- package/dist/entities/entity-store.js.map +1 -0
- package/dist/entities/entity-types.d.ts +40 -0
- package/dist/entities/entity-types.d.ts.map +1 -0
- package/dist/entities/entity-types.js +56 -0
- package/dist/entities/entity-types.js.map +1 -0
- package/dist/entities/if-entity.d.ts +259 -0
- package/dist/entities/if-entity.d.ts.map +1 -0
- package/dist/entities/if-entity.js +498 -0
- package/dist/entities/if-entity.js.map +1 -0
- package/dist/entities/index.d.ts +5 -0
- package/dist/entities/index.d.ts.map +1 -0
- package/dist/entities/index.js +13 -0
- package/dist/entities/index.js.map +1 -0
- package/dist/events/types.d.ts +45 -0
- package/dist/events/types.d.ts.map +1 -0
- package/dist/events/types.js +9 -0
- package/dist/events/types.js.map +1 -0
- package/dist/examples/event-handler-registration.d.ts +14 -0
- package/dist/examples/event-handler-registration.d.ts.map +1 -0
- package/dist/examples/event-handler-registration.js +158 -0
- package/dist/examples/event-handler-registration.js.map +1 -0
- package/dist/extensions/base-extension.d.ts +69 -0
- package/dist/extensions/base-extension.d.ts.map +1 -0
- package/dist/extensions/base-extension.js +83 -0
- package/dist/extensions/base-extension.js.map +1 -0
- package/dist/extensions/index.d.ts +11 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +39 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/extensions/loader.d.ts +52 -0
- package/dist/extensions/loader.d.ts.map +1 -0
- package/dist/extensions/loader.js +177 -0
- package/dist/extensions/loader.js.map +1 -0
- package/dist/extensions/manager.d.ts +68 -0
- package/dist/extensions/manager.d.ts.map +1 -0
- package/dist/extensions/manager.js +164 -0
- package/dist/extensions/manager.js.map +1 -0
- package/dist/extensions/registry.d.ts +100 -0
- package/dist/extensions/registry.d.ts.map +1 -0
- package/dist/extensions/registry.js +193 -0
- package/dist/extensions/registry.js.map +1 -0
- package/dist/extensions/types.d.ts +226 -0
- package/dist/extensions/types.d.ts.map +1 -0
- package/dist/extensions/types.js +28 -0
- package/dist/extensions/types.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +68 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/command-executor.d.ts +17 -0
- package/dist/interfaces/command-executor.d.ts.map +1 -0
- package/dist/interfaces/command-executor.js +6 -0
- package/dist/interfaces/command-executor.js.map +1 -0
- package/dist/interfaces/command-processor.d.ts +17 -0
- package/dist/interfaces/command-processor.d.ts.map +1 -0
- package/dist/interfaces/command-processor.js +6 -0
- package/dist/interfaces/command-processor.js.map +1 -0
- package/dist/interfaces/command-validator.d.ts +17 -0
- package/dist/interfaces/command-validator.d.ts.map +1 -0
- package/dist/interfaces/command-validator.js +6 -0
- package/dist/interfaces/command-validator.js.map +1 -0
- package/dist/interfaces/index.d.ts +8 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +24 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/language-provider.d.ts +86 -0
- package/dist/interfaces/language-provider.d.ts.map +1 -0
- package/dist/interfaces/language-provider.js +14 -0
- package/dist/interfaces/language-provider.js.map +1 -0
- package/dist/interfaces/parser.d.ts +16 -0
- package/dist/interfaces/parser.d.ts.map +1 -0
- package/dist/interfaces/parser.js +6 -0
- package/dist/interfaces/parser.js.map +1 -0
- package/dist/scope/index.d.ts +8 -0
- package/dist/scope/index.d.ts.map +1 -0
- package/dist/scope/index.js +24 -0
- package/dist/scope/index.js.map +1 -0
- package/dist/scope/scope-evaluator.d.ts +58 -0
- package/dist/scope/scope-evaluator.d.ts.map +1 -0
- package/dist/scope/scope-evaluator.js +207 -0
- package/dist/scope/scope-evaluator.js.map +1 -0
- package/dist/scope/scope-registry.d.ts +59 -0
- package/dist/scope/scope-registry.d.ts.map +1 -0
- package/dist/scope/scope-registry.js +182 -0
- package/dist/scope/scope-registry.js.map +1 -0
- package/dist/scope/scope-rule.d.ts +86 -0
- package/dist/scope/scope-rule.d.ts.map +1 -0
- package/dist/scope/scope-rule.js +7 -0
- package/dist/scope/scope-rule.js.map +1 -0
- package/dist/services/ScopeService.d.ts +8 -0
- package/dist/services/ScopeService.d.ts.map +1 -0
- package/dist/services/ScopeService.js +19 -0
- package/dist/services/ScopeService.js.map +1 -0
- package/dist/services/index.d.ts +2 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +6 -0
- package/dist/services/index.js.map +1 -0
- package/dist/test-structure.d.ts +3 -0
- package/dist/test-structure.d.ts.map +1 -0
- package/dist/test-structure.js +26 -0
- package/dist/test-structure.js.map +1 -0
- package/dist/traits/actor/actorBehavior.d.ts +121 -0
- package/dist/traits/actor/actorBehavior.d.ts.map +1 -0
- package/dist/traits/actor/actorBehavior.js +288 -0
- package/dist/traits/actor/actorBehavior.js.map +1 -0
- package/dist/traits/actor/actorTrait.d.ts +158 -0
- package/dist/traits/actor/actorTrait.d.ts.map +1 -0
- package/dist/traits/actor/actorTrait.js +152 -0
- package/dist/traits/actor/actorTrait.js.map +1 -0
- package/dist/traits/actor/index.d.ts +3 -0
- package/dist/traits/actor/index.d.ts.map +1 -0
- package/dist/traits/actor/index.js +11 -0
- package/dist/traits/actor/index.js.map +1 -0
- package/dist/traits/all-traits.d.ts +95 -0
- package/dist/traits/all-traits.d.ts.map +1 -0
- package/dist/traits/all-traits.js +178 -0
- package/dist/traits/all-traits.js.map +1 -0
- package/dist/traits/attached/attachedTrait.d.ts +61 -0
- package/dist/traits/attached/attachedTrait.d.ts.map +1 -0
- package/dist/traits/attached/attachedTrait.js +36 -0
- package/dist/traits/attached/attachedTrait.js.map +1 -0
- package/dist/traits/attached/index.d.ts +2 -0
- package/dist/traits/attached/index.d.ts.map +1 -0
- package/dist/traits/attached/index.js +18 -0
- package/dist/traits/attached/index.js.map +1 -0
- package/dist/traits/breakable/breakableBehavior.d.ts +43 -0
- package/dist/traits/breakable/breakableBehavior.d.ts.map +1 -0
- package/dist/traits/breakable/breakableBehavior.js +70 -0
- package/dist/traits/breakable/breakableBehavior.js.map +1 -0
- package/dist/traits/breakable/breakableTrait.d.ts +22 -0
- package/dist/traits/breakable/breakableTrait.d.ts.map +1 -0
- package/dist/traits/breakable/breakableTrait.js +25 -0
- package/dist/traits/breakable/breakableTrait.js.map +1 -0
- package/dist/traits/breakable/index.d.ts +3 -0
- package/dist/traits/breakable/index.d.ts.map +1 -0
- package/dist/traits/breakable/index.js +8 -0
- package/dist/traits/breakable/index.js.map +1 -0
- package/dist/traits/button/buttonTrait.d.ts +53 -0
- package/dist/traits/button/buttonTrait.d.ts.map +1 -0
- package/dist/traits/button/buttonTrait.js +36 -0
- package/dist/traits/button/buttonTrait.js.map +1 -0
- package/dist/traits/button/index.d.ts +2 -0
- package/dist/traits/button/index.d.ts.map +1 -0
- package/dist/traits/button/index.js +18 -0
- package/dist/traits/button/index.js.map +1 -0
- package/dist/traits/climbable/climbableBehavior.d.ts +37 -0
- package/dist/traits/climbable/climbableBehavior.d.ts.map +1 -0
- package/dist/traits/climbable/climbableBehavior.js +70 -0
- package/dist/traits/climbable/climbableBehavior.js.map +1 -0
- package/dist/traits/climbable/climbableTrait.d.ts +31 -0
- package/dist/traits/climbable/climbableTrait.d.ts.map +1 -0
- package/dist/traits/climbable/climbableTrait.js +47 -0
- package/dist/traits/climbable/climbableTrait.js.map +1 -0
- package/dist/traits/climbable/index.d.ts +6 -0
- package/dist/traits/climbable/index.d.ts.map +1 -0
- package/dist/traits/climbable/index.js +22 -0
- package/dist/traits/climbable/index.js.map +1 -0
- package/dist/traits/clothing/clothingTrait.d.ts +58 -0
- package/dist/traits/clothing/clothingTrait.d.ts.map +1 -0
- package/dist/traits/clothing/clothingTrait.js +78 -0
- package/dist/traits/clothing/clothingTrait.js.map +1 -0
- package/dist/traits/clothing/index.d.ts +2 -0
- package/dist/traits/clothing/index.d.ts.map +1 -0
- package/dist/traits/clothing/index.js +19 -0
- package/dist/traits/clothing/index.js.map +1 -0
- package/dist/traits/combatant/combatantBehavior.d.ts +70 -0
- package/dist/traits/combatant/combatantBehavior.d.ts.map +1 -0
- package/dist/traits/combatant/combatantBehavior.js +155 -0
- package/dist/traits/combatant/combatantBehavior.js.map +1 -0
- package/dist/traits/combatant/combatantTrait.d.ts +98 -0
- package/dist/traits/combatant/combatantTrait.d.ts.map +1 -0
- package/dist/traits/combatant/combatantTrait.js +122 -0
- package/dist/traits/combatant/combatantTrait.js.map +1 -0
- package/dist/traits/combatant/index.d.ts +3 -0
- package/dist/traits/combatant/index.d.ts.map +1 -0
- package/dist/traits/combatant/index.js +8 -0
- package/dist/traits/combatant/index.js.map +1 -0
- package/dist/traits/container/container-utils.d.ts +39 -0
- package/dist/traits/container/container-utils.d.ts.map +1 -0
- package/dist/traits/container/container-utils.js +72 -0
- package/dist/traits/container/container-utils.js.map +1 -0
- package/dist/traits/container/containerBehavior.d.ts +94 -0
- package/dist/traits/container/containerBehavior.d.ts.map +1 -0
- package/dist/traits/container/containerBehavior.js +256 -0
- package/dist/traits/container/containerBehavior.js.map +1 -0
- package/dist/traits/container/containerTrait.d.ts +30 -0
- package/dist/traits/container/containerTrait.d.ts.map +1 -0
- package/dist/traits/container/containerTrait.js +45 -0
- package/dist/traits/container/containerTrait.js.map +1 -0
- package/dist/traits/container/index.d.ts +4 -0
- package/dist/traits/container/index.d.ts.map +1 -0
- package/dist/traits/container/index.js +14 -0
- package/dist/traits/container/index.js.map +1 -0
- package/dist/traits/destructible/destructibleBehavior.d.ts +57 -0
- package/dist/traits/destructible/destructibleBehavior.d.ts.map +1 -0
- package/dist/traits/destructible/destructibleBehavior.js +145 -0
- package/dist/traits/destructible/destructibleBehavior.js.map +1 -0
- package/dist/traits/destructible/destructibleTrait.d.ts +49 -0
- package/dist/traits/destructible/destructibleTrait.d.ts.map +1 -0
- package/dist/traits/destructible/destructibleTrait.js +43 -0
- package/dist/traits/destructible/destructibleTrait.js.map +1 -0
- package/dist/traits/destructible/index.d.ts +3 -0
- package/dist/traits/destructible/index.d.ts.map +1 -0
- package/dist/traits/destructible/index.js +8 -0
- package/dist/traits/destructible/index.js.map +1 -0
- package/dist/traits/door/doorBehavior.d.ts +42 -0
- package/dist/traits/door/doorBehavior.d.ts.map +1 -0
- package/dist/traits/door/doorBehavior.js +76 -0
- package/dist/traits/door/doorBehavior.js.map +1 -0
- package/dist/traits/door/doorTrait.d.ts +19 -0
- package/dist/traits/door/doorTrait.d.ts.map +1 -0
- package/dist/traits/door/doorTrait.js +33 -0
- package/dist/traits/door/doorTrait.js.map +1 -0
- package/dist/traits/door/index.d.ts +3 -0
- package/dist/traits/door/index.d.ts.map +1 -0
- package/dist/traits/door/index.js +9 -0
- package/dist/traits/door/index.js.map +1 -0
- package/dist/traits/edible/edibleBehavior.d.ts +63 -0
- package/dist/traits/edible/edibleBehavior.d.ts.map +1 -0
- package/dist/traits/edible/edibleBehavior.js +157 -0
- package/dist/traits/edible/edibleBehavior.js.map +1 -0
- package/dist/traits/edible/edibleTrait.d.ts +57 -0
- package/dist/traits/edible/edibleTrait.d.ts.map +1 -0
- package/dist/traits/edible/edibleTrait.js +51 -0
- package/dist/traits/edible/edibleTrait.js.map +1 -0
- package/dist/traits/edible/index.d.ts +3 -0
- package/dist/traits/edible/index.d.ts.map +1 -0
- package/dist/traits/edible/index.js +20 -0
- package/dist/traits/edible/index.js.map +1 -0
- package/dist/traits/enterable/enterableTrait.d.ts +33 -0
- package/dist/traits/enterable/enterableTrait.d.ts.map +1 -0
- package/dist/traits/enterable/enterableTrait.js +38 -0
- package/dist/traits/enterable/enterableTrait.js.map +1 -0
- package/dist/traits/enterable/index.d.ts +5 -0
- package/dist/traits/enterable/index.d.ts.map +1 -0
- package/dist/traits/enterable/index.js +21 -0
- package/dist/traits/enterable/index.js.map +1 -0
- package/dist/traits/equipped/equippedTrait.d.ts +46 -0
- package/dist/traits/equipped/equippedTrait.d.ts.map +1 -0
- package/dist/traits/equipped/equippedTrait.js +34 -0
- package/dist/traits/equipped/equippedTrait.js.map +1 -0
- package/dist/traits/equipped/index.d.ts +2 -0
- package/dist/traits/equipped/index.d.ts.map +1 -0
- package/dist/traits/equipped/index.js +6 -0
- package/dist/traits/equipped/index.js.map +1 -0
- package/dist/traits/exit/exitBehavior.d.ts +51 -0
- package/dist/traits/exit/exitBehavior.d.ts.map +1 -0
- package/dist/traits/exit/exitBehavior.js +231 -0
- package/dist/traits/exit/exitBehavior.js.map +1 -0
- package/dist/traits/exit/exitTrait.d.ts +41 -0
- package/dist/traits/exit/exitTrait.d.ts.map +1 -0
- package/dist/traits/exit/exitTrait.js +75 -0
- package/dist/traits/exit/exitTrait.js.map +1 -0
- package/dist/traits/exit/index.d.ts +3 -0
- package/dist/traits/exit/index.d.ts.map +1 -0
- package/dist/traits/exit/index.js +9 -0
- package/dist/traits/exit/index.js.map +1 -0
- package/dist/traits/identity/identityBehavior.d.ts +64 -0
- package/dist/traits/identity/identityBehavior.d.ts.map +1 -0
- package/dist/traits/identity/identityBehavior.js +154 -0
- package/dist/traits/identity/identityBehavior.js.map +1 -0
- package/dist/traits/identity/identityTrait.d.ts +70 -0
- package/dist/traits/identity/identityTrait.d.ts.map +1 -0
- package/dist/traits/identity/identityTrait.js +79 -0
- package/dist/traits/identity/identityTrait.js.map +1 -0
- package/dist/traits/identity/index.d.ts +3 -0
- package/dist/traits/identity/index.d.ts.map +1 -0
- package/dist/traits/identity/index.js +20 -0
- package/dist/traits/identity/index.js.map +1 -0
- package/dist/traits/implementations.d.ts +51 -0
- package/dist/traits/implementations.d.ts.map +1 -0
- package/dist/traits/implementations.js +145 -0
- package/dist/traits/implementations.js.map +1 -0
- package/dist/traits/index.d.ts +36 -0
- package/dist/traits/index.d.ts.map +1 -0
- package/dist/traits/index.js +62 -0
- package/dist/traits/index.js.map +1 -0
- package/dist/traits/light-source/index.d.ts +3 -0
- package/dist/traits/light-source/index.d.ts.map +1 -0
- package/dist/traits/light-source/index.js +9 -0
- package/dist/traits/light-source/index.js.map +1 -0
- package/dist/traits/light-source/lightSourceBehavior.d.ts +57 -0
- package/dist/traits/light-source/lightSourceBehavior.d.ts.map +1 -0
- package/dist/traits/light-source/lightSourceBehavior.js +135 -0
- package/dist/traits/light-source/lightSourceBehavior.js.map +1 -0
- package/dist/traits/light-source/lightSourceTrait.d.ts +28 -0
- package/dist/traits/light-source/lightSourceTrait.d.ts.map +1 -0
- package/dist/traits/light-source/lightSourceTrait.js +37 -0
- package/dist/traits/light-source/lightSourceTrait.js.map +1 -0
- package/dist/traits/lockable/index.d.ts +3 -0
- package/dist/traits/lockable/index.d.ts.map +1 -0
- package/dist/traits/lockable/index.js +20 -0
- package/dist/traits/lockable/index.js.map +1 -0
- package/dist/traits/lockable/lockableBehavior.d.ts +88 -0
- package/dist/traits/lockable/lockableBehavior.d.ts.map +1 -0
- package/dist/traits/lockable/lockableBehavior.js +196 -0
- package/dist/traits/lockable/lockableBehavior.js.map +1 -0
- package/dist/traits/lockable/lockableTrait.d.ts +59 -0
- package/dist/traits/lockable/lockableTrait.d.ts.map +1 -0
- package/dist/traits/lockable/lockableTrait.js +50 -0
- package/dist/traits/lockable/lockableTrait.js.map +1 -0
- package/dist/traits/moveable-scenery/index.d.ts +2 -0
- package/dist/traits/moveable-scenery/index.d.ts.map +1 -0
- package/dist/traits/moveable-scenery/index.js +18 -0
- package/dist/traits/moveable-scenery/index.js.map +1 -0
- package/dist/traits/moveable-scenery/moveableSceneryTrait.d.ts +69 -0
- package/dist/traits/moveable-scenery/moveableSceneryTrait.d.ts.map +1 -0
- package/dist/traits/moveable-scenery/moveableSceneryTrait.js +43 -0
- package/dist/traits/moveable-scenery/moveableSceneryTrait.js.map +1 -0
- package/dist/traits/npc/index.d.ts +5 -0
- package/dist/traits/npc/index.d.ts.map +1 -0
- package/dist/traits/npc/index.js +9 -0
- package/dist/traits/npc/index.js.map +1 -0
- package/dist/traits/npc/npcTrait.d.ts +128 -0
- package/dist/traits/npc/npcTrait.d.ts.map +1 -0
- package/dist/traits/npc/npcTrait.js +180 -0
- package/dist/traits/npc/npcTrait.js.map +1 -0
- package/dist/traits/openable/index.d.ts +3 -0
- package/dist/traits/openable/index.d.ts.map +1 -0
- package/dist/traits/openable/index.js +20 -0
- package/dist/traits/openable/index.js.map +1 -0
- package/dist/traits/openable/openableBehavior.d.ts +64 -0
- package/dist/traits/openable/openableBehavior.d.ts.map +1 -0
- package/dist/traits/openable/openableBehavior.js +109 -0
- package/dist/traits/openable/openableBehavior.js.map +1 -0
- package/dist/traits/openable/openableTrait.d.ts +46 -0
- package/dist/traits/openable/openableTrait.d.ts.map +1 -0
- package/dist/traits/openable/openableTrait.js +42 -0
- package/dist/traits/openable/openableTrait.js.map +1 -0
- package/dist/traits/portable/portableTrait.d.ts +26 -0
- package/dist/traits/portable/portableTrait.d.ts.map +1 -0
- package/dist/traits/portable/portableTrait.js +35 -0
- package/dist/traits/portable/portableTrait.js.map +1 -0
- package/dist/traits/pullable/index.d.ts +2 -0
- package/dist/traits/pullable/index.d.ts.map +1 -0
- package/dist/traits/pullable/index.js +18 -0
- package/dist/traits/pullable/index.js.map +1 -0
- package/dist/traits/pullable/pullableTrait.d.ts +81 -0
- package/dist/traits/pullable/pullableTrait.d.ts.map +1 -0
- package/dist/traits/pullable/pullableTrait.js +44 -0
- package/dist/traits/pullable/pullableTrait.js.map +1 -0
- package/dist/traits/pushable/index.d.ts +2 -0
- package/dist/traits/pushable/index.d.ts.map +1 -0
- package/dist/traits/pushable/index.js +18 -0
- package/dist/traits/pushable/index.js.map +1 -0
- package/dist/traits/pushable/pushableTrait.d.ts +81 -0
- package/dist/traits/pushable/pushableTrait.d.ts.map +1 -0
- package/dist/traits/pushable/pushableTrait.js +44 -0
- package/dist/traits/pushable/pushableTrait.js.map +1 -0
- package/dist/traits/readable/index.d.ts +3 -0
- package/dist/traits/readable/index.d.ts.map +1 -0
- package/dist/traits/readable/index.js +9 -0
- package/dist/traits/readable/index.js.map +1 -0
- package/dist/traits/readable/readableBehavior.d.ts +42 -0
- package/dist/traits/readable/readableBehavior.d.ts.map +1 -0
- package/dist/traits/readable/readableBehavior.js +174 -0
- package/dist/traits/readable/readableBehavior.js.map +1 -0
- package/dist/traits/readable/readableTrait.d.ts +37 -0
- package/dist/traits/readable/readableTrait.d.ts.map +1 -0
- package/dist/traits/readable/readableTrait.js +51 -0
- package/dist/traits/readable/readableTrait.js.map +1 -0
- package/dist/traits/register-all.d.ts +10 -0
- package/dist/traits/register-all.d.ts.map +1 -0
- package/dist/traits/register-all.js +19 -0
- package/dist/traits/register-all.js.map +1 -0
- package/dist/traits/room/index.d.ts +9 -0
- package/dist/traits/room/index.d.ts.map +1 -0
- package/dist/traits/room/index.js +14 -0
- package/dist/traits/room/index.js.map +1 -0
- package/dist/traits/room/roomBehavior.d.ts +87 -0
- package/dist/traits/room/roomBehavior.d.ts.map +1 -0
- package/dist/traits/room/roomBehavior.js +232 -0
- package/dist/traits/room/roomBehavior.js.map +1 -0
- package/dist/traits/room/roomTrait.d.ts +87 -0
- package/dist/traits/room/roomTrait.d.ts.map +1 -0
- package/dist/traits/room/roomTrait.js +59 -0
- package/dist/traits/room/roomTrait.js.map +1 -0
- package/dist/traits/scenery/index.d.ts +3 -0
- package/dist/traits/scenery/index.d.ts.map +1 -0
- package/dist/traits/scenery/index.js +9 -0
- package/dist/traits/scenery/index.js.map +1 -0
- package/dist/traits/scenery/sceneryBehavior.d.ts +21 -0
- package/dist/traits/scenery/sceneryBehavior.d.ts.map +1 -0
- package/dist/traits/scenery/sceneryBehavior.js +42 -0
- package/dist/traits/scenery/sceneryBehavior.js.map +1 -0
- package/dist/traits/scenery/sceneryTrait.d.ts +30 -0
- package/dist/traits/scenery/sceneryTrait.d.ts.map +1 -0
- package/dist/traits/scenery/sceneryTrait.js +39 -0
- package/dist/traits/scenery/sceneryTrait.js.map +1 -0
- package/dist/traits/supporter/index.d.ts +3 -0
- package/dist/traits/supporter/index.d.ts.map +1 -0
- package/dist/traits/supporter/index.js +9 -0
- package/dist/traits/supporter/index.js.map +1 -0
- package/dist/traits/supporter/supporterBehavior.d.ts +83 -0
- package/dist/traits/supporter/supporterBehavior.d.ts.map +1 -0
- package/dist/traits/supporter/supporterBehavior.js +210 -0
- package/dist/traits/supporter/supporterBehavior.js.map +1 -0
- package/dist/traits/supporter/supporterTrait.d.ts +26 -0
- package/dist/traits/supporter/supporterTrait.d.ts.map +1 -0
- package/dist/traits/supporter/supporterTrait.js +30 -0
- package/dist/traits/supporter/supporterTrait.js.map +1 -0
- package/dist/traits/switchable/index.d.ts +3 -0
- package/dist/traits/switchable/index.d.ts.map +1 -0
- package/dist/traits/switchable/index.js +20 -0
- package/dist/traits/switchable/index.js.map +1 -0
- package/dist/traits/switchable/switchableBehavior.d.ts +73 -0
- package/dist/traits/switchable/switchableBehavior.d.ts.map +1 -0
- package/dist/traits/switchable/switchableBehavior.js +191 -0
- package/dist/traits/switchable/switchableBehavior.js.map +1 -0
- package/dist/traits/switchable/switchableTrait.d.ts +61 -0
- package/dist/traits/switchable/switchableTrait.d.ts.map +1 -0
- package/dist/traits/switchable/switchableTrait.js +52 -0
- package/dist/traits/switchable/switchableTrait.js.map +1 -0
- package/dist/traits/trait-types.d.ts +81 -0
- package/dist/traits/trait-types.d.ts.map +1 -0
- package/dist/traits/trait-types.js +146 -0
- package/dist/traits/trait-types.js.map +1 -0
- package/dist/traits/trait.d.ts +42 -0
- package/dist/traits/trait.d.ts.map +1 -0
- package/dist/traits/trait.js +42 -0
- package/dist/traits/trait.js.map +1 -0
- package/dist/traits/vehicle/index.d.ts +6 -0
- package/dist/traits/vehicle/index.d.ts.map +1 -0
- package/dist/traits/vehicle/index.js +22 -0
- package/dist/traits/vehicle/index.js.map +1 -0
- package/dist/traits/vehicle/vehicleBehavior.d.ts +62 -0
- package/dist/traits/vehicle/vehicleBehavior.d.ts.map +1 -0
- package/dist/traits/vehicle/vehicleBehavior.js +145 -0
- package/dist/traits/vehicle/vehicleBehavior.js.map +1 -0
- package/dist/traits/vehicle/vehicleTrait.d.ts +77 -0
- package/dist/traits/vehicle/vehicleTrait.d.ts.map +1 -0
- package/dist/traits/vehicle/vehicleTrait.js +92 -0
- package/dist/traits/vehicle/vehicleTrait.js.map +1 -0
- package/dist/traits/weapon/index.d.ts +3 -0
- package/dist/traits/weapon/index.d.ts.map +1 -0
- package/dist/traits/weapon/index.js +8 -0
- package/dist/traits/weapon/index.js.map +1 -0
- package/dist/traits/weapon/weaponBehavior.d.ts +47 -0
- package/dist/traits/weapon/weaponBehavior.d.ts.map +1 -0
- package/dist/traits/weapon/weaponBehavior.js +106 -0
- package/dist/traits/weapon/weaponBehavior.js.map +1 -0
- package/dist/traits/weapon/weaponTrait.d.ts +67 -0
- package/dist/traits/weapon/weaponTrait.d.ts.map +1 -0
- package/dist/traits/weapon/weaponTrait.js +60 -0
- package/dist/traits/weapon/weaponTrait.js.map +1 -0
- package/dist/traits/wearable/index.d.ts +3 -0
- package/dist/traits/wearable/index.d.ts.map +1 -0
- package/dist/traits/wearable/index.js +20 -0
- package/dist/traits/wearable/index.js.map +1 -0
- package/dist/traits/wearable/wearableBehavior.d.ts +64 -0
- package/dist/traits/wearable/wearableBehavior.d.ts.map +1 -0
- package/dist/traits/wearable/wearableBehavior.js +142 -0
- package/dist/traits/wearable/wearableBehavior.js.map +1 -0
- package/dist/traits/wearable/wearableTrait.d.ts +54 -0
- package/dist/traits/wearable/wearableTrait.d.ts.map +1 -0
- package/dist/traits/wearable/wearableTrait.js +53 -0
- package/dist/traits/wearable/wearableTrait.js.map +1 -0
- package/dist/utils/event-utils.d.ts +30 -0
- package/dist/utils/event-utils.d.ts.map +1 -0
- package/dist/utils/event-utils.js +33 -0
- package/dist/utils/event-utils.js.map +1 -0
- package/dist/world/AuthorModel.d.ts +151 -0
- package/dist/world/AuthorModel.d.ts.map +1 -0
- package/dist/world/AuthorModel.js +416 -0
- package/dist/world/AuthorModel.js.map +1 -0
- package/dist/world/SharedDataStore.d.ts +24 -0
- package/dist/world/SharedDataStore.d.ts.map +1 -0
- package/dist/world/SharedDataStore.js +50 -0
- package/dist/world/SharedDataStore.js.map +1 -0
- package/dist/world/SpatialIndex.d.ts +16 -0
- package/dist/world/SpatialIndex.d.ts.map +1 -0
- package/dist/world/SpatialIndex.js +117 -0
- package/dist/world/SpatialIndex.js.map +1 -0
- package/dist/world/VisibilityBehavior.d.ts +83 -0
- package/dist/world/VisibilityBehavior.d.ts.map +1 -0
- package/dist/world/VisibilityBehavior.js +484 -0
- package/dist/world/VisibilityBehavior.js.map +1 -0
- package/dist/world/WorldModel.d.ts +270 -0
- package/dist/world/WorldModel.d.ts.map +1 -0
- package/dist/world/WorldModel.js +1028 -0
- package/dist/world/WorldModel.js.map +1 -0
- package/dist/world/capabilities.d.ts +36 -0
- package/dist/world/capabilities.d.ts.map +1 -0
- package/dist/world/capabilities.js +18 -0
- package/dist/world/capabilities.js.map +1 -0
- package/dist/world/index.d.ts +7 -0
- package/dist/world/index.d.ts.map +1 -0
- package/dist/world/index.js +21 -0
- package/dist/world/index.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,1028 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// WorldModel.ts - Core world model interface and implementation for Sharpee IF Platform
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.WorldModel = void 0;
|
|
5
|
+
const if_entity_1 = require("../entities/if-entity");
|
|
6
|
+
const entity_types_1 = require("../entities/entity-types");
|
|
7
|
+
const trait_types_1 = require("../traits/trait-types");
|
|
8
|
+
const room_1 = require("../traits/room");
|
|
9
|
+
const container_1 = require("../traits/container");
|
|
10
|
+
const supporter_1 = require("../traits/supporter");
|
|
11
|
+
const actor_1 = require("../traits/actor");
|
|
12
|
+
const scenery_1 = require("../traits/scenery");
|
|
13
|
+
const SpatialIndex_1 = require("./SpatialIndex");
|
|
14
|
+
const VisibilityBehavior_1 = require("./VisibilityBehavior");
|
|
15
|
+
const container_utils_1 = require("../traits/container/container-utils");
|
|
16
|
+
const if_domain_1 = require("@sharpee/if-domain");
|
|
17
|
+
const scope_registry_1 = require("../scope/scope-registry");
|
|
18
|
+
const scope_evaluator_1 = require("../scope/scope-evaluator");
|
|
19
|
+
// Type prefixes for entity ID generation
|
|
20
|
+
const TYPE_PREFIXES = {
|
|
21
|
+
'room': 'r',
|
|
22
|
+
'door': 'd',
|
|
23
|
+
'item': 'i',
|
|
24
|
+
'actor': 'a',
|
|
25
|
+
'container': 'c',
|
|
26
|
+
'supporter': 's',
|
|
27
|
+
'scenery': 'y',
|
|
28
|
+
'exit': 'e',
|
|
29
|
+
'object': 'o' // default
|
|
30
|
+
};
|
|
31
|
+
class WorldModel {
|
|
32
|
+
entities = new Map();
|
|
33
|
+
state = {};
|
|
34
|
+
playerId;
|
|
35
|
+
spatialIndex;
|
|
36
|
+
config;
|
|
37
|
+
capabilities = {};
|
|
38
|
+
// ID generation
|
|
39
|
+
idCounters = new Map();
|
|
40
|
+
// Event sourcing support
|
|
41
|
+
eventHandlers = new Map();
|
|
42
|
+
eventValidators = new Map();
|
|
43
|
+
eventPreviewers = new Map();
|
|
44
|
+
appliedEvents = [];
|
|
45
|
+
eventProcessorWiring = null;
|
|
46
|
+
maxEventHistory = 1000; // Configurable limit
|
|
47
|
+
// Event chaining support (ADR-094)
|
|
48
|
+
eventChains = new Map();
|
|
49
|
+
platformEvents;
|
|
50
|
+
// Scope system
|
|
51
|
+
scopeRegistry;
|
|
52
|
+
scopeEvaluator;
|
|
53
|
+
// Vocabulary system (ADR-082)
|
|
54
|
+
grammarVocabularyProvider;
|
|
55
|
+
constructor(config = {}, platformEvents) {
|
|
56
|
+
this.config = {
|
|
57
|
+
enableSpatialIndex: true,
|
|
58
|
+
maxDepth: 10,
|
|
59
|
+
strictMode: false,
|
|
60
|
+
...config
|
|
61
|
+
};
|
|
62
|
+
this.spatialIndex = new SpatialIndex_1.SpatialIndex();
|
|
63
|
+
this.platformEvents = platformEvents;
|
|
64
|
+
// Initialize scope system
|
|
65
|
+
this.scopeRegistry = new scope_registry_1.ScopeRegistry();
|
|
66
|
+
this.scopeEvaluator = new scope_evaluator_1.ScopeEvaluator(this.scopeRegistry);
|
|
67
|
+
// Initialize vocabulary system (ADR-082)
|
|
68
|
+
this.grammarVocabularyProvider = new if_domain_1.GrammarVocabularyProvider();
|
|
69
|
+
// Register default scope rules
|
|
70
|
+
this.registerDefaultScopeRules();
|
|
71
|
+
}
|
|
72
|
+
// Platform event emission helper
|
|
73
|
+
emitPlatformEvent(type, data) {
|
|
74
|
+
if (this.platformEvents) {
|
|
75
|
+
this.platformEvents.addEvent({
|
|
76
|
+
id: `world_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
|
|
77
|
+
timestamp: Date.now(),
|
|
78
|
+
type: `platform.world.${type}`,
|
|
79
|
+
entities: {},
|
|
80
|
+
data: {
|
|
81
|
+
subsystem: 'world',
|
|
82
|
+
...data
|
|
83
|
+
},
|
|
84
|
+
tags: ['platform', 'world', 'debug'],
|
|
85
|
+
priority: 0,
|
|
86
|
+
narrate: false
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Capability Management
|
|
91
|
+
registerCapability(name, registration = {}) {
|
|
92
|
+
if (this.capabilities[name]) {
|
|
93
|
+
if (this.config.strictMode) {
|
|
94
|
+
throw new Error(`Capability '${name}' is already registered`);
|
|
95
|
+
}
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
// Initialize capability with schema and initial data
|
|
99
|
+
const initialData = {};
|
|
100
|
+
// Apply schema defaults
|
|
101
|
+
if (registration.schema) {
|
|
102
|
+
for (const [field, fieldDef] of Object.entries(registration.schema)) {
|
|
103
|
+
if (fieldDef.default !== undefined) {
|
|
104
|
+
initialData[field] = fieldDef.default;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Override with provided initial data
|
|
109
|
+
if (registration.initialData) {
|
|
110
|
+
Object.assign(initialData, registration.initialData);
|
|
111
|
+
}
|
|
112
|
+
this.capabilities[name] = {
|
|
113
|
+
data: initialData,
|
|
114
|
+
schema: registration.schema
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
updateCapability(name, updates) {
|
|
118
|
+
const capability = this.capabilities[name];
|
|
119
|
+
if (!capability) {
|
|
120
|
+
if (this.config.strictMode) {
|
|
121
|
+
throw new Error(`Capability '${name}' is not registered`);
|
|
122
|
+
}
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
// Validate updates against schema if present
|
|
126
|
+
if (capability.schema) {
|
|
127
|
+
for (const [field, value] of Object.entries(updates)) {
|
|
128
|
+
const fieldDef = capability.schema[field];
|
|
129
|
+
if (fieldDef) {
|
|
130
|
+
// Basic type validation
|
|
131
|
+
const actualType = Array.isArray(value) ? 'array' : typeof value;
|
|
132
|
+
if (actualType !== fieldDef.type && value !== null && value !== undefined) {
|
|
133
|
+
if (this.config.strictMode) {
|
|
134
|
+
throw new Error(`Invalid type for capability '${name}' field '${field}': expected ${fieldDef.type}, got ${actualType}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
// Apply updates
|
|
141
|
+
Object.assign(capability.data, updates);
|
|
142
|
+
}
|
|
143
|
+
getCapability(name) {
|
|
144
|
+
return this.capabilities[name]?.data;
|
|
145
|
+
}
|
|
146
|
+
hasCapability(name) {
|
|
147
|
+
return name in this.capabilities;
|
|
148
|
+
}
|
|
149
|
+
// ID Generation
|
|
150
|
+
generateId(type) {
|
|
151
|
+
const prefix = TYPE_PREFIXES[type] || TYPE_PREFIXES['object'];
|
|
152
|
+
const counter = this.idCounters.get(prefix) || 0;
|
|
153
|
+
// Increment counter
|
|
154
|
+
const nextCounter = counter + 1;
|
|
155
|
+
// Check for overflow (base36 with 2 chars = 1296 max)
|
|
156
|
+
if (nextCounter > 1295) {
|
|
157
|
+
throw new Error(`ID overflow for type '${type}' (prefix '${prefix}'). Maximum 1296 entities per type.`);
|
|
158
|
+
}
|
|
159
|
+
this.idCounters.set(prefix, nextCounter);
|
|
160
|
+
// Convert to base36 and pad to 2 characters
|
|
161
|
+
const base36 = nextCounter.toString(36).padStart(2, '0');
|
|
162
|
+
return `${prefix}${base36}`;
|
|
163
|
+
}
|
|
164
|
+
// Entity Management
|
|
165
|
+
createEntity(displayName, type = 'object') {
|
|
166
|
+
// Validate entity type
|
|
167
|
+
if (!(0, entity_types_1.isEntityType)(type)) {
|
|
168
|
+
throw new Error(`Unknown entity type: '${type}'. Valid types are: ${Object.values(entity_types_1.EntityType).join(', ')}`);
|
|
169
|
+
}
|
|
170
|
+
// Generate ID based on type
|
|
171
|
+
const id = this.generateId(type);
|
|
172
|
+
const entity = new if_entity_1.IFEntity(id, type, {
|
|
173
|
+
attributes: {
|
|
174
|
+
displayName: displayName,
|
|
175
|
+
name: displayName, // For compatibility
|
|
176
|
+
entityType: type
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
// Add to entity map
|
|
180
|
+
this.entities.set(id, entity);
|
|
181
|
+
return entity;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Create an entity with type safety and automatic trait assignment
|
|
185
|
+
* @param type The entity type (from EntityType constants)
|
|
186
|
+
* @returns The created entity with appropriate default traits
|
|
187
|
+
*/
|
|
188
|
+
createEntityWithTraits(type) {
|
|
189
|
+
const id = this.generateId(type);
|
|
190
|
+
const entity = new if_entity_1.IFEntity(id, type);
|
|
191
|
+
// Auto-add appropriate default trait based on type
|
|
192
|
+
switch (type) {
|
|
193
|
+
case entity_types_1.EntityType.ROOM:
|
|
194
|
+
entity.add(new room_1.RoomTrait({}));
|
|
195
|
+
break;
|
|
196
|
+
case entity_types_1.EntityType.CONTAINER:
|
|
197
|
+
entity.add(new container_1.ContainerTrait());
|
|
198
|
+
break;
|
|
199
|
+
case entity_types_1.EntityType.SUPPORTER:
|
|
200
|
+
entity.add(new supporter_1.SupporterTrait());
|
|
201
|
+
break;
|
|
202
|
+
case entity_types_1.EntityType.ACTOR:
|
|
203
|
+
entity.add(new actor_1.ActorTrait());
|
|
204
|
+
break;
|
|
205
|
+
case entity_types_1.EntityType.DOOR:
|
|
206
|
+
// Door trait requires room1 and room2 to be set
|
|
207
|
+
// These must be configured after creation when room IDs are known
|
|
208
|
+
break;
|
|
209
|
+
case entity_types_1.EntityType.SCENERY:
|
|
210
|
+
entity.add(new scenery_1.SceneryTrait());
|
|
211
|
+
break;
|
|
212
|
+
// ITEM, OBJECT, and EXIT don't need special traits by default
|
|
213
|
+
}
|
|
214
|
+
// Add to entity map
|
|
215
|
+
this.entities.set(id, entity);
|
|
216
|
+
return entity;
|
|
217
|
+
}
|
|
218
|
+
getEntity(id) {
|
|
219
|
+
return this.entities.get(id);
|
|
220
|
+
}
|
|
221
|
+
hasEntity(id) {
|
|
222
|
+
return this.entities.has(id);
|
|
223
|
+
}
|
|
224
|
+
removeEntity(id) {
|
|
225
|
+
const entity = this.entities.get(id);
|
|
226
|
+
if (!entity)
|
|
227
|
+
return false;
|
|
228
|
+
// Remove from spatial index
|
|
229
|
+
this.spatialIndex.remove(id);
|
|
230
|
+
// Remove from any containers
|
|
231
|
+
const location = this.getLocation(id);
|
|
232
|
+
if (location) {
|
|
233
|
+
this.moveEntity(id, null);
|
|
234
|
+
}
|
|
235
|
+
// Remove entity
|
|
236
|
+
return this.entities.delete(id);
|
|
237
|
+
}
|
|
238
|
+
getAllEntities() {
|
|
239
|
+
return Array.from(this.entities.values());
|
|
240
|
+
}
|
|
241
|
+
updateEntity(entityId, updater) {
|
|
242
|
+
const entity = this.getEntity(entityId);
|
|
243
|
+
if (!entity) {
|
|
244
|
+
if (this.config.strictMode) {
|
|
245
|
+
throw new Error(`Cannot update non-existent entity: ${entityId}`);
|
|
246
|
+
}
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
// Call the updater - entity is mutable so changes happen in place
|
|
250
|
+
updater(entity);
|
|
251
|
+
// Future: Could emit change events here for reactive systems
|
|
252
|
+
// this.emitChange({ type: 'entity-updated', entityId });
|
|
253
|
+
}
|
|
254
|
+
// Spatial Management
|
|
255
|
+
getLocation(entityId) {
|
|
256
|
+
return this.spatialIndex.getParent(entityId);
|
|
257
|
+
}
|
|
258
|
+
getContents(containerId, options = {}) {
|
|
259
|
+
const contents = this.spatialIndex.getChildren(containerId);
|
|
260
|
+
let entities = contents
|
|
261
|
+
.map(id => this.getEntity(id))
|
|
262
|
+
.filter((e) => e !== undefined);
|
|
263
|
+
if (options.visibleOnly) {
|
|
264
|
+
// Filter to only visible entities
|
|
265
|
+
entities = entities.filter(e => {
|
|
266
|
+
const scenery = e.getTrait(trait_types_1.TraitType.SCENERY);
|
|
267
|
+
return !scenery || scenery.visible !== false;
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
if (!options.includeWorn) {
|
|
271
|
+
// Filter out worn items (check both WEARABLE and CLOTHING traits)
|
|
272
|
+
entities = entities.filter(e => {
|
|
273
|
+
const wearable = e.getTrait(trait_types_1.TraitType.WEARABLE);
|
|
274
|
+
const clothing = e.getTrait(trait_types_1.TraitType.CLOTHING);
|
|
275
|
+
const wornFromWearable = wearable && wearable.isWorn;
|
|
276
|
+
const wornFromClothing = clothing && clothing.isWorn;
|
|
277
|
+
return !(wornFromWearable || wornFromClothing);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
return entities;
|
|
281
|
+
}
|
|
282
|
+
moveEntity(entityId, targetId) {
|
|
283
|
+
if (!this.canMoveEntity(entityId, targetId)) {
|
|
284
|
+
this.emitPlatformEvent('move_entity_failed', {
|
|
285
|
+
entityId,
|
|
286
|
+
targetId,
|
|
287
|
+
reason: 'cannot_move'
|
|
288
|
+
});
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
// Remove from current location
|
|
292
|
+
const currentLocation = this.getLocation(entityId);
|
|
293
|
+
if (currentLocation) {
|
|
294
|
+
this.spatialIndex.removeChild(currentLocation, entityId);
|
|
295
|
+
}
|
|
296
|
+
// Add to new location
|
|
297
|
+
if (targetId) {
|
|
298
|
+
this.spatialIndex.addChild(targetId, entityId);
|
|
299
|
+
}
|
|
300
|
+
// Emit platform event
|
|
301
|
+
this.emitPlatformEvent('entity_moved', {
|
|
302
|
+
entityId,
|
|
303
|
+
fromLocation: currentLocation,
|
|
304
|
+
toLocation: targetId
|
|
305
|
+
});
|
|
306
|
+
return true;
|
|
307
|
+
}
|
|
308
|
+
canMoveEntity(entityId, targetId) {
|
|
309
|
+
const entity = this.getEntity(entityId);
|
|
310
|
+
if (!entity)
|
|
311
|
+
return false;
|
|
312
|
+
// Can always remove from world
|
|
313
|
+
if (targetId === null)
|
|
314
|
+
return true;
|
|
315
|
+
const target = this.getEntity(targetId);
|
|
316
|
+
if (!target)
|
|
317
|
+
return false;
|
|
318
|
+
// Check for containment loops
|
|
319
|
+
if (this.wouldCreateLoop(entityId, targetId)) {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
// Check if target can contain - using our new utility
|
|
323
|
+
if (!(0, container_utils_1.canContain)(target)) {
|
|
324
|
+
return false;
|
|
325
|
+
}
|
|
326
|
+
// Check container constraints
|
|
327
|
+
if (target.hasTrait(trait_types_1.TraitType.CONTAINER) && target.hasTrait(trait_types_1.TraitType.OPENABLE)) {
|
|
328
|
+
const openable = target.getTrait(trait_types_1.TraitType.OPENABLE);
|
|
329
|
+
if (openable && !openable.isOpen) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
return true;
|
|
334
|
+
}
|
|
335
|
+
getContainingRoom(entityId) {
|
|
336
|
+
let current = entityId;
|
|
337
|
+
let depth = 0;
|
|
338
|
+
while (current && depth < this.config.maxDepth) {
|
|
339
|
+
const parent = this.getLocation(current);
|
|
340
|
+
if (!parent)
|
|
341
|
+
return undefined;
|
|
342
|
+
const parentEntity = this.getEntity(parent);
|
|
343
|
+
if (parentEntity?.hasTrait(trait_types_1.TraitType.ROOM)) {
|
|
344
|
+
return parentEntity;
|
|
345
|
+
}
|
|
346
|
+
current = parent;
|
|
347
|
+
depth++;
|
|
348
|
+
}
|
|
349
|
+
return undefined;
|
|
350
|
+
}
|
|
351
|
+
getAllContents(entityId, options = {}) {
|
|
352
|
+
const result = [];
|
|
353
|
+
const visited = new Set();
|
|
354
|
+
const traverse = (id, depth = 0, isRoot = false) => {
|
|
355
|
+
if (visited.has(id) || depth > this.config.maxDepth)
|
|
356
|
+
return;
|
|
357
|
+
visited.add(id);
|
|
358
|
+
// For the root entity, use the provided options
|
|
359
|
+
// For recursive calls, always include worn items to get complete contents
|
|
360
|
+
const contentsOptions = isRoot ? {
|
|
361
|
+
visibleOnly: options.visibleOnly,
|
|
362
|
+
includeWorn: options.includeWorn
|
|
363
|
+
} : {
|
|
364
|
+
visibleOnly: options.visibleOnly,
|
|
365
|
+
includeWorn: true // Always include worn items when recursing
|
|
366
|
+
};
|
|
367
|
+
const contents = this.getContents(id, contentsOptions);
|
|
368
|
+
result.push(...contents);
|
|
369
|
+
if (options.recursive) {
|
|
370
|
+
contents.forEach(item => traverse(item.id, depth + 1, false));
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
traverse(entityId, 0, true);
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
// World State Management
|
|
377
|
+
getState() {
|
|
378
|
+
return { ...this.state };
|
|
379
|
+
}
|
|
380
|
+
setState(state) {
|
|
381
|
+
this.state = { ...state };
|
|
382
|
+
}
|
|
383
|
+
getStateValue(key) {
|
|
384
|
+
return this.state[key];
|
|
385
|
+
}
|
|
386
|
+
setStateValue(key, value) {
|
|
387
|
+
this.state[key] = value;
|
|
388
|
+
}
|
|
389
|
+
// Query Operations
|
|
390
|
+
findByTrait(traitType) {
|
|
391
|
+
return this.findWhere(e => e.hasTrait(traitType));
|
|
392
|
+
}
|
|
393
|
+
findByType(entityType) {
|
|
394
|
+
return this.findWhere(e => e.type === entityType);
|
|
395
|
+
}
|
|
396
|
+
findWhere(predicate) {
|
|
397
|
+
return Array.from(this.entities.values()).filter(predicate);
|
|
398
|
+
}
|
|
399
|
+
// Scope methods moved to end of class to use new scope system
|
|
400
|
+
// Relationship Queries
|
|
401
|
+
relationships = new Map();
|
|
402
|
+
getRelated(entityId, relationshipType) {
|
|
403
|
+
const entityRels = this.relationships.get(entityId);
|
|
404
|
+
if (!entityRels)
|
|
405
|
+
return [];
|
|
406
|
+
const related = entityRels.get(relationshipType);
|
|
407
|
+
return related ? Array.from(related) : [];
|
|
408
|
+
}
|
|
409
|
+
areRelated(entity1Id, entity2Id, relationshipType) {
|
|
410
|
+
const related = this.getRelated(entity1Id, relationshipType);
|
|
411
|
+
return related.includes(entity2Id);
|
|
412
|
+
}
|
|
413
|
+
addRelationship(entity1Id, entity2Id, relationshipType) {
|
|
414
|
+
// Ensure entities exist
|
|
415
|
+
if (!this.hasEntity(entity1Id) || !this.hasEntity(entity2Id)) {
|
|
416
|
+
if (this.config.strictMode) {
|
|
417
|
+
throw new Error('Cannot add relationship between non-existent entities');
|
|
418
|
+
}
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
// Add forward relationship
|
|
422
|
+
if (!this.relationships.has(entity1Id)) {
|
|
423
|
+
this.relationships.set(entity1Id, new Map());
|
|
424
|
+
}
|
|
425
|
+
const entityRels = this.relationships.get(entity1Id);
|
|
426
|
+
if (!entityRels.has(relationshipType)) {
|
|
427
|
+
entityRels.set(relationshipType, new Set());
|
|
428
|
+
}
|
|
429
|
+
entityRels.get(relationshipType).add(entity2Id);
|
|
430
|
+
}
|
|
431
|
+
removeRelationship(entity1Id, entity2Id, relationshipType) {
|
|
432
|
+
const entityRels = this.relationships.get(entity1Id);
|
|
433
|
+
if (!entityRels)
|
|
434
|
+
return;
|
|
435
|
+
const related = entityRels.get(relationshipType);
|
|
436
|
+
if (related) {
|
|
437
|
+
related.delete(entity2Id);
|
|
438
|
+
if (related.size === 0) {
|
|
439
|
+
entityRels.delete(relationshipType);
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
if (entityRels.size === 0) {
|
|
443
|
+
this.relationships.delete(entity1Id);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
// Utility Methods
|
|
447
|
+
getTotalWeight(entityId) {
|
|
448
|
+
const entity = this.getEntity(entityId);
|
|
449
|
+
if (!entity)
|
|
450
|
+
return 0;
|
|
451
|
+
let weight = entity.weight || 0;
|
|
452
|
+
// Add weight of all contents
|
|
453
|
+
const contents = this.getAllContents(entityId, { recursive: true });
|
|
454
|
+
for (const item of contents) {
|
|
455
|
+
weight += item.weight || 0;
|
|
456
|
+
}
|
|
457
|
+
return weight;
|
|
458
|
+
}
|
|
459
|
+
wouldCreateLoop(entityId, targetId) {
|
|
460
|
+
if (entityId === targetId)
|
|
461
|
+
return true;
|
|
462
|
+
let current = targetId;
|
|
463
|
+
const visited = new Set();
|
|
464
|
+
while (current) {
|
|
465
|
+
if (visited.has(current))
|
|
466
|
+
return false; // Already checked this path
|
|
467
|
+
if (current === entityId)
|
|
468
|
+
return true; // Found a loop
|
|
469
|
+
visited.add(current);
|
|
470
|
+
current = this.getLocation(current) || '';
|
|
471
|
+
}
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
findPath(fromRoomId, toRoomId) {
|
|
475
|
+
if (fromRoomId === toRoomId)
|
|
476
|
+
return [];
|
|
477
|
+
const fromRoom = this.getEntity(fromRoomId);
|
|
478
|
+
const toRoom = this.getEntity(toRoomId);
|
|
479
|
+
if (!fromRoom?.hasTrait(trait_types_1.TraitType.ROOM) || !toRoom?.hasTrait(trait_types_1.TraitType.ROOM)) {
|
|
480
|
+
return null;
|
|
481
|
+
}
|
|
482
|
+
// Simple BFS pathfinding
|
|
483
|
+
const queue = [{ roomId: fromRoomId, path: [] }];
|
|
484
|
+
const visited = new Set();
|
|
485
|
+
while (queue.length > 0) {
|
|
486
|
+
const { roomId, path } = queue.shift();
|
|
487
|
+
if (visited.has(roomId))
|
|
488
|
+
continue;
|
|
489
|
+
visited.add(roomId);
|
|
490
|
+
// Get exits from this room
|
|
491
|
+
const room = this.getEntity(roomId);
|
|
492
|
+
if (!room)
|
|
493
|
+
continue;
|
|
494
|
+
const exits = room.getTrait(trait_types_1.TraitType.ROOM)?.exits || {};
|
|
495
|
+
for (const [direction, exitInfo] of Object.entries(exits)) {
|
|
496
|
+
let targetRoom;
|
|
497
|
+
let pathElement;
|
|
498
|
+
if (typeof exitInfo === 'string') {
|
|
499
|
+
// Simple string - treat as direct room connection
|
|
500
|
+
targetRoom = exitInfo;
|
|
501
|
+
pathElement = exitInfo; // For now, use room ID as path element
|
|
502
|
+
}
|
|
503
|
+
else if (typeof exitInfo === 'object') {
|
|
504
|
+
// ExitInfo object
|
|
505
|
+
if (exitInfo.via) {
|
|
506
|
+
// Has a door/exit entity
|
|
507
|
+
const exitEntity = this.getEntity(exitInfo.via);
|
|
508
|
+
if (!exitEntity)
|
|
509
|
+
continue;
|
|
510
|
+
pathElement = exitInfo.via;
|
|
511
|
+
// Get destination based on entity type
|
|
512
|
+
if (exitEntity.hasTrait(trait_types_1.TraitType.DOOR)) {
|
|
513
|
+
const door = exitEntity.getTrait(trait_types_1.TraitType.DOOR);
|
|
514
|
+
targetRoom = door?.room1 === roomId ? door?.room2 : door?.room1;
|
|
515
|
+
}
|
|
516
|
+
else if (exitEntity.hasTrait(trait_types_1.TraitType.EXIT)) {
|
|
517
|
+
targetRoom = exitEntity.getTrait(trait_types_1.TraitType.EXIT)?.to;
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
// Not a valid door/exit entity
|
|
521
|
+
continue;
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
else if (exitInfo.destination) {
|
|
525
|
+
// Direct room connection
|
|
526
|
+
targetRoom = exitInfo.destination;
|
|
527
|
+
pathElement = targetRoom; // Use room ID as path element
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (!targetRoom || !pathElement)
|
|
531
|
+
continue;
|
|
532
|
+
if (targetRoom === toRoomId) {
|
|
533
|
+
// Found the destination - return path
|
|
534
|
+
// For direct connections, return empty array (no doors to pass through)
|
|
535
|
+
if (pathElement === targetRoom && path.length === 0) {
|
|
536
|
+
return [];
|
|
537
|
+
}
|
|
538
|
+
return [...path, pathElement];
|
|
539
|
+
}
|
|
540
|
+
if (!visited.has(targetRoom)) {
|
|
541
|
+
// For direct connections, don't add room ID to path
|
|
542
|
+
const newPath = pathElement === targetRoom ? path : [...path, pathElement];
|
|
543
|
+
queue.push({ roomId: targetRoom, path: newPath });
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return null;
|
|
548
|
+
}
|
|
549
|
+
getPlayer() {
|
|
550
|
+
return this.playerId ? this.getEntity(this.playerId) : undefined;
|
|
551
|
+
}
|
|
552
|
+
setPlayer(entityId) {
|
|
553
|
+
if (!this.hasEntity(entityId)) {
|
|
554
|
+
throw new Error(`Cannot set player to non-existent entity: ${entityId}`);
|
|
555
|
+
}
|
|
556
|
+
this.playerId = entityId;
|
|
557
|
+
}
|
|
558
|
+
// Persistence
|
|
559
|
+
toJSON() {
|
|
560
|
+
const data = {
|
|
561
|
+
entities: Array.from(this.entities.entries()).map(([id, entity]) => ({
|
|
562
|
+
id,
|
|
563
|
+
entity: entity.toJSON()
|
|
564
|
+
})),
|
|
565
|
+
state: this.state,
|
|
566
|
+
playerId: this.playerId,
|
|
567
|
+
spatialIndex: this.spatialIndex.toJSON(),
|
|
568
|
+
relationships: Array.from(this.relationships.entries()).map(([entityId, rels]) => ({
|
|
569
|
+
entityId,
|
|
570
|
+
relationships: Array.from(rels.entries()).map(([type, related]) => ({
|
|
571
|
+
type,
|
|
572
|
+
related: Array.from(related)
|
|
573
|
+
}))
|
|
574
|
+
})),
|
|
575
|
+
// Add ID system data
|
|
576
|
+
idCounters: Array.from(this.idCounters.entries()),
|
|
577
|
+
// Add capabilities
|
|
578
|
+
capabilities: Object.entries(this.capabilities).map(([name, cap]) => ({
|
|
579
|
+
name,
|
|
580
|
+
data: cap.data,
|
|
581
|
+
schema: cap.schema
|
|
582
|
+
}))
|
|
583
|
+
};
|
|
584
|
+
return JSON.stringify(data, null, 2);
|
|
585
|
+
}
|
|
586
|
+
loadJSON(json) {
|
|
587
|
+
const data = JSON.parse(json);
|
|
588
|
+
// Clear current state
|
|
589
|
+
this.clear();
|
|
590
|
+
// Restore entities
|
|
591
|
+
for (const { id, entity } of data.entities) {
|
|
592
|
+
const newEntity = if_entity_1.IFEntity.fromJSON(entity);
|
|
593
|
+
this.entities.set(id, newEntity);
|
|
594
|
+
}
|
|
595
|
+
// Restore state
|
|
596
|
+
this.state = data.state || {};
|
|
597
|
+
this.playerId = data.playerId;
|
|
598
|
+
// Restore spatial index
|
|
599
|
+
if (data.spatialIndex) {
|
|
600
|
+
this.spatialIndex.loadJSON(data.spatialIndex);
|
|
601
|
+
}
|
|
602
|
+
// Restore relationships
|
|
603
|
+
if (data.relationships) {
|
|
604
|
+
for (const { entityId, relationships } of data.relationships) {
|
|
605
|
+
const entityRels = new Map();
|
|
606
|
+
for (const { type, related } of relationships) {
|
|
607
|
+
entityRels.set(type, new Set(related));
|
|
608
|
+
}
|
|
609
|
+
this.relationships.set(entityId, entityRels);
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
// Restore ID system data
|
|
613
|
+
if (data.idCounters) {
|
|
614
|
+
this.idCounters = new Map(data.idCounters);
|
|
615
|
+
}
|
|
616
|
+
else {
|
|
617
|
+
// Rebuild ID counters from existing entities for backward compatibility
|
|
618
|
+
this.rebuildIdCounters();
|
|
619
|
+
}
|
|
620
|
+
// Restore capabilities
|
|
621
|
+
if (data.capabilities) {
|
|
622
|
+
for (const { name, data: capData, schema } of data.capabilities) {
|
|
623
|
+
this.capabilities[name] = {
|
|
624
|
+
data: capData,
|
|
625
|
+
schema
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
clear() {
|
|
631
|
+
this.entities.clear();
|
|
632
|
+
this.state = {};
|
|
633
|
+
this.playerId = undefined;
|
|
634
|
+
this.spatialIndex.clear();
|
|
635
|
+
this.relationships.clear();
|
|
636
|
+
this.appliedEvents = [];
|
|
637
|
+
this.idCounters.clear();
|
|
638
|
+
this.capabilities = {};
|
|
639
|
+
this.grammarVocabularyProvider.clear();
|
|
640
|
+
this.eventChains.clear();
|
|
641
|
+
}
|
|
642
|
+
// Event Sourcing Implementation
|
|
643
|
+
registerEventHandler(eventType, handler) {
|
|
644
|
+
this.eventHandlers.set(eventType, handler);
|
|
645
|
+
// If already connected to EventProcessor, wire this handler immediately (ADR-086)
|
|
646
|
+
if (this.eventProcessorWiring) {
|
|
647
|
+
this.wireHandlerToProcessor(eventType, handler);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
unregisterEventHandler(eventType) {
|
|
651
|
+
this.eventHandlers.delete(eventType);
|
|
652
|
+
// Note: We don't unregister from EventProcessor as it doesn't support removal by type
|
|
653
|
+
// Handlers will still be called but won't find the handler in eventHandlers
|
|
654
|
+
}
|
|
655
|
+
registerEventValidator(eventType, validator) {
|
|
656
|
+
this.eventValidators.set(eventType, validator);
|
|
657
|
+
}
|
|
658
|
+
registerEventPreviewer(eventType, previewer) {
|
|
659
|
+
this.eventPreviewers.set(eventType, previewer);
|
|
660
|
+
}
|
|
661
|
+
/**
|
|
662
|
+
* Connect this WorldModel to the engine's EventProcessor (ADR-086).
|
|
663
|
+
* Wires all existing handlers and chains, and enables automatic wiring for future ones.
|
|
664
|
+
*/
|
|
665
|
+
connectEventProcessor(wiring) {
|
|
666
|
+
this.eventProcessorWiring = wiring;
|
|
667
|
+
// Wire all existing handlers
|
|
668
|
+
for (const [eventType, handler] of this.eventHandlers) {
|
|
669
|
+
this.wireHandlerToProcessor(eventType, handler);
|
|
670
|
+
}
|
|
671
|
+
// Wire all existing chains (ADR-094)
|
|
672
|
+
for (const triggerType of this.eventChains.keys()) {
|
|
673
|
+
this.wireChainToProcessor(triggerType);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
/**
|
|
677
|
+
* Adapt a WorldModel handler to EventProcessor signature and register it.
|
|
678
|
+
*/
|
|
679
|
+
wireHandlerToProcessor(eventType, handler) {
|
|
680
|
+
if (!this.eventProcessorWiring)
|
|
681
|
+
return;
|
|
682
|
+
// Adapt the handler: WorldModel handlers return void, EventProcessor expects Effect[]
|
|
683
|
+
const adaptedHandler = (event) => {
|
|
684
|
+
handler(event, this);
|
|
685
|
+
return [];
|
|
686
|
+
};
|
|
687
|
+
this.eventProcessorWiring.registerHandler(eventType, adaptedHandler);
|
|
688
|
+
}
|
|
689
|
+
/**
|
|
690
|
+
* Register an event chain handler (ADR-094).
|
|
691
|
+
* Chain handlers produce new events when a trigger event occurs.
|
|
692
|
+
*/
|
|
693
|
+
chainEvent(triggerType, handler, options = {}) {
|
|
694
|
+
const { mode = 'cascade', key, priority = 100 } = options;
|
|
695
|
+
const registration = { handler, key, priority };
|
|
696
|
+
if (!this.eventChains.has(triggerType)) {
|
|
697
|
+
this.eventChains.set(triggerType, []);
|
|
698
|
+
}
|
|
699
|
+
const chains = this.eventChains.get(triggerType);
|
|
700
|
+
if (mode === 'override') {
|
|
701
|
+
// Replace all existing chains
|
|
702
|
+
this.eventChains.set(triggerType, [registration]);
|
|
703
|
+
}
|
|
704
|
+
else if (key) {
|
|
705
|
+
// Replace chain with same key, or add
|
|
706
|
+
const existingIndex = chains.findIndex(c => c.key === key);
|
|
707
|
+
if (existingIndex >= 0) {
|
|
708
|
+
chains[existingIndex] = registration;
|
|
709
|
+
}
|
|
710
|
+
else {
|
|
711
|
+
chains.push(registration);
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
else {
|
|
715
|
+
// Cascade - just add
|
|
716
|
+
chains.push(registration);
|
|
717
|
+
}
|
|
718
|
+
// Sort by priority (lower = earlier)
|
|
719
|
+
chains.sort((a, b) => a.priority - b.priority);
|
|
720
|
+
// Wire to EventProcessor if connected
|
|
721
|
+
if (this.eventProcessorWiring) {
|
|
722
|
+
this.wireChainToProcessor(triggerType);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
/**
|
|
726
|
+
* Wire chains for a trigger type to the EventProcessor.
|
|
727
|
+
* Chain handlers return events to be emitted.
|
|
728
|
+
*/
|
|
729
|
+
wireChainToProcessor(triggerType) {
|
|
730
|
+
if (!this.eventProcessorWiring)
|
|
731
|
+
return;
|
|
732
|
+
// Register a handler that invokes all chains and returns EmitEffect objects
|
|
733
|
+
// The event processor expects Effect[] not ISemanticEvent[]
|
|
734
|
+
this.eventProcessorWiring.registerHandler(triggerType, (event) => {
|
|
735
|
+
const chainedEvents = this.executeChains(triggerType, event);
|
|
736
|
+
// Wrap each event as an EmitEffect
|
|
737
|
+
return chainedEvents.map(e => ({ type: 'emit', event: e }));
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Execute all chains for a trigger type and collect their events.
|
|
742
|
+
*/
|
|
743
|
+
executeChains(triggerType, event) {
|
|
744
|
+
const chains = this.eventChains.get(triggerType) || [];
|
|
745
|
+
const results = [];
|
|
746
|
+
// Get chain metadata from trigger event's data (ADR-094)
|
|
747
|
+
const triggerData = (event.data || {});
|
|
748
|
+
const currentDepth = triggerData._chainDepth || 0;
|
|
749
|
+
const transactionId = triggerData._transactionId;
|
|
750
|
+
for (const chain of chains) {
|
|
751
|
+
const chainedEvents = chain.handler(event, this);
|
|
752
|
+
if (chainedEvents) {
|
|
753
|
+
const eventsArray = Array.isArray(chainedEvents) ? chainedEvents : [chainedEvents];
|
|
754
|
+
// Add chain metadata to each event
|
|
755
|
+
for (const chainedEvent of eventsArray) {
|
|
756
|
+
const newDepth = currentDepth + 1;
|
|
757
|
+
// Safety: prevent infinite loops (max depth 10)
|
|
758
|
+
if (newDepth > 10) {
|
|
759
|
+
console.warn(`Chain depth exceeded for ${chainedEvent.type}, skipping`);
|
|
760
|
+
continue;
|
|
761
|
+
}
|
|
762
|
+
// Ensure the event has required fields and add chain metadata to data
|
|
763
|
+
const existingData = (chainedEvent.data || {});
|
|
764
|
+
const enrichedEvent = {
|
|
765
|
+
id: chainedEvent.id || `chain-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
766
|
+
type: chainedEvent.type,
|
|
767
|
+
timestamp: chainedEvent.timestamp || Date.now(),
|
|
768
|
+
entities: chainedEvent.entities || {},
|
|
769
|
+
data: {
|
|
770
|
+
...existingData,
|
|
771
|
+
_chainedFrom: event.type,
|
|
772
|
+
_chainSourceId: event.id,
|
|
773
|
+
_chainDepth: newDepth,
|
|
774
|
+
// Pass through transactionId from trigger event (ADR-094)
|
|
775
|
+
// Engine assigns this at action start; chained events inherit it
|
|
776
|
+
...(transactionId ? { _transactionId: transactionId } : {})
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
results.push(enrichedEvent);
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
return results;
|
|
784
|
+
}
|
|
785
|
+
applyEvent(event) {
|
|
786
|
+
// First validate if we can apply this event
|
|
787
|
+
if (!this.canApplyEvent(event)) {
|
|
788
|
+
throw new Error(`Cannot apply event of type '${event.type}': validation failed`);
|
|
789
|
+
}
|
|
790
|
+
// Look up handler for this event type
|
|
791
|
+
const handler = this.eventHandlers.get(event.type);
|
|
792
|
+
if (!handler) {
|
|
793
|
+
// No handler registered - event is recorded but has no effect
|
|
794
|
+
// Silent when no handler - this is a valid use case
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
// Apply the event through the handler
|
|
798
|
+
handler(event, this);
|
|
799
|
+
}
|
|
800
|
+
// Record the event in history
|
|
801
|
+
this.appliedEvents.push(event);
|
|
802
|
+
// Trim history if it exceeds the limit
|
|
803
|
+
if (this.appliedEvents.length > this.maxEventHistory) {
|
|
804
|
+
this.appliedEvents = this.appliedEvents.slice(-this.maxEventHistory);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
canApplyEvent(event) {
|
|
808
|
+
// Check if there's a validator for this event type
|
|
809
|
+
const validator = this.eventValidators.get(event.type);
|
|
810
|
+
// If no validator registered, assume event is valid
|
|
811
|
+
if (!validator) {
|
|
812
|
+
return true;
|
|
813
|
+
}
|
|
814
|
+
// Run the validator
|
|
815
|
+
return validator(event, this);
|
|
816
|
+
}
|
|
817
|
+
previewEvent(event) {
|
|
818
|
+
// Check if there's a previewer for this event type
|
|
819
|
+
const previewer = this.eventPreviewers.get(event.type);
|
|
820
|
+
// If no previewer registered, return empty array
|
|
821
|
+
if (!previewer) {
|
|
822
|
+
return [];
|
|
823
|
+
}
|
|
824
|
+
// Run the previewer
|
|
825
|
+
return previewer(event, this);
|
|
826
|
+
}
|
|
827
|
+
getAppliedEvents() {
|
|
828
|
+
return [...this.appliedEvents];
|
|
829
|
+
}
|
|
830
|
+
getEventsSince(timestamp) {
|
|
831
|
+
return this.appliedEvents.filter(event => event.timestamp > timestamp);
|
|
832
|
+
}
|
|
833
|
+
clearEventHistory() {
|
|
834
|
+
this.appliedEvents = [];
|
|
835
|
+
}
|
|
836
|
+
// Rebuild ID counters by analyzing existing entities
|
|
837
|
+
rebuildIdCounters() {
|
|
838
|
+
// Clear counters
|
|
839
|
+
this.idCounters.clear();
|
|
840
|
+
// Find the highest ID for each prefix
|
|
841
|
+
for (const entity of this.entities.values()) {
|
|
842
|
+
const id = entity.id;
|
|
843
|
+
if (id.length >= 3) {
|
|
844
|
+
const prefix = id[0];
|
|
845
|
+
const numPart = id.substring(1);
|
|
846
|
+
// Parse the numeric part (base36)
|
|
847
|
+
const num = parseInt(numPart, 36);
|
|
848
|
+
if (!isNaN(num)) {
|
|
849
|
+
const currentMax = this.idCounters.get(prefix) || 0;
|
|
850
|
+
if (num > currentMax) {
|
|
851
|
+
this.idCounters.set(prefix, num);
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
// Get the data store for sharing with AuthorModel
|
|
858
|
+
getDataStore() {
|
|
859
|
+
// Return a reference to the WorldModel's internal state
|
|
860
|
+
// AuthorModel will share these same objects
|
|
861
|
+
return {
|
|
862
|
+
entities: this.entities,
|
|
863
|
+
spatialIndex: this.spatialIndex,
|
|
864
|
+
state: this.state,
|
|
865
|
+
playerId: this.playerId,
|
|
866
|
+
relationships: this.relationships,
|
|
867
|
+
idCounters: this.idCounters,
|
|
868
|
+
capabilities: this.capabilities
|
|
869
|
+
};
|
|
870
|
+
}
|
|
871
|
+
// Scope Management Methods
|
|
872
|
+
getScopeRegistry() {
|
|
873
|
+
return this.scopeRegistry;
|
|
874
|
+
}
|
|
875
|
+
// Vocabulary Management (ADR-082)
|
|
876
|
+
getGrammarVocabularyProvider() {
|
|
877
|
+
return this.grammarVocabularyProvider;
|
|
878
|
+
}
|
|
879
|
+
addScopeRule(rule) {
|
|
880
|
+
this.scopeRegistry.addRule(rule);
|
|
881
|
+
this.emitPlatformEvent('scope_rule_added', {
|
|
882
|
+
ruleId: rule.id,
|
|
883
|
+
fromLocations: rule.fromLocations,
|
|
884
|
+
forActions: rule.forActions
|
|
885
|
+
});
|
|
886
|
+
}
|
|
887
|
+
removeScopeRule(ruleId) {
|
|
888
|
+
const removed = this.scopeRegistry.removeRule(ruleId);
|
|
889
|
+
if (removed) {
|
|
890
|
+
this.emitPlatformEvent('scope_rule_removed', { ruleId });
|
|
891
|
+
}
|
|
892
|
+
return removed;
|
|
893
|
+
}
|
|
894
|
+
evaluateScope(actorId, actionId) {
|
|
895
|
+
const actor = this.getEntity(actorId);
|
|
896
|
+
if (!actor) {
|
|
897
|
+
console.warn('evaluateScope: No actor found for ID:', actorId);
|
|
898
|
+
return [];
|
|
899
|
+
}
|
|
900
|
+
const currentLocation = this.getLocation(actorId);
|
|
901
|
+
if (!currentLocation) {
|
|
902
|
+
console.warn('evaluateScope: No location found for actor:', actorId);
|
|
903
|
+
return [];
|
|
904
|
+
}
|
|
905
|
+
const context = {
|
|
906
|
+
world: this,
|
|
907
|
+
actorId,
|
|
908
|
+
actionId,
|
|
909
|
+
currentLocation
|
|
910
|
+
};
|
|
911
|
+
const result = this.scopeEvaluator.evaluate(context);
|
|
912
|
+
return Array.from(result.entityIds);
|
|
913
|
+
}
|
|
914
|
+
/**
|
|
915
|
+
* Register default scope rules for standard visibility
|
|
916
|
+
*/
|
|
917
|
+
registerDefaultScopeRules() {
|
|
918
|
+
// Basic visibility rule - entities in same room
|
|
919
|
+
this.addScopeRule({
|
|
920
|
+
id: 'default_room_visibility',
|
|
921
|
+
fromLocations: '*',
|
|
922
|
+
includeEntities: (context) => {
|
|
923
|
+
const room = this.getEntity(context.currentLocation);
|
|
924
|
+
if (!room) {
|
|
925
|
+
console.warn('No room found for location:', context.currentLocation);
|
|
926
|
+
return [];
|
|
927
|
+
}
|
|
928
|
+
// Get all entities in the room
|
|
929
|
+
const contents = this.getContents(context.currentLocation);
|
|
930
|
+
const entityIds = contents.map(e => e.id);
|
|
931
|
+
// Add the room itself
|
|
932
|
+
entityIds.push(context.currentLocation);
|
|
933
|
+
// Add nested contents (in containers, on supporters)
|
|
934
|
+
for (const entity of contents) {
|
|
935
|
+
const nested = this.getAllContents(entity.id);
|
|
936
|
+
entityIds.push(...nested.map(e => e.id));
|
|
937
|
+
}
|
|
938
|
+
return entityIds;
|
|
939
|
+
},
|
|
940
|
+
priority: 50,
|
|
941
|
+
source: 'core'
|
|
942
|
+
});
|
|
943
|
+
// Carried items are always in scope
|
|
944
|
+
this.addScopeRule({
|
|
945
|
+
id: 'default_inventory_visibility',
|
|
946
|
+
fromLocations: '*',
|
|
947
|
+
includeEntities: (context) => {
|
|
948
|
+
const carried = this.getContents(context.actorId);
|
|
949
|
+
const entityIds = carried.map(e => e.id);
|
|
950
|
+
// Add nested contents of carried items
|
|
951
|
+
for (const entity of carried) {
|
|
952
|
+
const nested = this.getAllContents(entity.id);
|
|
953
|
+
entityIds.push(...nested.map(e => e.id));
|
|
954
|
+
}
|
|
955
|
+
return entityIds;
|
|
956
|
+
},
|
|
957
|
+
priority: 100,
|
|
958
|
+
source: 'core'
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
/**
|
|
962
|
+
* Get physically visible entities using VisibilityBehavior (line-of-sight)
|
|
963
|
+
*
|
|
964
|
+
* Returns entities that can actually be seen by the observer based on:
|
|
965
|
+
* - Physical location (must be in same room)
|
|
966
|
+
* - Container state (can't see inside closed opaque containers)
|
|
967
|
+
* - Lighting conditions (limited visibility in darkness)
|
|
968
|
+
* - Scenery visibility flags
|
|
969
|
+
*
|
|
970
|
+
* This is for perception and display purposes. For command resolution,
|
|
971
|
+
* use getInScope() instead which includes entities that can be referenced
|
|
972
|
+
* even if not visible.
|
|
973
|
+
*
|
|
974
|
+
* @param observerId - The entity doing the observing
|
|
975
|
+
* @returns Array of entities that are physically visible
|
|
976
|
+
*/
|
|
977
|
+
getVisible(observerId) {
|
|
978
|
+
const observer = this.getEntity(observerId);
|
|
979
|
+
if (!observer)
|
|
980
|
+
return [];
|
|
981
|
+
return VisibilityBehavior_1.VisibilityBehavior.getVisible(observer, this);
|
|
982
|
+
}
|
|
983
|
+
/**
|
|
984
|
+
* Get entities in scope for command resolution using the scope system
|
|
985
|
+
*
|
|
986
|
+
* Returns entities that can be referenced in commands, including:
|
|
987
|
+
* - All entities in the current room
|
|
988
|
+
* - Items in containers (even closed ones)
|
|
989
|
+
* - Carried items and their contents
|
|
990
|
+
* - Entities made available by scope rules (e.g., through windows)
|
|
991
|
+
*
|
|
992
|
+
* This is for parser/command resolution. For physical visibility,
|
|
993
|
+
* use getVisible() instead.
|
|
994
|
+
*
|
|
995
|
+
* @param observerId - The entity whose scope to evaluate
|
|
996
|
+
* @returns Array of entities that can be referenced in commands
|
|
997
|
+
*/
|
|
998
|
+
getInScope(observerId) {
|
|
999
|
+
const entityIds = this.evaluateScope(observerId);
|
|
1000
|
+
return entityIds
|
|
1001
|
+
.map(id => this.getEntity(id))
|
|
1002
|
+
.filter((e) => e !== undefined);
|
|
1003
|
+
}
|
|
1004
|
+
/**
|
|
1005
|
+
* Check if observer can physically see target (line-of-sight)
|
|
1006
|
+
*
|
|
1007
|
+
* Uses VisibilityBehavior to determine if target is visible based on:
|
|
1008
|
+
* - Physical location
|
|
1009
|
+
* - Container state
|
|
1010
|
+
* - Lighting conditions
|
|
1011
|
+
*
|
|
1012
|
+
* This is for perception checks. To check if an entity can be
|
|
1013
|
+
* referenced in commands, check if it's in getInScope() instead.
|
|
1014
|
+
*
|
|
1015
|
+
* @param observerId - The entity doing the observing
|
|
1016
|
+
* @param targetId - The entity being observed
|
|
1017
|
+
* @returns true if observer can see target
|
|
1018
|
+
*/
|
|
1019
|
+
canSee(observerId, targetId) {
|
|
1020
|
+
const observer = this.getEntity(observerId);
|
|
1021
|
+
const target = this.getEntity(targetId);
|
|
1022
|
+
if (!observer || !target)
|
|
1023
|
+
return false;
|
|
1024
|
+
return VisibilityBehavior_1.VisibilityBehavior.canSee(observer, target, this);
|
|
1025
|
+
}
|
|
1026
|
+
}
|
|
1027
|
+
exports.WorldModel = WorldModel;
|
|
1028
|
+
//# sourceMappingURL=WorldModel.js.map
|