@almadar/ui 1.0.21 → 1.0.23

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.
@@ -3,7 +3,7 @@ import React__default from 'react';
3
3
  import { LucideIcon } from 'lucide-react';
4
4
  import { SExpr } from '@almadar/evaluator';
5
5
  import * as react_jsx_runtime from 'react/jsx-runtime';
6
- export { AuthContextValue, AuthUser, ChangeSummary, CompileResult, CompileStage, ENTITY_EVENTS, EntityDataRecord, EntityMutationResult, Extension, ExtensionManifest, FileSystemFile, FileSystemStatus, GitHubRepo, GitHubStatus, HistoryTimelineItem, OpenFile, OrbitalEventPayload, OrbitalEventResponse, QuerySingletonEntity, QuerySingletonResult, QuerySingletonState, QueryState, RevertResult, SelectedFile, UseCompileResult, UseEntityDetailResult, UseEntityListOptions, UseEntityListResult, UseEntityMutationsOptions, UseExtensionsOptions, UseExtensionsResult, UseFileEditorOptions, UseFileEditorResult, UseFileSystemResult, UseOrbitalHistoryOptions, UseOrbitalHistoryResult, entityDataKeys, parseQueryBinding, useAgentChat, useAuthContext, useCompile, useConnectGitHub, useCreateEntity, useDeepAgentGeneration, useDeleteEntity, useDisconnectGitHub, useEmitEvent, useEntities, useEntitiesByType, useEntity, useEntityById, useEntityDetail, useEntityList, useEntityMutations, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInput, useOrbitalHistory, useOrbitalMutations, usePhysics, usePlayer, usePreview, useQuerySingleton, useSelectedEntity, useSendOrbitalEvent, useSingletonEntity, useUIEvents, useUpdateEntity, useValidation } from '../hooks/index.js';
6
+ export { AuthContextValue, AuthUser, ChangeSummary, CompileResult, CompileStage, ENTITY_EVENTS, EntityDataAdapter, EntityDataProvider, EntityDataRecord, EntityMutationResult, Extension, ExtensionManifest, FileSystemFile, FileSystemStatus, GitHubRepo, GitHubStatus, HistoryTimelineItem, OpenFile, OrbitalEventPayload, OrbitalEventResponse, QuerySingletonEntity, QuerySingletonResult, QuerySingletonState, QueryState, RevertResult, SelectedFile, UseCompileResult, UseEntityDetailResult, UseEntityListOptions, UseEntityListResult, UseEntityMutationsOptions, UseExtensionsOptions, UseExtensionsResult, UseFileEditorOptions, UseFileEditorResult, UseFileSystemResult, UseOrbitalHistoryOptions, UseOrbitalHistoryResult, entityDataKeys, parseQueryBinding, useAgentChat, useAuthContext, useCompile, useConnectGitHub, useCreateEntity, useDeepAgentGeneration, useDeleteEntity, useDisconnectGitHub, useEmitEvent, useEntities, useEntitiesByType, useEntity, useEntityById, useEntityDataAdapter, useEntityDetail, useEntityList, useEntityMutations, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useInput, useOrbitalHistory, useOrbitalMutations, usePhysics, usePlayer, usePreview, useQuerySingleton, useSelectedEntity, useSendOrbitalEvent, useSingletonEntity, useUIEvents, useUpdateEntity, useValidation } from '../hooks/index.js';
7
7
  import { E as EventBusContextType } from '../event-bus-types-8-cjyMxw.js';
8
8
  export { a as EventListener, K as KFlowEvent, U as Unsubscribe } from '../event-bus-types-8-cjyMxw.js';
9
9
  import { S as SlotContent, a as UISlot } from '../useUISlots-mnggE9X9.js';
@@ -3803,12 +3803,18 @@ declare const TabbedContainer: React__default.FC<TabbedContainerProps>;
3803
3803
  */
3804
3804
  /** A single isometric tile on the grid */
3805
3805
  interface IsometricTile {
3806
+ /** Optional unique identifier (required for 3D rendering) */
3807
+ id?: string;
3806
3808
  /** Grid x coordinate */
3807
3809
  x: number;
3808
- /** Grid y coordinate */
3810
+ /** Grid y coordinate (2D) */
3809
3811
  y: number;
3810
- /** Terrain type key (e.g., 'grass', 'stone', 'water') */
3811
- terrain: string;
3812
+ /** Grid z coordinate (3D alternative to y) */
3813
+ z?: number;
3814
+ /** Terrain type key (e.g., 'grass', 'stone', 'water') - 2D */
3815
+ terrain?: string;
3816
+ /** Tile type for visual rendering (3D) */
3817
+ type?: string;
3812
3818
  /** Direct sprite URL override (bypasses getTerrainSprite resolver) */
3813
3819
  terrainSprite?: string;
3814
3820
  /** Whether units can traverse this tile (default true) */
@@ -3817,16 +3823,24 @@ interface IsometricTile {
3817
3823
  movementCost?: number;
3818
3824
  /** Optional tile type for visual variants */
3819
3825
  tileType?: string;
3826
+ /** Elevation offset for 3D rendering */
3827
+ elevation?: number;
3820
3828
  }
3821
3829
  /** A unit positioned on the isometric grid */
3822
3830
  interface IsometricUnit {
3823
3831
  /** Unique unit identifier */
3824
3832
  id: string;
3825
- /** Current grid position */
3826
- position: {
3833
+ /** Current grid position (2D format) */
3834
+ position?: {
3827
3835
  x: number;
3828
3836
  y: number;
3829
3837
  };
3838
+ /** Grid x coordinate (3D format) */
3839
+ x?: number;
3840
+ /** Grid y coordinate (3D format) */
3841
+ y?: number;
3842
+ /** Grid z coordinate (3D format) */
3843
+ z?: number;
3830
3844
  /** Static sprite URL (used when no sprite sheet animation) */
3831
3845
  sprite?: string;
3832
3846
  /** Unit archetype key for sprite resolution */
@@ -3837,6 +3851,8 @@ interface IsometricUnit {
3837
3851
  name?: string;
3838
3852
  /** Team affiliation for coloring */
3839
3853
  team?: 'player' | 'enemy' | 'neutral';
3854
+ /** Faction for 3D rendering (player/enemy/neutral) */
3855
+ faction?: 'player' | 'enemy' | 'neutral';
3840
3856
  /** Current health */
3841
3857
  health?: number;
3842
3858
  /** Maximum health */
@@ -3853,17 +3869,29 @@ interface IsometricUnit {
3853
3869
  x: number;
3854
3870
  y: number;
3855
3871
  };
3872
+ /** Elevation offset for 3D rendering */
3873
+ elevation?: number;
3856
3874
  }
3857
3875
  /** A map feature (resource, building, portal, etc.) */
3858
3876
  interface IsometricFeature {
3877
+ /** Optional unique identifier (required for 3D rendering) */
3878
+ id?: string;
3859
3879
  /** Grid x coordinate */
3860
3880
  x: number;
3861
- /** Grid y coordinate */
3881
+ /** Grid y coordinate (2D) */
3862
3882
  y: number;
3883
+ /** Grid z coordinate (3D alternative to y) */
3884
+ z?: number;
3863
3885
  /** Feature type key (e.g., 'goldMine', 'castle', 'portal') */
3864
3886
  type: string;
3865
3887
  /** Direct sprite URL override (bypasses getFeatureSprite resolver) */
3866
3888
  sprite?: string;
3889
+ /** 3D model URL (GLB format) for GameCanvas3D */
3890
+ assetUrl?: string;
3891
+ /** Color override for 3D rendering */
3892
+ color?: string;
3893
+ /** Elevation offset for 3D rendering */
3894
+ elevation?: number;
3867
3895
  }
3868
3896
  /** Camera state for pan/zoom */
3869
3897
  interface CameraState {
@@ -4028,6 +4056,9 @@ interface IsometricCanvasProps {
4028
4056
  enableCamera?: boolean;
4029
4057
  /** Extra scale multiplier for unit draw size. 1 = default. */
4030
4058
  unitScale?: number;
4059
+ /** Override for the diamond-top Y offset within the tile sprite (default: 374).
4060
+ * This controls where the flat diamond face sits vertically inside the tile image. */
4061
+ diamondTopY?: number;
4031
4062
  /** Resolve terrain sprite URL from terrain key */
4032
4063
  getTerrainSprite?: (terrain: string) => string | undefined;
4033
4064
  /** Resolve feature sprite URL from feature type key */
@@ -4055,7 +4086,7 @@ interface IsometricCanvasProps {
4055
4086
  effects?: Record<string, string>;
4056
4087
  };
4057
4088
  }
4058
- declare function IsometricCanvas({ className, isLoading, error, entity, tiles: tilesProp, units, features, selectedUnitId, validMoves, attackTargets, hoveredTile, onTileClick, onUnitClick, onTileHover, onTileLeave, tileClickEvent, unitClickEvent, tileHoverEvent, tileLeaveEvent, scale, debug, backgroundImage, showMinimap, enableCamera, unitScale, getTerrainSprite, getFeatureSprite, getUnitSprite, resolveUnitFrame, effectSpriteUrls, onDrawEffects, hasActiveEffects, assetBaseUrl, assetManifest, }: IsometricCanvasProps): JSX.Element;
4089
+ declare function IsometricCanvas({ className, isLoading, error, entity, tiles: tilesProp, units, features, selectedUnitId, validMoves, attackTargets, hoveredTile, onTileClick, onUnitClick, onTileHover, onTileLeave, tileClickEvent, unitClickEvent, tileHoverEvent, tileLeaveEvent, scale, debug, backgroundImage, showMinimap, enableCamera, unitScale, getTerrainSprite, getFeatureSprite, getUnitSprite, resolveUnitFrame, effectSpriteUrls, onDrawEffects, hasActiveEffects, diamondTopY: diamondTopYProp, assetBaseUrl, assetManifest, }: IsometricCanvasProps): JSX.Element;
4059
4090
  declare namespace IsometricCanvas {
4060
4091
  var displayName: string;
4061
4092
  }
@@ -4288,6 +4319,187 @@ type FrameDimsResolver = (unit: IsometricUnit) => SpriteFrameDims | null;
4288
4319
  */
4289
4320
  declare function useSpriteAnimations(getSheetUrls: SheetUrlResolver, getFrameDims: FrameDimsResolver, options?: UseSpriteAnimationsOptions): UseSpriteAnimationsResult;
4290
4321
 
4322
+ /**
4323
+ * PhysicsManager
4324
+ *
4325
+ * Manages 2D physics simulation for entities with Physics2D state.
4326
+ * This implements the tick logic that would normally be compiled from .orb schemas.
4327
+ *
4328
+ * @packageDocumentation
4329
+ */
4330
+ interface Physics2DState {
4331
+ id: string;
4332
+ x: number;
4333
+ y: number;
4334
+ vx: number;
4335
+ vy: number;
4336
+ isGrounded: boolean;
4337
+ gravity: number;
4338
+ friction: number;
4339
+ airResistance: number;
4340
+ maxVelocityY: number;
4341
+ mass?: number;
4342
+ restitution?: number;
4343
+ state: 'Active' | 'Frozen';
4344
+ }
4345
+ interface PhysicsBounds {
4346
+ x: number;
4347
+ y: number;
4348
+ width: number;
4349
+ height: number;
4350
+ }
4351
+ interface PhysicsConfig {
4352
+ gravity?: number;
4353
+ friction?: number;
4354
+ airResistance?: number;
4355
+ maxVelocityY?: number;
4356
+ groundY?: number;
4357
+ }
4358
+ declare class PhysicsManager {
4359
+ private entities;
4360
+ private config;
4361
+ constructor(config?: PhysicsConfig);
4362
+ /**
4363
+ * Register an entity for physics simulation
4364
+ */
4365
+ registerEntity(entityId: string, initialState?: Partial<Physics2DState>): Physics2DState;
4366
+ /**
4367
+ * Unregister an entity from physics simulation
4368
+ */
4369
+ unregisterEntity(entityId: string): void;
4370
+ /**
4371
+ * Get physics state for an entity
4372
+ */
4373
+ getState(entityId: string): Physics2DState | undefined;
4374
+ /**
4375
+ * Get all registered entities
4376
+ */
4377
+ getAllEntities(): Physics2DState[];
4378
+ /**
4379
+ * Apply a force to an entity (impulse)
4380
+ */
4381
+ applyForce(entityId: string, fx: number, fy: number): void;
4382
+ /**
4383
+ * Set velocity directly
4384
+ */
4385
+ setVelocity(entityId: string, vx: number, vy: number): void;
4386
+ /**
4387
+ * Set position directly
4388
+ */
4389
+ setPosition(entityId: string, x: number, y: number): void;
4390
+ /**
4391
+ * Freeze/unfreeze an entity
4392
+ */
4393
+ setFrozen(entityId: string, frozen: boolean): void;
4394
+ /**
4395
+ * Main tick function - call this every frame
4396
+ * Implements the logic from std-physics2d ticks
4397
+ */
4398
+ tick(deltaTime?: number): void;
4399
+ /**
4400
+ * ApplyGravity tick implementation
4401
+ */
4402
+ private applyGravity;
4403
+ /**
4404
+ * ApplyVelocity tick implementation
4405
+ */
4406
+ private applyVelocity;
4407
+ /**
4408
+ * Check and handle ground collision
4409
+ */
4410
+ private checkGroundCollision;
4411
+ /**
4412
+ * Check AABB collision between two entities
4413
+ */
4414
+ checkCollision(entityIdA: string, entityIdB: string, boundsA: PhysicsBounds, boundsB: PhysicsBounds): boolean;
4415
+ /**
4416
+ * Resolve collision with bounce
4417
+ */
4418
+ resolveCollision(entityIdA: string, entityIdB: string): void;
4419
+ /**
4420
+ * Reset all physics state
4421
+ */
4422
+ reset(): void;
4423
+ }
4424
+
4425
+ /**
4426
+ * usePhysics2D Hook
4427
+ *
4428
+ * React hook for integrating 2D physics with the IsometricCanvas.
4429
+ * Provides physics state management and tick synchronization.
4430
+ *
4431
+ * @example
4432
+ * ```tsx
4433
+ * const { registerUnit, getPosition, applyForce, tick } = usePhysics2D({
4434
+ * gravity: 0.5,
4435
+ * groundY: 400
4436
+ * });
4437
+ *
4438
+ * // Register units
4439
+ * useEffect(() => {
4440
+ * units.forEach(unit => {
4441
+ * registerUnit(unit.id, { x: unit.x, y: unit.y, mass: 1 });
4442
+ * });
4443
+ * }, [units]);
4444
+ *
4445
+ * // In animation loop
4446
+ * useEffect(() => {
4447
+ * const animate = (timestamp) => {
4448
+ * tick(16); // Run physics
4449
+ * draw(); // Render
4450
+ * requestAnimationFrame(animate);
4451
+ * };
4452
+ * requestAnimationFrame(animate);
4453
+ * }, []);
4454
+ * ```
4455
+ *
4456
+ * @packageDocumentation
4457
+ */
4458
+
4459
+ interface UsePhysics2DOptions extends PhysicsConfig {
4460
+ /** Enable physics debug visualization */
4461
+ debug?: boolean;
4462
+ /** Callback when collision occurs */
4463
+ onCollision?: (entityIdA: string, entityIdB: string) => void;
4464
+ /** Ground Y position (default: 500) */
4465
+ groundY?: number;
4466
+ }
4467
+ interface UsePhysics2DReturn {
4468
+ /** Register a unit for physics simulation */
4469
+ registerUnit: (unitId: string, options?: Partial<Physics2DState>) => void;
4470
+ /** Unregister a unit from physics */
4471
+ unregisterUnit: (unitId: string) => void;
4472
+ /** Get current physics position for a unit */
4473
+ getPosition: (unitId: string) => {
4474
+ x: number;
4475
+ y: number;
4476
+ } | null;
4477
+ /** Get full physics state for a unit */
4478
+ getState: (unitId: string) => Physics2DState | undefined;
4479
+ /** Apply force to a unit */
4480
+ applyForce: (unitId: string, fx: number, fy: number) => void;
4481
+ /** Set velocity directly */
4482
+ setVelocity: (unitId: string, vx: number, vy: number) => void;
4483
+ /** Set position directly (teleport) */
4484
+ setPosition: (unitId: string, x: number, y: number) => void;
4485
+ /** Run physics tick - call this in your RAF loop */
4486
+ tick: (deltaTime?: number) => void;
4487
+ /** Check collision between two units */
4488
+ checkCollision: (unitIdA: string, unitIdB: string, boundsA: PhysicsBounds, boundsB: PhysicsBounds) => boolean;
4489
+ /** Resolve collision between two units */
4490
+ resolveCollision: (unitIdA: string, unitIdB: string) => void;
4491
+ /** Freeze/unfreeze a unit */
4492
+ setFrozen: (unitId: string, frozen: boolean) => void;
4493
+ /** Get all physics-enabled units */
4494
+ getAllUnits: () => Physics2DState[];
4495
+ /** Reset all physics */
4496
+ reset: () => void;
4497
+ }
4498
+ /**
4499
+ * Hook for managing 2D physics simulation
4500
+ */
4501
+ declare function usePhysics2D(options?: UsePhysics2DOptions): UsePhysics2DReturn;
4502
+
4291
4503
  /**
4292
4504
  * Isometric Coordinate Utilities
4293
4505
  *
@@ -4298,10 +4510,21 @@ declare function useSpriteAnimations(getSheetUrls: SheetUrlResolver, getFrameDim
4298
4510
  */
4299
4511
  /** Base tile width in pixels (before scale) */
4300
4512
  declare const TILE_WIDTH = 256;
4301
- /** Base tile height in pixels (before scale) — full diamond height */
4302
- declare const TILE_HEIGHT = 384;
4303
- /** Floor diamond height — the "walkable surface" portion of the tile */
4304
- declare const FLOOR_HEIGHT = 149;
4513
+ /** Base tile height in pixels (before scale) — full sprite image height (Kenney 256×512) */
4514
+ declare const TILE_HEIGHT = 512;
4515
+ /** Floor diamond height — the "walkable surface" portion of the tile (TILE_WIDTH / 2 for 2:1 ratio) */
4516
+ declare const FLOOR_HEIGHT = 128;
4517
+ /**
4518
+ * Measured Y offset from sprite top to the diamond top vertex within a Kenney
4519
+ * 256×512 tile sprite. The code previously assumed `TILE_HEIGHT - FLOOR_HEIGHT = 384`,
4520
+ * but the actual diamond (dirt_E.png) begins at y = 374 because the 3D side walls
4521
+ * occupy 10 extra pixels above the pure 128 px diamond.
4522
+ *
4523
+ * Use `DIAMOND_TOP_Y * scale` for highlight positioning, unit groundY, feature
4524
+ * placement, and hit-testing — NOT `(TILE_HEIGHT - FLOOR_HEIGHT) * scale`.
4525
+ * `FLOOR_HEIGHT` remains 128 for the isoToScreen spacing formula (2:1 ratio).
4526
+ */
4527
+ declare const DIAMOND_TOP_Y = 374;
4305
4528
  /**
4306
4529
  * Feature type → fallback color mapping (when sprites not loaded).
4307
4530
  */
@@ -4698,6 +4921,459 @@ interface DialogueBoxProps {
4698
4921
  */
4699
4922
  declare function DialogueBox({ dialogue, typewriterSpeed, position, onComplete, onChoice, onAdvance, completeEvent, choiceEvent, advanceEvent, className, }: DialogueBoxProps): JSX.Element;
4700
4923
 
4924
+ /**
4925
+ * BattleBoard
4926
+ *
4927
+ * Core game-logic organism extracted from BattleTemplate.
4928
+ * Handles turn-based phase management, movement animation, valid-move/attack-target
4929
+ * calculation, screen shake/flash, and game-over detection.
4930
+ *
4931
+ * Accepts a single `entity` prop (BattleEntity) containing all board data,
4932
+ * plus optional render-prop slots, callback overrides, and declarative event props
4933
+ * that emit via `useEventBus()`.
4934
+ *
4935
+ * @packageDocumentation
4936
+ */
4937
+
4938
+ /** Battle phases an encounter walks through */
4939
+ type BattlePhase = 'observation' | 'selection' | 'movement' | 'action' | 'enemy_turn' | 'game_over';
4940
+ /** A unit participating in battle */
4941
+ interface BattleUnit {
4942
+ id: string;
4943
+ name: string;
4944
+ unitType?: string;
4945
+ heroId?: string;
4946
+ sprite?: string;
4947
+ team: 'player' | 'enemy';
4948
+ position: {
4949
+ x: number;
4950
+ y: number;
4951
+ };
4952
+ health: number;
4953
+ maxHealth: number;
4954
+ movement: number;
4955
+ attack: number;
4956
+ defense: number;
4957
+ traits?: {
4958
+ name: string;
4959
+ currentState: string;
4960
+ states: string[];
4961
+ cooldown?: number;
4962
+ }[];
4963
+ }
4964
+ /** Minimal tile for map generation */
4965
+ interface BattleTile {
4966
+ x: number;
4967
+ y: number;
4968
+ terrain: string;
4969
+ terrainSprite?: string;
4970
+ }
4971
+ /** Entity prop containing all board data */
4972
+ interface BattleEntity {
4973
+ id: string;
4974
+ initialUnits: BattleUnit[];
4975
+ tiles: IsometricTile[];
4976
+ features?: IsometricFeature[];
4977
+ boardWidth?: number;
4978
+ boardHeight?: number;
4979
+ assetManifest?: {
4980
+ baseUrl: string;
4981
+ terrains?: Record<string, string>;
4982
+ units?: Record<string, string>;
4983
+ features?: Record<string, string>;
4984
+ effects?: Record<string, string>;
4985
+ };
4986
+ backgroundImage?: string;
4987
+ }
4988
+ /** Context exposed to render-prop slots */
4989
+ interface BattleSlotContext {
4990
+ phase: BattlePhase;
4991
+ turn: number;
4992
+ selectedUnit: BattleUnit | null;
4993
+ hoveredUnit: BattleUnit | null;
4994
+ playerUnits: BattleUnit[];
4995
+ enemyUnits: BattleUnit[];
4996
+ gameResult: 'victory' | 'defeat' | null;
4997
+ onEndTurn: () => void;
4998
+ onCancel: () => void;
4999
+ onReset: () => void;
5000
+ attackTargets: Array<{
5001
+ x: number;
5002
+ y: number;
5003
+ }>;
5004
+ /** Resolve screen position of a tile for overlays */
5005
+ tileToScreen: (x: number, y: number) => {
5006
+ x: number;
5007
+ y: number;
5008
+ };
5009
+ }
5010
+ interface BattleBoardProps {
5011
+ /** Entity containing all board data */
5012
+ entity: BattleEntity;
5013
+ /** Canvas render scale */
5014
+ scale?: number;
5015
+ /** Unit draw-size multiplier */
5016
+ unitScale?: number;
5017
+ /** Header area -- receives battle context */
5018
+ header?: (ctx: BattleSlotContext) => React__default.ReactNode;
5019
+ /** Sidebar content (combat log, unit roster, etc.) */
5020
+ sidebar?: (ctx: BattleSlotContext) => React__default.ReactNode;
5021
+ /** Floating action buttons */
5022
+ actions?: (ctx: BattleSlotContext) => React__default.ReactNode;
5023
+ /** Floating overlays above the canvas (damage popups, tooltips) */
5024
+ overlay?: (ctx: BattleSlotContext) => React__default.ReactNode;
5025
+ /** Game-over screen overlay */
5026
+ gameOverOverlay?: (ctx: BattleSlotContext) => React__default.ReactNode;
5027
+ /** Called when a unit attacks another */
5028
+ onAttack?: (attacker: BattleUnit, target: BattleUnit, damage: number) => void;
5029
+ /** Called when battle ends */
5030
+ onGameEnd?: (result: 'victory' | 'defeat') => void;
5031
+ /** Called after a unit moves */
5032
+ onUnitMove?: (unit: BattleUnit, to: {
5033
+ x: number;
5034
+ y: number;
5035
+ }) => void;
5036
+ /** Custom combat damage calculator */
5037
+ calculateDamage?: (attacker: BattleUnit, target: BattleUnit) => number;
5038
+ onDrawEffects?: (ctx: CanvasRenderingContext2D, timestamp: number) => void;
5039
+ hasActiveEffects?: boolean;
5040
+ effectSpriteUrls?: string[];
5041
+ resolveUnitFrame?: (unitId: string) => ResolvedFrame | null;
5042
+ /** Emits UI:{tileClickEvent} with { x, y } on tile click */
5043
+ tileClickEvent?: string;
5044
+ /** Emits UI:{unitClickEvent} with { unitId } on unit click */
5045
+ unitClickEvent?: string;
5046
+ /** Emits UI:{endTurnEvent} with {} on end turn */
5047
+ endTurnEvent?: string;
5048
+ /** Emits UI:{cancelEvent} with {} on cancel */
5049
+ cancelEvent?: string;
5050
+ /** Emits UI:{gameEndEvent} with { result } on game end */
5051
+ gameEndEvent?: string;
5052
+ /** Emits UI:{playAgainEvent} with {} on play again / reset */
5053
+ playAgainEvent?: string;
5054
+ /** Emits UI:{attackEvent} with { attackerId, targetId, damage } on attack */
5055
+ attackEvent?: string;
5056
+ className?: string;
5057
+ }
5058
+ declare function BattleBoard({ entity, scale, unitScale, header, sidebar, actions, overlay, gameOverOverlay, onAttack, onGameEnd, onUnitMove, calculateDamage, onDrawEffects, hasActiveEffects, effectSpriteUrls, resolveUnitFrame, tileClickEvent, unitClickEvent, endTurnEvent, cancelEvent, gameEndEvent, playAgainEvent, attackEvent, className, }: BattleBoardProps): JSX.Element;
5059
+ declare namespace BattleBoard {
5060
+ var displayName: string;
5061
+ }
5062
+
5063
+ /**
5064
+ * WorldMapBoard
5065
+ *
5066
+ * Organism that contains ALL game logic for the strategic world-map view.
5067
+ * Renders an isometric hex/iso map with hero selection, movement animation,
5068
+ * and encounter callbacks. Game-specific panels (hero detail, hero lists,
5069
+ * resource bars) are injected via render-prop slots.
5070
+ *
5071
+ * This component is the logic-heavy core; WorldMapTemplate is a thin layout
5072
+ * wrapper that delegates to WorldMapBoard.
5073
+ *
5074
+ * @packageDocumentation
5075
+ */
5076
+
5077
+ /** A hero on the world map */
5078
+ interface MapHero {
5079
+ id: string;
5080
+ name: string;
5081
+ owner: 'player' | 'enemy' | string;
5082
+ position: {
5083
+ x: number;
5084
+ y: number;
5085
+ };
5086
+ movement: number;
5087
+ sprite?: string;
5088
+ level?: number;
5089
+ }
5090
+ /** A hex on the map */
5091
+ interface MapHex {
5092
+ x: number;
5093
+ y: number;
5094
+ terrain: string;
5095
+ terrainSprite?: string;
5096
+ feature?: string;
5097
+ featureData?: Record<string, unknown>;
5098
+ passable?: boolean;
5099
+ }
5100
+ /** Context exposed to render-prop slots */
5101
+ interface WorldMapSlotContext {
5102
+ /** Currently hovered tile */
5103
+ hoveredTile: {
5104
+ x: number;
5105
+ y: number;
5106
+ } | null;
5107
+ /** Hex at the hovered tile */
5108
+ hoveredHex: MapHex | null;
5109
+ /** Hero at the hovered tile */
5110
+ hoveredHero: MapHero | null;
5111
+ /** Currently selected hero */
5112
+ selectedHero: MapHero | null;
5113
+ /** Valid move tiles for selected hero */
5114
+ validMoves: Array<{
5115
+ x: number;
5116
+ y: number;
5117
+ }>;
5118
+ /** Selects a hero */
5119
+ selectHero: (id: string) => void;
5120
+ /** Resolve screen position of a tile for overlays */
5121
+ tileToScreen: (x: number, y: number) => {
5122
+ x: number;
5123
+ y: number;
5124
+ };
5125
+ /** Canvas scale */
5126
+ scale: number;
5127
+ }
5128
+ /** Entity shape for the WorldMapBoard */
5129
+ interface WorldMapEntity {
5130
+ id: string;
5131
+ hexes: MapHex[];
5132
+ heroes: MapHero[];
5133
+ features?: IsometricFeature[];
5134
+ selectedHeroId?: string | null;
5135
+ assetManifest?: {
5136
+ baseUrl: string;
5137
+ terrains?: Record<string, string>;
5138
+ units?: Record<string, string>;
5139
+ features?: Record<string, string>;
5140
+ };
5141
+ backgroundImage?: string;
5142
+ }
5143
+ interface WorldMapBoardProps {
5144
+ /** World map entity data */
5145
+ entity: WorldMapEntity;
5146
+ /** Canvas render scale */
5147
+ scale?: number;
5148
+ /** Unit draw-size multiplier */
5149
+ unitScale?: number;
5150
+ /** Allow selecting / moving ALL heroes (including enemy). For testing. */
5151
+ allowMoveAllHeroes?: boolean;
5152
+ /** Custom movement range validator */
5153
+ isInRange?: (from: {
5154
+ x: number;
5155
+ y: number;
5156
+ }, to: {
5157
+ x: number;
5158
+ y: number;
5159
+ }, range: number) => boolean;
5160
+ /** Emits UI:{heroSelectEvent} with { heroId } */
5161
+ heroSelectEvent?: string;
5162
+ /** Emits UI:{heroMoveEvent} with { heroId, toX, toY } */
5163
+ heroMoveEvent?: string;
5164
+ /** Emits UI:{battleEncounterEvent} with { attackerId, defenderId } */
5165
+ battleEncounterEvent?: string;
5166
+ /** Emits UI:{featureEnterEvent} with { heroId, feature, hex } */
5167
+ featureEnterEvent?: string;
5168
+ /** Emits UI:{tileClickEvent} with { x, y } */
5169
+ tileClickEvent?: string;
5170
+ /** Header / top bar */
5171
+ header?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
5172
+ /** Side panel (hero detail, hero lists, etc.) */
5173
+ sidePanel?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
5174
+ /** Canvas overlay (tooltips, popups) */
5175
+ overlay?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
5176
+ /** Footer */
5177
+ footer?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
5178
+ onHeroSelect?: (heroId: string) => void;
5179
+ onHeroMove?: (heroId: string, toX: number, toY: number) => void;
5180
+ /** Called when hero clicks an enemy hero tile */
5181
+ onBattleEncounter?: (attackerId: string, defenderId: string) => void;
5182
+ /** Called when hero enters a feature hex (castle, resource, etc.) */
5183
+ onFeatureEnter?: (heroId: string, hex: MapHex) => void;
5184
+ effectSpriteUrls?: string[];
5185
+ resolveUnitFrame?: (unitId: string) => ResolvedFrame | null;
5186
+ className?: string;
5187
+ }
5188
+ declare function WorldMapBoard({ entity, scale, unitScale, allowMoveAllHeroes, isInRange, heroSelectEvent, heroMoveEvent, battleEncounterEvent, featureEnterEvent, tileClickEvent, header, sidePanel, overlay, footer, onHeroSelect, onHeroMove, onBattleEncounter, onFeatureEnter, effectSpriteUrls, resolveUnitFrame, className, }: WorldMapBoardProps): JSX.Element;
5189
+ declare namespace WorldMapBoard {
5190
+ var displayName: string;
5191
+ }
5192
+
5193
+ /**
5194
+ * CastleBoard
5195
+ *
5196
+ * Self-contained castle / base-management game board organism. Encapsulates all
5197
+ * isometric canvas rendering, hover/selection state, and slot-based layout.
5198
+ * Designed to be consumed by CastleTemplate (thin wrapper) or embedded directly
5199
+ * in any page that needs an isometric castle view.
5200
+ *
5201
+ * Accepts an `entity` prop conforming to `CastleEntity` and optional declarative
5202
+ * event props (`featureClickEvent`, `unitClickEvent`, `tileClickEvent`) that
5203
+ * emit through the Orbital event bus.
5204
+ *
5205
+ * @packageDocumentation
5206
+ */
5207
+
5208
+ /** Entity shape consumed by CastleBoard */
5209
+ interface CastleEntity {
5210
+ id: string;
5211
+ tiles: IsometricTile[];
5212
+ features?: IsometricFeature[];
5213
+ units?: IsometricUnit[];
5214
+ assetManifest?: {
5215
+ baseUrl: string;
5216
+ terrains?: Record<string, string>;
5217
+ units?: Record<string, string>;
5218
+ features?: Record<string, string>;
5219
+ };
5220
+ backgroundImage?: string;
5221
+ }
5222
+ /** Context exposed to render-prop slots */
5223
+ interface CastleSlotContext {
5224
+ /** Currently hovered tile coordinates (null when not hovering) */
5225
+ hoveredTile: {
5226
+ x: number;
5227
+ y: number;
5228
+ } | null;
5229
+ /** Feature that sits on the hovered tile, if any */
5230
+ hoveredFeature: IsometricFeature | null;
5231
+ /** Unit that sits on the hovered tile, if any */
5232
+ hoveredUnit: IsometricUnit | null;
5233
+ /** The clicked feature (e.g. building) for detail view */
5234
+ selectedFeature: IsometricFeature | null;
5235
+ /** Clear selected feature */
5236
+ clearSelection: () => void;
5237
+ /** Resolve screen position for overlay positioning */
5238
+ tileToScreen: (x: number, y: number) => {
5239
+ x: number;
5240
+ y: number;
5241
+ };
5242
+ /** Canvas scale */
5243
+ scale: number;
5244
+ }
5245
+ interface CastleBoardProps {
5246
+ /** Castle entity data */
5247
+ entity: CastleEntity;
5248
+ /** Canvas render scale */
5249
+ scale?: number;
5250
+ /** Top bar / header */
5251
+ header?: (ctx: CastleSlotContext) => React__default.ReactNode;
5252
+ /** Side panel content (buildings list, recruit tab, garrison tab) */
5253
+ sidePanel?: (ctx: CastleSlotContext) => React__default.ReactNode;
5254
+ /** Canvas overlay (hover tooltips, etc.) */
5255
+ overlay?: (ctx: CastleSlotContext) => React__default.ReactNode;
5256
+ /** Bottom bar (income summary, etc.) */
5257
+ footer?: (ctx: CastleSlotContext) => React__default.ReactNode;
5258
+ /** Called when a feature (building) is clicked */
5259
+ onFeatureClick?: (feature: IsometricFeature) => void;
5260
+ /** Called when a unit is clicked */
5261
+ onUnitClick?: (unit: IsometricUnit) => void;
5262
+ /** Called when any tile is clicked */
5263
+ onTileClick?: (x: number, y: number) => void;
5264
+ /** Event name to emit via event bus when a feature is clicked (emits UI:{featureClickEvent}) */
5265
+ featureClickEvent?: string;
5266
+ /** Event name to emit via event bus when a unit is clicked (emits UI:{unitClickEvent}) */
5267
+ unitClickEvent?: string;
5268
+ /** Event name to emit via event bus when a tile is clicked (emits UI:{tileClickEvent}) */
5269
+ tileClickEvent?: string;
5270
+ className?: string;
5271
+ }
5272
+ declare function CastleBoard({ entity, scale, header, sidePanel, overlay, footer, onFeatureClick, onUnitClick, onTileClick, featureClickEvent, unitClickEvent, tileClickEvent, className, }: CastleBoardProps): JSX.Element;
5273
+ declare namespace CastleBoard {
5274
+ var displayName: string;
5275
+ }
5276
+
5277
+ type EditorMode = 'select' | 'paint' | 'unit' | 'feature' | 'erase';
5278
+ declare const TERRAIN_COLORS: Record<string, string>;
5279
+ declare const FEATURE_TYPES: readonly ["goldMine", "resonanceCrystal", "traitCache", "salvageYard", "portal", "battleMarker", "treasure", "castle"];
5280
+ interface CollapsibleSectionProps {
5281
+ title: string;
5282
+ expanded: boolean;
5283
+ onToggle: () => void;
5284
+ children: React__default.ReactNode;
5285
+ className?: string;
5286
+ }
5287
+ declare function CollapsibleSection({ title, expanded, onToggle, children, className }: CollapsibleSectionProps): react_jsx_runtime.JSX.Element;
5288
+ declare namespace CollapsibleSection {
5289
+ var displayName: string;
5290
+ }
5291
+ interface EditorSliderProps {
5292
+ label: string;
5293
+ value: number;
5294
+ min: number;
5295
+ max: number;
5296
+ step?: number;
5297
+ onChange: (value: number) => void;
5298
+ className?: string;
5299
+ }
5300
+ declare function EditorSlider({ label, value, min, max, step, onChange, className }: EditorSliderProps): react_jsx_runtime.JSX.Element;
5301
+ declare namespace EditorSlider {
5302
+ var displayName: string;
5303
+ }
5304
+ interface EditorSelectProps {
5305
+ label: string;
5306
+ value: string;
5307
+ options: Array<{
5308
+ value: string;
5309
+ label: string;
5310
+ }>;
5311
+ onChange: (value: string) => void;
5312
+ className?: string;
5313
+ }
5314
+ declare function EditorSelect({ label, value, options, onChange, className }: EditorSelectProps): react_jsx_runtime.JSX.Element;
5315
+ declare namespace EditorSelect {
5316
+ var displayName: string;
5317
+ }
5318
+ interface EditorCheckboxProps {
5319
+ label: string;
5320
+ checked: boolean;
5321
+ onChange: (checked: boolean) => void;
5322
+ className?: string;
5323
+ }
5324
+ declare function EditorCheckbox({ label, checked, onChange, className }: EditorCheckboxProps): react_jsx_runtime.JSX.Element;
5325
+ declare namespace EditorCheckbox {
5326
+ var displayName: string;
5327
+ }
5328
+ interface EditorTextInputProps {
5329
+ label: string;
5330
+ value: string;
5331
+ onChange: (value: string) => void;
5332
+ placeholder?: string;
5333
+ className?: string;
5334
+ }
5335
+ declare function EditorTextInput({ label, value, onChange, placeholder, className }: EditorTextInputProps): react_jsx_runtime.JSX.Element;
5336
+ declare namespace EditorTextInput {
5337
+ var displayName: string;
5338
+ }
5339
+ interface StatusBarProps {
5340
+ hoveredTile: {
5341
+ x: number;
5342
+ y: number;
5343
+ } | null;
5344
+ mode: EditorMode;
5345
+ gridSize?: {
5346
+ width: number;
5347
+ height: number;
5348
+ };
5349
+ unitCount?: number;
5350
+ featureCount?: number;
5351
+ className?: string;
5352
+ }
5353
+ declare function StatusBar({ hoveredTile, mode, gridSize, unitCount, featureCount, className }: StatusBarProps): react_jsx_runtime.JSX.Element;
5354
+ declare namespace StatusBar {
5355
+ var displayName: string;
5356
+ }
5357
+ interface TerrainPaletteProps {
5358
+ terrains: string[];
5359
+ selectedTerrain: string;
5360
+ onSelect: (terrain: string) => void;
5361
+ className?: string;
5362
+ }
5363
+ declare function TerrainPalette({ terrains, selectedTerrain, onSelect, className }: TerrainPaletteProps): react_jsx_runtime.JSX.Element;
5364
+ declare namespace TerrainPalette {
5365
+ var displayName: string;
5366
+ }
5367
+ interface EditorToolbarProps {
5368
+ mode: EditorMode;
5369
+ onModeChange: (mode: EditorMode) => void;
5370
+ className?: string;
5371
+ }
5372
+ declare function EditorToolbar({ mode, onModeChange, className }: EditorToolbarProps): react_jsx_runtime.JSX.Element;
5373
+ declare namespace EditorToolbar {
5374
+ var displayName: string;
5375
+ }
5376
+
4701
5377
  /**
4702
5378
  * UISlotRenderer Component
4703
5379
  *
@@ -5348,6 +6024,24 @@ interface CodeViewerProps {
5348
6024
  }
5349
6025
  declare const CodeViewer: React__default.FC<CodeViewerProps>;
5350
6026
 
6027
+ /**
6028
+ * Base template types for Almadar UI.
6029
+ *
6030
+ * All templates MUST extend `TemplateProps<E>` to enforce entity-only data flow
6031
+ * and JSON round-trip compatibility with the flattener pipeline.
6032
+ *
6033
+ * @see docs/Almadar_Templates.md
6034
+ */
6035
+ /** Base props for all templates — enforces entity-only data flow. */
6036
+ interface TemplateProps<E extends {
6037
+ id: string;
6038
+ }> {
6039
+ /** Entity data — the sole source of runtime state */
6040
+ entity: E;
6041
+ /** External styling override */
6042
+ className?: string;
6043
+ }
6044
+
5351
6045
  interface NavItem {
5352
6046
  label: string;
5353
6047
  href: string;
@@ -5777,124 +6471,21 @@ declare const GameShell: React__default.FC<GameShellProps>;
5777
6471
  /**
5778
6472
  * BattleTemplate
5779
6473
  *
5780
- * Generalized tactical battle template composing IsometricCanvas from almadar-ui.
5781
- * Provides turn-based phase management, movement animation, valid-move/attack-target
5782
- * calculation, screen shake/flash, and a game-over overlay.
6474
+ * Thin declarative wrapper around BattleBoard organism.
6475
+ * All game logic (turn phases, movement animation, combat, etc.) lives in BattleBoard.
5783
6476
  *
5784
- * Game-specific UI (combat log, trait viewer, damage popups, etc.) is injected via
5785
- * render-prop slots so this template remains project-agnostic.
6477
+ * Compliant with Almadar_Templates.md: no hooks, no callbacks, entity-only data flow.
5786
6478
  *
5787
6479
  * @packageDocumentation
5788
6480
  */
5789
6481
 
5790
- /** Battle phases an encounter walks through */
5791
- type BattlePhase = 'observation' | 'selection' | 'movement' | 'action' | 'enemy_turn' | 'game_over';
5792
- /** A unit participating in battle */
5793
- interface BattleUnit {
5794
- id: string;
5795
- name: string;
5796
- unitType?: string;
5797
- heroId?: string;
5798
- sprite?: string;
5799
- team: 'player' | 'enemy';
5800
- position: {
5801
- x: number;
5802
- y: number;
5803
- };
5804
- health: number;
5805
- maxHealth: number;
5806
- movement: number;
5807
- attack: number;
5808
- defense: number;
5809
- traits?: {
5810
- name: string;
5811
- currentState: string;
5812
- states: string[];
5813
- cooldown?: number;
5814
- }[];
5815
- }
5816
- /** Minimal tile for map generation */
5817
- interface BattleTile {
5818
- x: number;
5819
- y: number;
5820
- terrain: string;
5821
- terrainSprite?: string;
5822
- }
5823
- /** Context exposed to render-prop slots */
5824
- interface BattleSlotContext {
5825
- phase: BattlePhase;
5826
- turn: number;
5827
- selectedUnit: BattleUnit | null;
5828
- hoveredUnit: BattleUnit | null;
5829
- playerUnits: BattleUnit[];
5830
- enemyUnits: BattleUnit[];
5831
- gameResult: 'victory' | 'defeat' | null;
5832
- onEndTurn: () => void;
5833
- onCancel: () => void;
5834
- onReset: () => void;
5835
- attackTargets: Array<{
5836
- x: number;
5837
- y: number;
5838
- }>;
5839
- /** Resolve screen position of a tile for overlays */
5840
- tileToScreen: (x: number, y: number) => {
5841
- x: number;
5842
- y: number;
5843
- };
5844
- }
5845
- interface BattleTemplateProps {
5846
- /** Initial units for the battle */
5847
- initialUnits: BattleUnit[];
5848
- /** Isometric tiles (pre-resolved with terrainSprite) */
5849
- tiles: IsometricTile[];
6482
+ interface BattleTemplateProps extends TemplateProps<BattleEntity> {
5850
6483
  /** Canvas render scale */
5851
6484
  scale?: number;
5852
- /** Board width for bounds checking */
5853
- boardWidth?: number;
5854
- /** Board height for bounds checking */
5855
- boardHeight?: number;
5856
- /** Asset manifest for IsometricCanvas */
5857
- assetManifest?: {
5858
- baseUrl: string;
5859
- terrains?: Record<string, string>;
5860
- units?: Record<string, string>;
5861
- features?: Record<string, string>;
5862
- effects?: Record<string, string>;
5863
- };
5864
- /** Background image URL for canvas */
5865
- backgroundImage?: string;
5866
6485
  /** Unit draw-size multiplier */
5867
6486
  unitScale?: number;
5868
- /** Header area — receives battle context */
5869
- header?: (ctx: BattleSlotContext) => React__default.ReactNode;
5870
- /** Sidebar content (combat log, unit roster, etc.) */
5871
- sidebar?: (ctx: BattleSlotContext) => React__default.ReactNode;
5872
- /** Floating action buttons */
5873
- actions?: (ctx: BattleSlotContext) => React__default.ReactNode;
5874
- /** Floating overlays above the canvas (damage popups, tooltips) */
5875
- overlay?: (ctx: BattleSlotContext) => React__default.ReactNode;
5876
- /** Game-over screen overlay */
5877
- gameOverOverlay?: (ctx: BattleSlotContext) => React__default.ReactNode;
5878
- /** Static features (obstacles, decorations) rendered on the grid */
5879
- features?: IsometricFeature[];
5880
- /** Called when a unit attacks another */
5881
- onAttack?: (attacker: BattleUnit, target: BattleUnit, damage: number) => void;
5882
- /** Called when battle ends */
5883
- onGameEnd?: (result: 'victory' | 'defeat') => void;
5884
- /** Called after a unit moves */
5885
- onUnitMove?: (unit: BattleUnit, to: {
5886
- x: number;
5887
- y: number;
5888
- }) => void;
5889
- /** Custom combat damage calculator */
5890
- calculateDamage?: (attacker: BattleUnit, target: BattleUnit) => number;
5891
- onDrawEffects?: (ctx: CanvasRenderingContext2D, timestamp: number) => void;
5892
- hasActiveEffects?: boolean;
5893
- effectSpriteUrls?: string[];
5894
- resolveUnitFrame?: (unitId: string) => ResolvedFrame | null;
5895
- className?: string;
5896
6487
  }
5897
- declare function BattleTemplate({ initialUnits, tiles, scale, boardWidth, boardHeight, assetManifest, backgroundImage, unitScale, header, sidebar, actions, overlay, gameOverOverlay, features, onAttack, onGameEnd, onUnitMove, calculateDamage, onDrawEffects, hasActiveEffects, effectSpriteUrls, resolveUnitFrame, className, }: BattleTemplateProps): JSX.Element;
6488
+ declare function BattleTemplate({ entity, scale, unitScale, className, }: BattleTemplateProps): JSX.Element;
5898
6489
  declare namespace BattleTemplate {
5899
6490
  var displayName: string;
5900
6491
  }
@@ -5902,71 +6493,19 @@ declare namespace BattleTemplate {
5902
6493
  /**
5903
6494
  * CastleTemplate
5904
6495
  *
5905
- * Generalized castle / base-management template composing IsometricCanvas from
5906
- * almadar-ui. Renders an isometric courtyard/base view and exposes a side-panel
5907
- * area via slots for game-specific UI (building details, recruitment, garrison).
6496
+ * Thin declarative wrapper around CastleBoard organism.
6497
+ * All game logic (hover state, feature selection, etc.) lives in CastleBoard.
6498
+ *
6499
+ * Compliant with Almadar_Templates.md: no hooks, no callbacks, entity-only data flow.
5908
6500
  *
5909
6501
  * @packageDocumentation
5910
6502
  */
5911
6503
 
5912
- /** Context exposed to render-prop slots */
5913
- interface CastleSlotContext {
5914
- /** Currently hovered tile coordinates (null when not hovering) */
5915
- hoveredTile: {
5916
- x: number;
5917
- y: number;
5918
- } | null;
5919
- /** Feature that sits on the hovered tile, if any */
5920
- hoveredFeature: IsometricFeature | null;
5921
- /** Unit that sits on the hovered tile, if any */
5922
- hoveredUnit: IsometricUnit | null;
5923
- /** The clicked feature (e.g. building) for detail view */
5924
- selectedFeature: IsometricFeature | null;
5925
- /** Clear selected feature */
5926
- clearSelection: () => void;
5927
- /** Resolve screen position for overlay positioning */
5928
- tileToScreen: (x: number, y: number) => {
5929
- x: number;
5930
- y: number;
5931
- };
5932
- /** Canvas scale */
5933
- scale: number;
5934
- }
5935
- interface CastleTemplateProps {
5936
- /** Isometric tiles (pre-resolved with terrainSprite) */
5937
- tiles: IsometricTile[];
5938
- /** Building features rendered on the grid */
5939
- features?: IsometricFeature[];
5940
- /** Garrison / stationed units on the grid */
5941
- units?: IsometricUnit[];
6504
+ interface CastleTemplateProps extends TemplateProps<CastleEntity> {
5942
6505
  /** Canvas render scale */
5943
6506
  scale?: number;
5944
- /** Asset manifest for IsometricCanvas */
5945
- assetManifest?: {
5946
- baseUrl: string;
5947
- terrains?: Record<string, string>;
5948
- units?: Record<string, string>;
5949
- features?: Record<string, string>;
5950
- };
5951
- /** Background image URL */
5952
- backgroundImage?: string;
5953
- /** Top bar / header */
5954
- header?: (ctx: CastleSlotContext) => React__default.ReactNode;
5955
- /** Side panel content (buildings list, recruit tab, garrison tab) */
5956
- sidePanel?: (ctx: CastleSlotContext) => React__default.ReactNode;
5957
- /** Canvas overlay (hover tooltips, etc.) */
5958
- overlay?: (ctx: CastleSlotContext) => React__default.ReactNode;
5959
- /** Bottom bar (income summary, etc.) */
5960
- footer?: (ctx: CastleSlotContext) => React__default.ReactNode;
5961
- /** Called when a feature (building) is clicked */
5962
- onFeatureClick?: (feature: IsometricFeature) => void;
5963
- /** Called when a unit is clicked */
5964
- onUnitClick?: (unit: IsometricUnit) => void;
5965
- /** Called when any tile is clicked */
5966
- onTileClick?: (x: number, y: number) => void;
5967
- className?: string;
5968
6507
  }
5969
- declare function CastleTemplate({ tiles, features, units, scale, assetManifest, backgroundImage, header, sidePanel, overlay, footer, onFeatureClick, onUnitClick, onTileClick, className, }: CastleTemplateProps): JSX.Element;
6508
+ declare function CastleTemplate({ entity, scale, className, }: CastleTemplateProps): JSX.Element;
5970
6509
  declare namespace CastleTemplate {
5971
6510
  var displayName: string;
5972
6511
  }
@@ -5974,118 +6513,25 @@ declare namespace CastleTemplate {
5974
6513
  /**
5975
6514
  * WorldMapTemplate
5976
6515
  *
5977
- * Generalized strategic world-map template composing IsometricCanvas from
5978
- * almadar-ui. Renders an isometric hex/iso map with hero selection, movement
5979
- * animation, and encounter callbacks. Game-specific panels (hero detail, hero
5980
- * lists, resource bars) are injected via render-prop slots.
6516
+ * Thin declarative wrapper around WorldMapBoard organism.
6517
+ * All game logic (hero movement, encounters, hex conversion, etc.) lives in WorldMapBoard.
6518
+ *
6519
+ * Compliant with Almadar_Templates.md: no hooks, no callbacks, entity-only data flow.
5981
6520
  *
5982
6521
  * @packageDocumentation
5983
6522
  */
5984
6523
 
5985
- /** A hero on the world map */
5986
- interface MapHero {
5987
- id: string;
5988
- name: string;
5989
- owner: 'player' | 'enemy' | string;
5990
- position: {
5991
- x: number;
5992
- y: number;
5993
- };
5994
- movement: number;
5995
- sprite?: string;
5996
- level?: number;
5997
- }
5998
- /** A feature hex on the map */
5999
- interface MapHex {
6000
- x: number;
6001
- y: number;
6002
- terrain: string;
6003
- terrainSprite?: string;
6004
- feature?: string;
6005
- featureData?: Record<string, unknown>;
6006
- passable?: boolean;
6007
- }
6008
- /** Context exposed to render-prop slots */
6009
- interface WorldMapSlotContext {
6010
- /** Currently hovered tile */
6011
- hoveredTile: {
6012
- x: number;
6013
- y: number;
6014
- } | null;
6015
- /** Hex at the hovered tile */
6016
- hoveredHex: MapHex | null;
6017
- /** Hero at the hovered tile */
6018
- hoveredHero: MapHero | null;
6019
- /** Currently selected hero */
6020
- selectedHero: MapHero | null;
6021
- /** Valid move tiles for selected hero */
6022
- validMoves: Array<{
6023
- x: number;
6024
- y: number;
6025
- }>;
6026
- /** Selects a hero */
6027
- selectHero: (id: string) => void;
6028
- /** Resolve screen position of a tile for overlays */
6029
- tileToScreen: (x: number, y: number) => {
6030
- x: number;
6031
- y: number;
6032
- };
6033
- /** Canvas scale */
6034
- scale: number;
6035
- }
6036
- interface WorldMapTemplateProps {
6037
- /** All map hexes (with pre-resolved terrain sprites) */
6038
- hexes: MapHex[];
6039
- /** Heroes on the map */
6040
- heroes: MapHero[];
6041
- /** Features rendered on tiles */
6042
- features?: IsometricFeature[];
6043
- /** Currently selected hero ID */
6044
- selectedHeroId?: string | null;
6524
+ interface WorldMapTemplateProps extends TemplateProps<WorldMapEntity> {
6045
6525
  /** Canvas render scale */
6046
6526
  scale?: number;
6047
6527
  /** Unit draw-size multiplier */
6048
6528
  unitScale?: number;
6049
- /** Asset manifest for IsometricCanvas */
6050
- assetManifest?: {
6051
- baseUrl: string;
6052
- terrains?: Record<string, string>;
6053
- units?: Record<string, string>;
6054
- features?: Record<string, string>;
6055
- };
6056
- /** Background image URL */
6057
- backgroundImage?: string;
6058
6529
  /** Allow selecting / moving ALL heroes (including enemy). For testing. */
6059
6530
  allowMoveAllHeroes?: boolean;
6060
- /** Custom movement range validator */
6061
- isInRange?: (from: {
6062
- x: number;
6063
- y: number;
6064
- }, to: {
6065
- x: number;
6066
- y: number;
6067
- }, range: number) => boolean;
6068
- /** Header / top bar */
6069
- header?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
6070
- /** Side panel (hero detail, hero lists, etc.) */
6071
- sidePanel?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
6072
- /** Canvas overlay (tooltips, popups) */
6073
- overlay?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
6074
- /** Footer */
6075
- footer?: (ctx: WorldMapSlotContext) => React__default.ReactNode;
6076
- onHeroSelect?: (heroId: string) => void;
6077
- onHeroMove?: (heroId: string, toX: number, toY: number) => void;
6078
- /** Called when hero clicks an enemy hero tile */
6079
- onBattleEncounter?: (attackerId: string, defenderId: string) => void;
6080
- /** Called when hero enters a feature hex (castle, resource, etc.) */
6081
- onFeatureEnter?: (heroId: string, hex: MapHex) => void;
6082
- effectSpriteUrls?: string[];
6083
- resolveUnitFrame?: (unitId: string) => ResolvedFrame | null;
6084
- className?: string;
6085
6531
  }
6086
- declare function WorldMapTemplate({ hexes, heroes, features, selectedHeroId, scale, unitScale, assetManifest, backgroundImage, allowMoveAllHeroes, isInRange, header, sidePanel, overlay, footer, onHeroSelect, onHeroMove, onBattleEncounter, onFeatureEnter, effectSpriteUrls, resolveUnitFrame, className, }: WorldMapTemplateProps): JSX.Element;
6532
+ declare function WorldMapTemplate({ entity, scale, unitScale, allowMoveAllHeroes, className, }: WorldMapTemplateProps): JSX.Element;
6087
6533
  declare namespace WorldMapTemplate {
6088
6534
  var displayName: string;
6089
6535
  }
6090
6536
 
6091
- export { Accordion, type AccordionItem, type AccordionProps, Card as ActionCard, type CardProps as ActionCardProps, Alert, type AlertProps, type AlertVariant, type AnimationDef, type AnimationName, AuthLayout, type AuthLayoutProps, Avatar, type AvatarProps, type AvatarSize, type AvatarStatus, Badge, type BadgeProps, type BadgeVariant, type BattlePhase, type BattleSlotContext, BattleTemplate, type BattleTemplateProps, type BattleTile, type BattleUnit, Box, type BoxBg, type BoxMargin, type BoxPadding, type BoxProps, type BoxRounded, type BoxShadow, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type CameraState, CanvasEffect, type CanvasEffectProps, Card$1 as Card, type CardAction, CardBody, CardContent, CardFooter, CardGrid, type CardGridGap, type CardGridProps, CardHeader, type CardProps$1 as CardProps, CardTitle, type CastleSlotContext, CastleTemplate, type CastleTemplateProps, Center, type CenterProps, Chart, type ChartDataPoint, type ChartProps, type ChartSeries, type ChartType, Checkbox, type CheckboxProps, CodeViewer, type CodeViewerMode, type CodeViewerProps, type Column, type ColumnConfig, type CombatActionType, type ConditionalContext, ConditionalWrapper, type ConditionalWrapperProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmDialogVariant, Container, type ContainerProps, ControlButton, type ControlButtonProps, type CounterSize, CounterTemplate, type CounterTemplateProps, type CounterVariant, type CrudItem, CrudTemplate, type CrudTemplateProps, type CrudVariant, DashboardGrid, type DashboardGridCell, type DashboardGridProps, DashboardLayout, type DashboardLayoutProps, DataTable, type DataTableProps, type DetailField, DetailPanel, type DetailPanelProps, type DetailSection, DialogueBox, type DialogueBoxProps, type DialogueChoice, type DialogueNode, type DiffLine, Divider, type DividerOrientation, type DividerProps, type DocumentType, DocumentViewer, type DocumentViewerProps, Drawer, type DrawerPosition, type DrawerProps, type DrawerSize, DrawerSlot, type DrawerSlotProps, EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, EventBusContextType, FEATURE_COLORS, FLOOR_HEIGHT, type FacingDirection, type FieldConfig, type FilterDefinition, FilterGroup, type FilterGroupProps, type FilterValue, Flex, type FlexProps, FloatingActionButton, type FloatingActionButtonProps, Form, FormActions, type FormActionsProps, FormField, type FormFieldConfig, type FormFieldProps, FormLayout, type FormLayoutProps, type FormProps, FormSection$1 as FormSection, FormSectionHeader, type FormSectionHeaderProps, type FormSectionProps, FormTemplate, type FormTemplateProps, type FormVariant, type FrameDimsResolver, GameHud, type GameHudElement, type GameHudProps, type GameHudStat, GameMenu, type GameMenuProps, type GameOverAction, GameOverScreen, type GameOverScreenProps, type GameOverStat, GameShell, type GameShellProps, GameTemplate, type GameTemplateProps, GenericAppTemplate, type GenericAppTemplateProps, GraphCanvas, type GraphCanvasProps, type GraphEdge, type GraphNode, Grid, type GridProps, HStack, type HStackProps, Header, type HeaderProps, Heading, type HeadingProps, HealthBar, type HealthBarProps, type HighlightType, Icon, type IconAnimation, type IconProps, type IconSize, Input, InputGroup, type InputGroupProps, type InputProps, type InventoryItem, InventoryPanel, type InventoryPanelProps, IsometricCanvas, type IsometricCanvasProps, type IsometricFeature, type IsometricTile, type IsometricUnit, Label, type LabelProps, type LawReference, LawReferenceTooltip, type LawReferenceTooltipProps, List, type ListItem, type ListProps, ListTemplate, type ListTemplateItem, type ListTemplateProps, type ListVariant, LoadingState, type LoadingStateProps, type MapHero, type MapHex, MasterDetail, type MasterDetailProps, MediaGallery, type MediaGalleryProps, type MediaItem, Menu, type MenuItem, type MenuOption, type MenuProps, Meter, type MeterProps, type MeterThreshold, type MeterVariant, Modal, type ModalProps, type ModalSize, ModalSlot, type ModalSlotProps, type NavItem, Navigation, type NavigationItem, type NavigationProps, OrbitalVisualization, type OrbitalVisualizationProps, Overlay, type OverlayProps, type PageBreadcrumb, PageHeader, type PageHeaderProps, Pagination, type PaginationProps, Popover, type PopoverProps, ProgressBar, type ProgressBarColor, type ProgressBarProps, type ProgressBarVariant, Radio, type RadioProps, type RelationOption, RelationSelect, type RelationSelectProps, RepeatableFormSection, type RepeatableFormSectionProps, type RepeatableItem, type ResolvedFrame, type RowAction, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScoreDisplay, type ScoreDisplayProps, SearchInput, type SearchInputProps, Section, type SectionProps, Select, type SelectOption, type SelectProps, type SettingsFieldConfig, type SettingsSectionConfig, SettingsTemplate, type SettingsTemplateProps, type SettingsVariant, type SheetUrlResolver, SidePanel, type SidePanelProps, Sidebar, type SidebarItem, type SidebarProps, SignaturePad, type SignaturePadProps, SimpleGrid, type SimpleGridProps, SlotContent, SlotContentRenderer, type SortDirection, Spacer, type SpacerProps, type SpacerSize, Spinner, type SpinnerProps, Split, SplitPane, type SplitPaneProps, type SplitProps, Sprite, type SpriteDirection, type SpriteFrameDims, type SpriteProps, type SpriteSheetUrls, Stack, type StackAlign, type StackDirection, type StackGap, type StackJustify, type StackProps, StatCard, type StatCardProps, Switch, type SwitchProps, TILE_HEIGHT, TILE_WIDTH, type TabDefinition, type TabItem, TabbedContainer, type TabbedContainerProps, Table, type TableColumn, type TableProps, Tabs, type TabsProps, Text, TextHighlight, type TextHighlightProps, type TextProps, Textarea, type TextareaProps, ThemeSelector, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineItem, type TimelineItemStatus, type TimelineProps, Toast, type ToastProps, ToastSlot, type ToastSlotProps, type ToastVariant, Tooltip, type TooltipProps, Typography, type TypographyProps, type TypographyVariant, UISlot, UISlotComponent, UISlotRenderer, type UISlotRendererProps, type UnitAnimationState, type UseSpriteAnimationsOptions, type UseSpriteAnimationsResult, VStack, type VStackProps, ViolationAlert, type ViolationAlertProps, type ViolationRecord, WizardContainer, type WizardContainerProps, WizardNavigation, type WizardNavigationProps, WizardProgress, type WizardProgressProps, type WizardProgressStep, type WizardStep, type WorldMapSlotContext, WorldMapTemplate, type WorldMapTemplateProps, createUnitAnimationState, drawSprite, getCurrentFrame, inferDirection, isoToScreen, resolveFrame, resolveSheetDirection, screenToIso, tickAnimationState, transitionAnimation, useCamera, useImageCache, useSpriteAnimations };
6537
+ export { Accordion, type AccordionItem, type AccordionProps, Card as ActionCard, type CardProps as ActionCardProps, Alert, type AlertProps, type AlertVariant, type AnimationDef, type AnimationName, AuthLayout, type AuthLayoutProps, Avatar, type AvatarProps, type AvatarSize, type AvatarStatus, Badge, type BadgeProps, type BadgeVariant, BattleBoard, type BattleBoardProps, type BattleEntity, type BattlePhase, type BattleSlotContext, BattleTemplate, type BattleTemplateProps, type BattleTile, type BattleUnit, Box, type BoxBg, type BoxMargin, type BoxPadding, type BoxProps, type BoxRounded, type BoxShadow, Breadcrumb, type BreadcrumbItem, type BreadcrumbProps, Button, ButtonGroup, type ButtonGroupProps, type ButtonProps, type CameraState, CanvasEffect, type CanvasEffectProps, Card$1 as Card, type CardAction, CardBody, CardContent, CardFooter, CardGrid, type CardGridGap, type CardGridProps, CardHeader, type CardProps$1 as CardProps, CardTitle, CastleBoard, type CastleBoardProps, type CastleEntity, type CastleSlotContext, CastleTemplate, type CastleTemplateProps, Center, type CenterProps, Chart, type ChartDataPoint, type ChartProps, type ChartSeries, type ChartType, Checkbox, type CheckboxProps, CodeViewer, type CodeViewerMode, type CodeViewerProps, CollapsibleSection, type CollapsibleSectionProps, type Column, type ColumnConfig, type CombatActionType, type ConditionalContext, ConditionalWrapper, type ConditionalWrapperProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmDialogVariant, Container, type ContainerProps, ControlButton, type ControlButtonProps, type CounterSize, CounterTemplate, type CounterTemplateProps, type CounterVariant, type CrudItem, CrudTemplate, type CrudTemplateProps, type CrudVariant, DIAMOND_TOP_Y, DashboardGrid, type DashboardGridCell, type DashboardGridProps, DashboardLayout, type DashboardLayoutProps, DataTable, type DataTableProps, type DetailField, DetailPanel, type DetailPanelProps, type DetailSection, DialogueBox, type DialogueBoxProps, type DialogueChoice, type DialogueNode, type DiffLine, Divider, type DividerOrientation, type DividerProps, type DocumentType, DocumentViewer, type DocumentViewerProps, Drawer, type DrawerPosition, type DrawerProps, type DrawerSize, DrawerSlot, type DrawerSlotProps, EditorCheckbox, type EditorCheckboxProps, type EditorMode, EditorSelect, type EditorSelectProps, EditorSlider, type EditorSliderProps, EditorTextInput, type EditorTextInputProps, EditorToolbar, type EditorToolbarProps, EmptyState, type EmptyStateProps, ErrorState, type ErrorStateProps, EventBusContextType, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, type FacingDirection, type FieldConfig, type FilterDefinition, FilterGroup, type FilterGroupProps, type FilterValue, Flex, type FlexProps, FloatingActionButton, type FloatingActionButtonProps, Form, FormActions, type FormActionsProps, FormField, type FormFieldConfig, type FormFieldProps, FormLayout, type FormLayoutProps, type FormProps, FormSection$1 as FormSection, FormSectionHeader, type FormSectionHeaderProps, type FormSectionProps, FormTemplate, type FormTemplateProps, type FormVariant, type FrameDimsResolver, GameHud, type GameHudElement, type GameHudProps, type GameHudStat, GameMenu, type GameMenuProps, type GameOverAction, GameOverScreen, type GameOverScreenProps, type GameOverStat, GameShell, type GameShellProps, GameTemplate, type GameTemplateProps, GenericAppTemplate, type GenericAppTemplateProps, GraphCanvas, type GraphCanvasProps, type GraphEdge, type GraphNode, Grid, type GridProps, HStack, type HStackProps, Header, type HeaderProps, Heading, type HeadingProps, HealthBar, type HealthBarProps, type HighlightType, Icon, type IconAnimation, type IconProps, type IconSize, Input, InputGroup, type InputGroupProps, type InputProps, type InventoryItem, InventoryPanel, type InventoryPanelProps, IsometricCanvas, type IsometricCanvasProps, type IsometricFeature, type IsometricTile, type IsometricUnit, Label, type LabelProps, type LawReference, LawReferenceTooltip, type LawReferenceTooltipProps, List, type ListItem, type ListProps, ListTemplate, type ListTemplateItem, type ListTemplateProps, type ListVariant, LoadingState, type LoadingStateProps, type MapHero, type MapHex, MasterDetail, type MasterDetailProps, MediaGallery, type MediaGalleryProps, type MediaItem, Menu, type MenuItem, type MenuOption, type MenuProps, Meter, type MeterProps, type MeterThreshold, type MeterVariant, Modal, type ModalProps, type ModalSize, ModalSlot, type ModalSlotProps, type NavItem, Navigation, type NavigationItem, type NavigationProps, OrbitalVisualization, type OrbitalVisualizationProps, Overlay, type OverlayProps, type PageBreadcrumb, PageHeader, type PageHeaderProps, Pagination, type PaginationProps, type Physics2DState, type PhysicsBounds, type PhysicsConfig, PhysicsManager, Popover, type PopoverProps, ProgressBar, type ProgressBarColor, type ProgressBarProps, type ProgressBarVariant, Radio, type RadioProps, type RelationOption, RelationSelect, type RelationSelectProps, RepeatableFormSection, type RepeatableFormSectionProps, type RepeatableItem, type ResolvedFrame, type RowAction, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScoreDisplay, type ScoreDisplayProps, SearchInput, type SearchInputProps, Section, type SectionProps, Select, type SelectOption, type SelectProps, type SettingsFieldConfig, type SettingsSectionConfig, SettingsTemplate, type SettingsTemplateProps, type SettingsVariant, type SheetUrlResolver, SidePanel, type SidePanelProps, Sidebar, type SidebarItem, type SidebarProps, SignaturePad, type SignaturePadProps, SimpleGrid, type SimpleGridProps, SlotContent, SlotContentRenderer, type SortDirection, Spacer, type SpacerProps, type SpacerSize, Spinner, type SpinnerProps, Split, SplitPane, type SplitPaneProps, type SplitProps, Sprite, type SpriteDirection, type SpriteFrameDims, type SpriteProps, type SpriteSheetUrls, Stack, type StackAlign, type StackDirection, type StackGap, type StackJustify, type StackProps, StatCard, type StatCardProps, StatusBar, type StatusBarProps, Switch, type SwitchProps, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, type TabDefinition, type TabItem, TabbedContainer, type TabbedContainerProps, Table, type TableColumn, type TableProps, Tabs, type TabsProps, type TemplateProps, TerrainPalette, type TerrainPaletteProps, Text, TextHighlight, type TextHighlightProps, type TextProps, Textarea, type TextareaProps, ThemeSelector, ThemeToggle, type ThemeToggleProps, Timeline, type TimelineItem, type TimelineItemStatus, type TimelineProps, Toast, type ToastProps, ToastSlot, type ToastSlotProps, type ToastVariant, Tooltip, type TooltipProps, Typography, type TypographyProps, type TypographyVariant, UISlot, UISlotComponent, UISlotRenderer, type UISlotRendererProps, type UnitAnimationState, type UsePhysics2DOptions, type UsePhysics2DReturn, type UseSpriteAnimationsOptions, type UseSpriteAnimationsResult, VStack, type VStackProps, ViolationAlert, type ViolationAlertProps, type ViolationRecord, WizardContainer, type WizardContainerProps, WizardNavigation, type WizardNavigationProps, WizardProgress, type WizardProgressProps, type WizardProgressStep, type WizardStep, WorldMapBoard, type WorldMapBoardProps, type WorldMapEntity, type WorldMapSlotContext, WorldMapTemplate, type WorldMapTemplateProps, createUnitAnimationState, drawSprite, getCurrentFrame, inferDirection, isoToScreen, resolveFrame, resolveSheetDirection, screenToIso, tickAnimationState, transitionAnimation, useCamera, useImageCache, usePhysics2D, useSpriteAnimations };