Documentation
¶
Overview ¶
Package spatial provides 2D positioning and movement infrastructure for entity placement and spatial queries without imposing game-specific rules.
Purpose: This package handles all spatial mathematics, collision detection, and movement validation without imposing any game-specific movement rules or combat mechanics. It provides the mathematical foundation for position-based game systems.
Scope:
- 2D coordinate system with configurable units
- Grid support (square, hex, gridless)
- Room-based spatial organization
- Collision detection and spatial queries
- Path validation (not pathfinding algorithms)
- Multi-room orchestration and connections
- Distance calculations and area queries
- Entity position tracking
Non-Goals:
- Movement rules: Speed, difficult terrain are game-specific
- Line of sight rules: Cover/concealment mechanics belong in games
- Pathfinding algorithms: AI navigation belongs in behavior package
- Combat ranges: Weapon/spell ranges are game-specific
- 3D positioning: This is explicitly 2D only
- Movement costs: Action economy is game-specific
- Elevation: Height/flying is game-specific
Integration: This package integrates with:
- behavior: Provides position queries for AI decisions
- spawn: Validates entity placement
- environments: Provides room infrastructure
- events: Publishes movement and room transition events
The spatial package is the foundation for any position-based mechanics but deliberately avoids encoding any game rules about how space is used.
Example:
// Create a room with square grid
room := spatial.NewBasicRoom(spatial.RoomConfig{
ID: "throne-room",
Width: 40,
Height: 30,
Grid: spatial.GridTypeSquare,
})
// Place entities
err := room.PlaceEntity("guard-1", spatial.Position{X: 10, Y: 5})
err = room.PlaceEntity("king", spatial.Position{X: 20, Y: 25})
// Query nearby entities
nearby := room.GetEntitiesWithinDistance(
spatial.Position{X: 15, Y: 15},
10.0, // 10 units radius
)
// Multi-room orchestration
orchestrator := spatial.NewBasicOrchestrator(spatial.OrchestratorConfig{})
orchestrator.AddRoom(room)
orchestrator.AddRoom(hallway)
// Connect rooms
door := spatial.NewDoorConnection("door-1", "throne-room", "hallway",
spatial.Position{X: 40, Y: 15}, // Exit position
spatial.Position{X: 0, Y: 5}, // Entry position
)
orchestrator.AddConnection(door)
Package spatial provides 2D spatial positioning and movement capabilities for RPG games.
Package spatial provides 2D spatial positioning and movement capabilities for RPG games.
Index ¶
- Constants
- Variables
- func RunPositionValidationTests(t *testing.T, grid Grid)
- type AxialHexGrid
- func (a *AxialHexGrid) Distance(from, to Position) float64
- func (a *AxialHexGrid) GetDimensions() Dimensions
- func (a *AxialHexGrid) GetLineOfSight(from, to Position) []Position
- func (a *AxialHexGrid) GetNeighbors(pos Position) []Position
- func (a *AxialHexGrid) GetPositionsInCircle(circle Circle) []Position
- func (a *AxialHexGrid) GetPositionsInCone(origin, direction Position, length, angle float64) []Position
- func (a *AxialHexGrid) GetPositionsInLine(from, to Position) []Position
- func (a *AxialHexGrid) GetPositionsInRange(center Position, radius float64) []Position
- func (a *AxialHexGrid) GetPositionsInRectangle(rect Rectangle) []Position
- func (a *AxialHexGrid) GetShape() GridShape
- func (a *AxialHexGrid) IsAdjacent(pos1, pos2 Position) bool
- func (a *AxialHexGrid) IsValidPosition(pos Position) bool
- type AxialHexGridConfig
- type BasicConnection
- func CreateBridgeConnection(id, fromRoom, toRoom string, cost float64) *BasicConnection
- func CreateDoorConnection(id, fromRoom, toRoom string, cost float64) *BasicConnection
- func CreatePortalConnection(id, fromRoom, toRoom string, cost float64, bidirectional bool) *BasicConnection
- func CreateSecretPassageConnection(id, fromRoom, toRoom string, cost float64, requirements []string) *BasicConnection
- func CreateStairsConnection(id, fromRoom, toRoom string, cost float64, goingUp bool) *BasicConnection
- func CreateTunnelConnection(id, fromRoom, toRoom string, cost float64) *BasicConnection
- func NewBasicConnection(config BasicConnectionConfig) *BasicConnection
- func (bc *BasicConnection) AddRequirement(requirement string)
- func (bc *BasicConnection) GetConnectionType() ConnectionType
- func (bc *BasicConnection) GetFromRoom() string
- func (bc *BasicConnection) GetID() string
- func (bc *BasicConnection) GetRequirements() []string
- func (bc *BasicConnection) GetToRoom() string
- func (bc *BasicConnection) GetTraversalCost(_ core.Entity) float64
- func (bc *BasicConnection) GetType() core.EntityType
- func (bc *BasicConnection) HasRequirement(requirement string) bool
- func (bc *BasicConnection) IsPassable(_ core.Entity) bool
- func (bc *BasicConnection) IsReversible() bool
- func (bc *BasicConnection) RemoveRequirement(requirement string)
- func (bc *BasicConnection) SetPassable(passable bool)
- type BasicConnectionConfig
- type BasicRoom
- func (r *BasicRoom) CanPlaceEntity(entity core.Entity, pos Position) bool
- func (r *BasicRoom) ConnectToEventBus(bus events.EventBus)
- func (r *BasicRoom) GetAllEntities() map[string]core.Entity
- func (r *BasicRoom) GetBoundary(from, to Position) (Boundary, bool)
- func (r *BasicRoom) GetEntitiesAt(pos Position) []core.Entity
- func (r *BasicRoom) GetEntitiesInRange(center Position, radius float64) []core.Entity
- func (r *BasicRoom) GetEntityCount() int
- func (r *BasicRoom) GetEntityCubePosition(entityID string) *CubeCoordinate
- func (r *BasicRoom) GetEntityPosition(entityID string) (Position, bool)
- func (r *BasicRoom) GetGrid() Grid
- func (r *BasicRoom) GetID() string
- func (r *BasicRoom) GetLineOfSight(from, to Position) []Position
- func (r *BasicRoom) GetOccupiedPositions() []Position
- func (r *BasicRoom) GetPositionsInRange(center Position, radius float64) []Position
- func (r *BasicRoom) GetType() core.EntityType
- func (r *BasicRoom) IsBoundaryLineOfSightBlocked(from, to Position) bool
- func (r *BasicRoom) IsBoundaryMovementBlocked(from, to Position) bool
- func (r *BasicRoom) IsLineOfSightBlocked(from, to Position) bool
- func (r *BasicRoom) IsPositionOccupied(pos Position) bool
- func (r *BasicRoom) MoveEntity(entityID string, newPos Position) error
- func (r *BasicRoom) PlaceEntity(entity core.Entity, pos Position) error
- func (r *BasicRoom) RegisterBoundary(boundary Boundary) error
- func (r *BasicRoom) RemoveBoundary(from, to Position) error
- func (r *BasicRoom) RemoveEntity(entityID string) error
- func (r *BasicRoom) ToData() RoomData
- type BasicRoomConfig
- type BasicRoomOrchestrator
- func (bro *BasicRoomOrchestrator) AddConnection(connection Connection) error
- func (bro *BasicRoomOrchestrator) AddRoom(room Room) error
- func (bro *BasicRoomOrchestrator) CanMoveEntityBetweenRooms(entityIDStr, fromRoomStr, toRoomStr, connectionIDStr string) bool
- func (bro *BasicRoomOrchestrator) ConnectToEventBus(bus events.EventBus)
- func (bro *BasicRoomOrchestrator) FindPath(fromRoom, toRoom string, entity core.Entity) ([]string, error)
- func (bro *BasicRoomOrchestrator) GetAllConnections() map[string]Connection
- func (bro *BasicRoomOrchestrator) GetAllRooms() map[string]Room
- func (bro *BasicRoomOrchestrator) GetConnection(connectionIDStr string) (Connection, bool)
- func (bro *BasicRoomOrchestrator) GetEntityRoom(entityIDStr string) (string, bool)
- func (bro *BasicRoomOrchestrator) GetEventBus() events.EventBus
- func (bro *BasicRoomOrchestrator) GetID() string
- func (bro *BasicRoomOrchestrator) GetLayout() LayoutType
- func (bro *BasicRoomOrchestrator) GetRoom(roomIDStr string) (Room, bool)
- func (bro *BasicRoomOrchestrator) GetRoomConnections(roomIDStr string) []Connection
- func (bro *BasicRoomOrchestrator) GetType() core.EntityType
- func (bro *BasicRoomOrchestrator) MoveEntityBetweenRooms(entityIDStr, fromRoomStr, toRoomStr, connectionIDStr string) error
- func (bro *BasicRoomOrchestrator) RemoveConnection(connectionIDStr string) error
- func (bro *BasicRoomOrchestrator) RemoveRoom(roomIDStr string) error
- func (bro *BasicRoomOrchestrator) SetEventBus(bus events.EventBus)
- func (bro *BasicRoomOrchestrator) SetLayout(layout LayoutType) error
- type BasicRoomOrchestratorConfig
- type Boundary
- type BoundaryAwareRoom
- type Circle
- type Connection
- type ConnectionAddedEvent
- type ConnectionID
- type ConnectionRemovedEvent
- type ConnectionType
- type CubeCoordinate
- func (c CubeCoordinate) Add(other CubeCoordinate) CubeCoordinate
- func (c CubeCoordinate) Distance(other CubeCoordinate) int
- func (c CubeCoordinate) Equals(other CubeCoordinate) bool
- func (c CubeCoordinate) GetNeighbors() []CubeCoordinate
- func (c CubeCoordinate) IsValid() bool
- func (c CubeCoordinate) Scale(factor int) CubeCoordinate
- func (c CubeCoordinate) String() string
- func (c CubeCoordinate) Subtract(other CubeCoordinate) CubeCoordinate
- func (c CubeCoordinate) ToOffsetCoordinate() Position
- func (c CubeCoordinate) ToOffsetCoordinateWithOrientation(orientation HexOrientation) Position
- type Dimensions
- type EntityCubePlacement
- type EntityFilter
- type EntityID
- type EntityMovedEvent
- type EntityPlacedEvent
- type EntityPlacement
- type EntityRemovedEvent
- type EntityRoomTransitionEvent
- type EntityTransitionBeganEvent
- type EntityTransitionEndedEvent
- type EventBusIntegration
- type Grid
- type GridShape
- type GridlessConfig
- type GridlessRoom
- func (gr *GridlessRoom) Distance(from, to Position) float64
- func (gr *GridlessRoom) GetDimensions() Dimensions
- func (gr *GridlessRoom) GetLineOfSight(from, to Position) []Position
- func (gr *GridlessRoom) GetNearestPosition(pos Position) Position
- func (gr *GridlessRoom) GetNeighbors(pos Position) []Position
- func (gr *GridlessRoom) GetPositionsInArc(center Position, radius float64, startAngle, endAngle float64) []Position
- func (gr *GridlessRoom) GetPositionsInCircle(circle Circle) []Position
- func (gr *GridlessRoom) GetPositionsInCone(origin Position, direction Position, length float64, angle float64) []Position
- func (gr *GridlessRoom) GetPositionsInLine(from, to Position) []Position
- func (gr *GridlessRoom) GetPositionsInRange(center Position, radius float64) []Position
- func (gr *GridlessRoom) GetPositionsInRectangle(rect Rectangle) []Position
- func (gr *GridlessRoom) GetShape() GridShape
- func (gr *GridlessRoom) IsAdjacent(pos1, pos2 Position) bool
- func (gr *GridlessRoom) IsValidPosition(pos Position) bool
- type HexGrid
- func (hg *HexGrid) CubeToOffset(cube CubeCoordinate) Position
- func (hg *HexGrid) Distance(from, to Position) float64
- func (hg *HexGrid) GetCubeNeighbors(pos Position) []CubeCoordinate
- func (hg *HexGrid) GetDimensions() Dimensions
- func (hg *HexGrid) GetHexRing(center Position, radius int) []Position
- func (hg *HexGrid) GetHexSpiral(center Position, radius int) []Position
- func (hg *HexGrid) GetLineOfSight(from, to Position) []Position
- func (hg *HexGrid) GetNeighbors(pos Position) []Position
- func (hg *HexGrid) GetOrientation() HexOrientation
- func (hg *HexGrid) GetPositionsInCircle(circle Circle) []Position
- func (hg *HexGrid) GetPositionsInCone(origin Position, direction Position, length float64, angle float64) []Position
- func (hg *HexGrid) GetPositionsInLine(from, to Position) []Position
- func (hg *HexGrid) GetPositionsInRange(center Position, radius float64) []Position
- func (hg *HexGrid) GetPositionsInRectangle(rect Rectangle) []Position
- func (hg *HexGrid) GetShape() GridShape
- func (hg *HexGrid) IsAdjacent(pos1, pos2 Position) bool
- func (hg *HexGrid) IsPointyTop() bool
- func (hg *HexGrid) IsValidPosition(pos Position) bool
- func (hg *HexGrid) OffsetToCube(pos Position) CubeCoordinate
- type HexGridConfig
- type HexOrientation
- type LayoutChangedEvent
- type LayoutMetrics
- type LayoutOrchestrator
- type LayoutType
- type OrchestratorID
- type PathFinder
- type Placeable
- type PlaceableData
- type Position
- type Query
- type QueryEntitiesInRangeData
- type QueryHandler
- type QueryLineOfSightData
- type QueryMovementData
- type QueryPlacementData
- type QueryPositionsInRangeData
- type QueryResult
- type QueryUtils
- func (q *QueryUtils) QueryEntitiesInRange(ctx context.Context, center Position, radius float64, roomID string, ...) ([]core.Entity, error)
- func (q *QueryUtils) QueryLineOfSight(ctx context.Context, from, to Position, roomID string) ([]Position, bool, error)
- func (q *QueryUtils) QueryMovement(ctx context.Context, entity core.Entity, from, to Position, roomID string) (bool, []Position, float64, error)
- func (q *QueryUtils) QueryPlacement(ctx context.Context, entity core.Entity, position Position, roomID string) (bool, error)
- func (q *QueryUtils) QueryPositionsInRange(ctx context.Context, center Position, radius float64, roomID string) ([]Position, error)
- type Rectangle
- type Room
- type RoomAddedEvent
- type RoomCreatedEvent
- type RoomData
- type RoomID
- type RoomOrchestrator
- type RoomRemovedEvent
- type SimpleEntityFilter
- func (f *SimpleEntityFilter) Matches(entity core.Entity) bool
- func (f *SimpleEntityFilter) WithEntityIDs(ids ...string) *SimpleEntityFilter
- func (f *SimpleEntityFilter) WithEntityTypes(types ...string) *SimpleEntityFilter
- func (f *SimpleEntityFilter) WithExcludeIDs(ids ...string) *SimpleEntityFilter
- type SimplePathFinder
- type SpatialQueryHandler
- type SquareGrid
- func (sg *SquareGrid) Distance(from, to Position) float64
- func (sg *SquareGrid) GetDimensions() Dimensions
- func (sg *SquareGrid) GetLineOfSight(from, to Position) []Position
- func (sg *SquareGrid) GetNeighbors(pos Position) []Position
- func (sg *SquareGrid) GetPositionsInCircle(circle Circle) []Position
- func (sg *SquareGrid) GetPositionsInCone(origin Position, direction Position, length float64, angle float64) []Position
- func (sg *SquareGrid) GetPositionsInLine(from, to Position) []Position
- func (sg *SquareGrid) GetPositionsInRange(center Position, radius float64) []Position
- func (sg *SquareGrid) GetPositionsInRectangle(rect Rectangle) []Position
- func (sg *SquareGrid) GetShape() GridShape
- func (sg *SquareGrid) IsAdjacent(pos1, pos2 Position) bool
- func (sg *SquareGrid) IsValidPosition(pos Position) bool
- type SquareGridConfig
- type Transition
- type TransitionID
- type TransitionSystem
- type TraversalPathFinder
- type TraversalPredicate
- type TraversalSearchLimit
Constants ¶
const ( // GridTypeSquare represents square grid type in room data GridTypeSquare = "square" // GridTypeHex represents hexagonal grid type in room data GridTypeHex = "hex" // GridTypeGridless represents gridless type in room data GridTypeGridless = "gridless" )
Grid type constants for room data
const ( // Query events - these remain as direct function calls, not migrated to typed events EventQueryPositionsInRange = "spatial.query.positions_in_range" EventQueryEntitiesInRange = "spatial.query.entities_in_range" EventQueryLineOfSight = "spatial.query.line_of_sight" EventQueryMovement = "spatial.query.movement" EventQueryPlacement = "spatial.query.placement" )
Legacy event constants kept only for query operations (non-notification events)
Variables ¶
var ( // EntityPlacedTopic publishes events when entities are placed in rooms EntityPlacedTopic = events.DefineTypedTopic[EntityPlacedEvent]("spatial.entity.placed") // EntityMovedTopic publishes events when entities are moved within or between rooms EntityMovedTopic = events.DefineTypedTopic[EntityMovedEvent]("spatial.entity.moved") // EntityRemovedTopic publishes events when entities are removed from rooms EntityRemovedTopic = events.DefineTypedTopic[EntityRemovedEvent]("spatial.entity.removed") // RoomCreatedTopic publishes events when rooms are created RoomCreatedTopic = events.DefineTypedTopic[RoomCreatedEvent]("spatial.room.created") // RoomAddedTopic publishes events when rooms are added to orchestrators RoomAddedTopic = events.DefineTypedTopic[RoomAddedEvent]("spatial.orchestrator.room_added") // RoomRemovedTopic publishes events when rooms are removed from orchestrators RoomRemovedTopic = events.DefineTypedTopic[RoomRemovedEvent]("spatial.orchestrator.room_removed") // ConnectionAddedTopic publishes events when connections are added between rooms ConnectionAddedTopic = events.DefineTypedTopic[ConnectionAddedEvent]("spatial.orchestrator.connection_added") // ConnectionRemovedTopic publishes events when connections are removed between rooms ConnectionRemovedTopic = events.DefineTypedTopic[ConnectionRemovedEvent]("spatial.orchestrator.connection_removed") // EntityTransitionBeganTopic publishes events when entity transitions begin EntityTransitionBeganTopic = events.DefineTypedTopic[EntityTransitionBeganEvent]("spatial.entity.transition.began") // EntityTransitionEndedTopic publishes events when entity transitions complete EntityTransitionEndedTopic = events.DefineTypedTopic[EntityTransitionEndedEvent]("spatial.entity.transition.ended") // EntityRoomTransitionTopic publishes events when entities transition between rooms EntityRoomTransitionTopic = events.DefineTypedTopic[EntityRoomTransitionEvent]("entity.room_transition") // LayoutChangedTopic publishes events when orchestrator layouts change LayoutChangedTopic = events.DefineTypedTopic[LayoutChangedEvent]("spatial.orchestrator.layout_changed") )
Functions ¶
func RunPositionValidationTests ¶
RunPositionValidationTests runs common position validation tests for any Grid
Types ¶
type AxialHexGrid ¶ added in v0.5.0
type AxialHexGrid struct {
// contains filtered or unexported fields
}
AxialHexGrid implements Grid for hexagonal maps that store positions in axial coordinates: Position.X = Q (column), Position.Y = R (row), S = -(Q+R).
This is the correct grid for encounter SDKs and tactical maps that use axial hex coordinates natively (e.g. rpg-api's encountercore.Hex). The existing HexGrid expects offset coordinates and would produce wrong distances when fed axial positions — AxialHexGrid eliminates that mismatch.
Distance uses the cube formula: (|ΔQ| + |ΔR| + |ΔS|) / 2, which correctly counts adjacent hexes as distance 1 regardless of their direction relative to the X/Y axes. This matches D&D 5e adjacency rules for hex maps.
func NewAxialHexGrid ¶ added in v0.5.0
func NewAxialHexGrid(config AxialHexGridConfig) *AxialHexGrid
NewAxialHexGrid creates a new hex grid that treats Position.X/Y as axial Q/R coordinates. Use this instead of NewHexGrid when positions are stored in axial (not offset) form.
func (*AxialHexGrid) Distance ¶ added in v0.5.0
func (a *AxialHexGrid) Distance(from, to Position) float64
Distance returns the hex distance between two axial positions. Interprets Position.X as Q and Position.Y as R; derives S = -(Q+R). Uses the cube formula: (|ΔQ| + |ΔR| + |ΔS|) / 2.
func (*AxialHexGrid) GetDimensions ¶ added in v0.5.0
func (a *AxialHexGrid) GetDimensions() Dimensions
GetDimensions returns the configured bounding-box dimensions.
func (*AxialHexGrid) GetLineOfSight ¶ added in v0.5.0
func (a *AxialHexGrid) GetLineOfSight(from, to Position) []Position
GetLineOfSight returns hex positions along the line from from to to using cube-coordinate linear interpolation (standard hex line algorithm).
func (*AxialHexGrid) GetNeighbors ¶ added in v0.5.0
func (a *AxialHexGrid) GetNeighbors(pos Position) []Position
GetNeighbors returns the 6 axial positions adjacent to pos.
func (*AxialHexGrid) GetPositionsInCircle ¶ added in v0.5.0
func (a *AxialHexGrid) GetPositionsInCircle(circle Circle) []Position
GetPositionsInCircle returns all valid axial positions within the given circle.
func (*AxialHexGrid) GetPositionsInCone ¶ added in v0.5.0
func (a *AxialHexGrid) GetPositionsInCone(origin, direction Position, length, angle float64) []Position
GetPositionsInCone returns axial positions within a cone.
func (*AxialHexGrid) GetPositionsInLine ¶ added in v0.5.0
func (a *AxialHexGrid) GetPositionsInLine(from, to Position) []Position
GetPositionsInLine returns the positions along a line from from to to.
func (*AxialHexGrid) GetPositionsInRange ¶ added in v0.5.0
func (a *AxialHexGrid) GetPositionsInRange(center Position, radius float64) []Position
GetPositionsInRange returns all valid axial positions within radius hex steps of center.
func (*AxialHexGrid) GetPositionsInRectangle ¶ added in v0.5.0
func (a *AxialHexGrid) GetPositionsInRectangle(rect Rectangle) []Position
GetPositionsInRectangle returns all valid axial positions within the given rectangle (treating X as Q and Y as R for the bounding box).
func (*AxialHexGrid) GetShape ¶ added in v0.5.0
func (a *AxialHexGrid) GetShape() GridShape
GetShape returns GridShapeHex.
func (*AxialHexGrid) IsAdjacent ¶ added in v0.5.0
func (a *AxialHexGrid) IsAdjacent(pos1, pos2 Position) bool
IsAdjacent reports whether two positions are adjacent (hex distance <= 1).
func (*AxialHexGrid) IsValidPosition ¶ added in v0.5.0
func (a *AxialHexGrid) IsValidPosition(pos Position) bool
IsValidPosition reports true when (Q, R) falls within ±SpanWidth/2 along Q and ±SpanHeight/2 along R. The check is centered on the origin because axial hex coordinates are symmetric — positions can have negative Q or R. This differs from SquareGrid/HexGrid whose bounds start at (0,0).
type AxialHexGridConfig ¶ added in v0.5.0
AxialHexGridConfig holds configuration for creating an AxialHexGrid. SpanWidth and SpanHeight define the total span of valid axial coordinates. IsValidPosition checks are centered on the origin — a position (Q, R) is valid when Q ∈ [-SpanWidth/2, SpanWidth/2) and R ∈ [-SpanHeight/2, SpanHeight/2). This differs from SquareGrid/HexGrid, whose Width/Height are one-sided bounds starting at (0,0). Pass large values (e.g. 1000×1000) for encounter rooms where position bounds are not meaningful.
type BasicConnection ¶
type BasicConnection struct {
// contains filtered or unexported fields
}
BasicConnection implements the Connection interface (ADR-0015: Abstract Connections)
func CreateBridgeConnection ¶
func CreateBridgeConnection(id, fromRoom, toRoom string, cost float64) *BasicConnection
CreateBridgeConnection creates a bridge connection that might be destructible
func CreateDoorConnection ¶
func CreateDoorConnection(id, fromRoom, toRoom string, cost float64) *BasicConnection
CreateDoorConnection creates a bidirectional door connection between two rooms (ADR-0015: Abstract Connections)
func CreatePortalConnection ¶
func CreatePortalConnection(id, fromRoom, toRoom string, cost float64, bidirectional bool) *BasicConnection
CreatePortalConnection creates a magical portal connection
func CreateSecretPassageConnection ¶
func CreateSecretPassageConnection(id, fromRoom, toRoom string, cost float64, requirements []string) *BasicConnection
CreateSecretPassageConnection creates a hidden passage that may have requirements
func CreateStairsConnection ¶
func CreateStairsConnection(id, fromRoom, toRoom string, cost float64, goingUp bool) *BasicConnection
CreateStairsConnection creates a stairway connection between floors
func CreateTunnelConnection ¶
func CreateTunnelConnection(id, fromRoom, toRoom string, cost float64) *BasicConnection
CreateTunnelConnection creates an underground tunnel
func NewBasicConnection ¶
func NewBasicConnection(config BasicConnectionConfig) *BasicConnection
NewBasicConnection creates a new basic connection
func (*BasicConnection) AddRequirement ¶
func (bc *BasicConnection) AddRequirement(requirement string)
AddRequirement adds a new requirement
func (*BasicConnection) GetConnectionType ¶
func (bc *BasicConnection) GetConnectionType() ConnectionType
GetConnectionType returns the connection type
func (*BasicConnection) GetFromRoom ¶
func (bc *BasicConnection) GetFromRoom() string
GetFromRoom returns the source room ID
func (*BasicConnection) GetID ¶
func (bc *BasicConnection) GetID() string
GetID returns the connection ID
func (*BasicConnection) GetRequirements ¶
func (bc *BasicConnection) GetRequirements() []string
GetRequirements returns any requirements for using this connection
func (*BasicConnection) GetToRoom ¶
func (bc *BasicConnection) GetToRoom() string
GetToRoom returns the destination room ID
func (*BasicConnection) GetTraversalCost ¶
func (bc *BasicConnection) GetTraversalCost(_ core.Entity) float64
GetTraversalCost returns the cost to traverse this connection
func (*BasicConnection) GetType ¶
func (bc *BasicConnection) GetType() core.EntityType
GetType returns the entity type (implementing core.Entity)
func (*BasicConnection) HasRequirement ¶
func (bc *BasicConnection) HasRequirement(requirement string) bool
HasRequirement checks if a specific requirement exists
func (*BasicConnection) IsPassable ¶
func (bc *BasicConnection) IsPassable(_ core.Entity) bool
IsPassable checks if entities can currently traverse this connection
func (*BasicConnection) IsReversible ¶
func (bc *BasicConnection) IsReversible() bool
IsReversible returns true if the connection works both ways
func (*BasicConnection) RemoveRequirement ¶
func (bc *BasicConnection) RemoveRequirement(requirement string)
RemoveRequirement removes a requirement
func (*BasicConnection) SetPassable ¶
func (bc *BasicConnection) SetPassable(passable bool)
SetPassable changes the passable state of the connection
type BasicConnectionConfig ¶
type BasicConnectionConfig struct {
ID string
Type string
ConnType ConnectionType
FromRoom string
ToRoom string
Reversible bool
Passable bool
Cost float64
Requirements []string
}
BasicConnectionConfig holds configuration for creating a basic connection
type BasicRoom ¶
type BasicRoom struct {
// contains filtered or unexported fields
}
BasicRoom implements the Room interface with event integration
func LoadRoomFromContext ¶
LoadRoomFromContext creates a BasicRoom from data using the GameContext pattern. This allows the room to integrate with the event system and other game infrastructure.
func NewBasicRoom ¶
func NewBasicRoom(config BasicRoomConfig) *BasicRoom
NewBasicRoom creates a new basic room (call ConnectToEventBus after creation)
func (*BasicRoom) CanPlaceEntity ¶
CanPlaceEntity checks if an entity can be placed at a position
func (*BasicRoom) ConnectToEventBus ¶ added in v0.1.1
ConnectToEventBus connects the room to an event bus for typed event publishing
func (*BasicRoom) GetAllEntities ¶
GetAllEntities returns all entities in the room
func (*BasicRoom) GetBoundary ¶ added in v0.6.0
GetBoundary returns the normalized boundary for an endpoint pair regardless of the direction passed by the caller.
func (*BasicRoom) GetEntitiesAt ¶
GetEntitiesAt returns all entities at a specific position
func (*BasicRoom) GetEntitiesInRange ¶
GetEntitiesInRange returns entities within a given range
func (*BasicRoom) GetEntityCount ¶
GetEntityCount returns the number of entities in the room
func (*BasicRoom) GetEntityCubePosition ¶ added in v0.2.0
func (r *BasicRoom) GetEntityCubePosition(entityID string) *CubeCoordinate
GetEntityCubePosition returns the cube coordinate position of an entity Returns nil if the entity doesn't exist or the grid is not a hex grid
func (*BasicRoom) GetEntityPosition ¶
GetEntityPosition returns the position of an entity
func (*BasicRoom) GetLineOfSight ¶
GetLineOfSight returns positions along the line of sight
func (*BasicRoom) GetOccupiedPositions ¶
GetOccupiedPositions returns all positions that have entities
func (*BasicRoom) GetPositionsInRange ¶
GetPositionsInRange returns all positions within a given range
func (*BasicRoom) GetType ¶
func (r *BasicRoom) GetType() core.EntityType
GetType returns the room's type (implements core.Entity)
func (*BasicRoom) IsBoundaryLineOfSightBlocked ¶ added in v0.6.0
IsBoundaryLineOfSightBlocked reports whether a registered boundary blocks line of sight across the crossing between two positions.
func (*BasicRoom) IsBoundaryMovementBlocked ¶ added in v0.6.0
IsBoundaryMovementBlocked reports whether a registered boundary blocks the crossing between two positions.
func (*BasicRoom) IsLineOfSightBlocked ¶
IsLineOfSightBlocked checks if line of sight is blocked by entities
func (*BasicRoom) IsPositionOccupied ¶
IsPositionOccupied checks if a position is occupied
func (*BasicRoom) MoveEntity ¶
MoveEntity moves an entity to a new position
func (*BasicRoom) PlaceEntity ¶
PlaceEntity places an entity at a specific position
func (*BasicRoom) RegisterBoundary ¶ added in v0.6.0
RegisterBoundary validates and registers an undirected boundary between two adjacent in-grid positions. Endpoint order is normalized and registering the same pair replaces its blocking flags.
func (*BasicRoom) RemoveBoundary ¶ added in v0.6.0
RemoveBoundary validates an undirected boundary pair and removes it. Removing an otherwise-valid pair with no registered boundary is a no-op.
func (*BasicRoom) RemoveEntity ¶
RemoveEntity removes an entity from the room
type BasicRoomConfig ¶
BasicRoomConfig holds configuration for creating a basic room
type BasicRoomOrchestrator ¶
type BasicRoomOrchestrator struct {
// contains filtered or unexported fields
}
BasicRoomOrchestrator implements the RoomOrchestrator interface
func NewBasicRoomOrchestrator ¶
func NewBasicRoomOrchestrator(config BasicRoomOrchestratorConfig) *BasicRoomOrchestrator
NewBasicRoomOrchestrator creates a new basic room orchestrator
func (*BasicRoomOrchestrator) AddConnection ¶
func (bro *BasicRoomOrchestrator) AddConnection(connection Connection) error
AddConnection creates a connection between two rooms
func (*BasicRoomOrchestrator) AddRoom ¶
func (bro *BasicRoomOrchestrator) AddRoom(room Room) error
AddRoom adds a room to the orchestrator
func (*BasicRoomOrchestrator) CanMoveEntityBetweenRooms ¶
func (bro *BasicRoomOrchestrator) CanMoveEntityBetweenRooms( entityIDStr, fromRoomStr, toRoomStr, connectionIDStr string, ) bool
CanMoveEntityBetweenRooms checks if entity movement is possible
func (*BasicRoomOrchestrator) ConnectToEventBus ¶ added in v0.1.1
func (bro *BasicRoomOrchestrator) ConnectToEventBus(bus events.EventBus)
ConnectToEventBus connects all typed topics to the event bus
func (*BasicRoomOrchestrator) FindPath ¶
func (bro *BasicRoomOrchestrator) FindPath(fromRoom, toRoom string, entity core.Entity) ([]string, error)
FindPath finds a path between rooms using connections (simple implementation)
func (*BasicRoomOrchestrator) GetAllConnections ¶
func (bro *BasicRoomOrchestrator) GetAllConnections() map[string]Connection
GetAllConnections returns all connections
func (*BasicRoomOrchestrator) GetAllRooms ¶
func (bro *BasicRoomOrchestrator) GetAllRooms() map[string]Room
GetAllRooms returns all managed rooms
func (*BasicRoomOrchestrator) GetConnection ¶
func (bro *BasicRoomOrchestrator) GetConnection(connectionIDStr string) (Connection, bool)
GetConnection retrieves a connection by ID
func (*BasicRoomOrchestrator) GetEntityRoom ¶
func (bro *BasicRoomOrchestrator) GetEntityRoom(entityIDStr string) (string, bool)
GetEntityRoom returns which room contains the entity
func (*BasicRoomOrchestrator) GetEventBus ¶
func (bro *BasicRoomOrchestrator) GetEventBus() events.EventBus
GetEventBus returns the current event bus (implements EventBusIntegration)
func (*BasicRoomOrchestrator) GetID ¶
func (bro *BasicRoomOrchestrator) GetID() string
GetID returns the orchestrator ID
func (*BasicRoomOrchestrator) GetLayout ¶
func (bro *BasicRoomOrchestrator) GetLayout() LayoutType
GetLayout returns the current layout pattern
func (*BasicRoomOrchestrator) GetRoom ¶
func (bro *BasicRoomOrchestrator) GetRoom(roomIDStr string) (Room, bool)
GetRoom retrieves a room by ID
func (*BasicRoomOrchestrator) GetRoomConnections ¶
func (bro *BasicRoomOrchestrator) GetRoomConnections(roomIDStr string) []Connection
GetRoomConnections returns all connections for a specific room
func (*BasicRoomOrchestrator) GetType ¶
func (bro *BasicRoomOrchestrator) GetType() core.EntityType
GetType returns the entity type
func (*BasicRoomOrchestrator) MoveEntityBetweenRooms ¶
func (bro *BasicRoomOrchestrator) MoveEntityBetweenRooms( entityIDStr, fromRoomStr, toRoomStr, connectionIDStr string, ) error
MoveEntityBetweenRooms moves an entity from one room to another (ADR-0015: Abstract Connections)
func (*BasicRoomOrchestrator) RemoveConnection ¶
func (bro *BasicRoomOrchestrator) RemoveConnection(connectionIDStr string) error
RemoveConnection removes a connection
func (*BasicRoomOrchestrator) RemoveRoom ¶
func (bro *BasicRoomOrchestrator) RemoveRoom(roomIDStr string) error
RemoveRoom removes a room from the orchestrator
func (*BasicRoomOrchestrator) SetEventBus ¶
func (bro *BasicRoomOrchestrator) SetEventBus(bus events.EventBus)
SetEventBus sets the event bus for the orchestrator (implements EventBusIntegration)
func (*BasicRoomOrchestrator) SetLayout ¶
func (bro *BasicRoomOrchestrator) SetLayout(layout LayoutType) error
SetLayout configures the arrangement pattern
type BasicRoomOrchestratorConfig ¶
type BasicRoomOrchestratorConfig struct {
ID OrchestratorID // Optional: if empty, will auto-generate
Type string
Layout LayoutType
}
BasicRoomOrchestratorConfig holds configuration for creating a basic room orchestrator
type Boundary ¶ added in v0.6.0
type Boundary struct {
// From is one endpoint of the crossing. Registered boundaries expose the
// lexicographically first endpoint here.
From Position
// To is the other endpoint of the crossing. Registered boundaries expose
// the lexicographically second endpoint here.
To Position
// BlocksMovement reports whether an entity may cross this boundary.
BlocksMovement bool
// BlocksLineOfSight reports whether line of sight may cross this boundary.
BlocksLineOfSight bool
}
Boundary represents an undirected crossing between two adjacent grid positions. BasicRoom normalizes From and To when the boundary is registered, so the same boundary is found regardless of the caller's direction.
Boundaries are runtime spatial state only. Higher-level domains own any authored or persisted representation and register their current crossings when reconstructing a room.
type BoundaryAwareRoom ¶ added in v0.6.0
type BoundaryAwareRoom interface {
Room
// RegisterBoundary validates and normalizes an undirected adjacent in-grid
// boundary. Registering an existing pair updates its blocking flags.
RegisterBoundary(boundary Boundary) error
// RemoveBoundary validates an undirected adjacent in-grid pair and removes
// its boundary. Removing an unregistered valid pair is a no-op.
RemoveBoundary(from, to Position) error
// GetBoundary returns the normalized boundary registered for either order
// of the endpoint pair.
GetBoundary(from, to Position) (Boundary, bool)
// IsBoundaryMovementBlocked reports whether the endpoint crossing blocks
// movement. It returns false when no boundary is registered.
IsBoundaryMovementBlocked(from, to Position) bool
// IsBoundaryLineOfSightBlocked reports whether the endpoint crossing blocks
// line of sight. It returns false when no boundary is registered.
IsBoundaryLineOfSightBlocked(from, to Position) bool
}
BoundaryAwareRoom is an optional Room capability for registering and querying barriers between adjacent grid positions. It is separate from Room so legacy Room implementations and callers remain compatible.
type Circle ¶
Circle represents a circular area
func (Circle) Intersects ¶
Intersects checks if this circle intersects with another circle
type Connection ¶
type Connection interface {
core.Entity
// GetConnectionType returns the connection type
GetConnectionType() ConnectionType
// GetFromRoom returns the source room ID
GetFromRoom() string
// GetToRoom returns the destination room ID
GetToRoom() string
// IsPassable checks if entities can currently traverse this connection
IsPassable(entity core.Entity) bool
// GetTraversalCost returns the cost to traverse this connection
GetTraversalCost(entity core.Entity) float64
// IsReversible returns true if the connection works both ways
IsReversible() bool
// GetRequirements returns any requirements for using this connection
GetRequirements() []string
}
Connection represents a logical link between two rooms (ADR-0015: Abstract Connections)
type ConnectionAddedEvent ¶ added in v0.1.1
type ConnectionAddedEvent struct {
OrchestratorID string `json:"orchestrator_id"`
ConnectionID string `json:"connection_id"`
FromRoom string `json:"from_room"`
ToRoom string `json:"to_room"`
ConnectionType string `json:"connection_type"`
AddedAt time.Time `json:"added_at"`
}
ConnectionAddedEvent contains data for connection addition events
type ConnectionID ¶
type ConnectionID string
ConnectionID is a unique identifier for a connection
func NewConnectionID ¶
func NewConnectionID() ConnectionID
NewConnectionID generates a new unique connection identifier
func (ConnectionID) String ¶
func (id ConnectionID) String() string
type ConnectionRemovedEvent ¶ added in v0.1.1
type ConnectionRemovedEvent struct {
OrchestratorID string `json:"orchestrator_id"`
ConnectionID string `json:"connection_id"`
Reason string `json:"reason,omitempty"`
RemovedAt time.Time `json:"removed_at"`
}
ConnectionRemovedEvent contains data for connection removal events
type ConnectionType ¶
type ConnectionType string
ConnectionType represents different types of connections between rooms
const ( ConnectionTypeDoor ConnectionType = "door" // Standard doorway connection ConnectionTypeStairs ConnectionType = "stairs" // Stairway between different levels ConnectionTypePassage ConnectionType = "passage" // Corridor or hallway connection ConnectionTypePortal ConnectionType = "portal" // Magical or teleportation connection ConnectionTypeBridge ConnectionType = "bridge" // Bridge spanning a gap or obstacle ConnectionTypeTunnel ConnectionType = "tunnel" // Underground or enclosed tunnel )
Connection type constants define the various ways rooms can be linked
type CubeCoordinate ¶
CubeCoordinate represents a position in cube coordinate system (for hex grids) In hex grids, cube coordinates simplify distance and neighbor calculations
func OffsetCoordinateToCube ¶
func OffsetCoordinateToCube(pos Position) CubeCoordinate
OffsetCoordinateToCube converts offset coordinate to cube coordinate Uses pointy-top orientation by default. Use OffsetCoordinateToCubeWithOrientation for flat-top.
func OffsetCoordinateToCubeWithOrientation ¶ added in v0.2.0
func OffsetCoordinateToCubeWithOrientation(pos Position, orientation HexOrientation) CubeCoordinate
OffsetCoordinateToCubeWithOrientation converts offset coordinate to cube coordinate using the specified hex orientation
func (CubeCoordinate) Add ¶
func (c CubeCoordinate) Add(other CubeCoordinate) CubeCoordinate
Add adds another cube coordinate to this one
func (CubeCoordinate) Distance ¶
func (c CubeCoordinate) Distance(other CubeCoordinate) int
Distance calculates the hex distance between two cube coordinates This is specific to hex grids and uses cube coordinate math
func (CubeCoordinate) Equals ¶
func (c CubeCoordinate) Equals(other CubeCoordinate) bool
Equals checks if two cube coordinates are equal
func (CubeCoordinate) GetNeighbors ¶
func (c CubeCoordinate) GetNeighbors() []CubeCoordinate
GetNeighbors returns all 6 neighboring cube coordinates
func (CubeCoordinate) IsValid ¶
func (c CubeCoordinate) IsValid() bool
IsValid checks whether the cube coordinate is valid (x + y + z == 0). It compares exact unsigned magnitudes by sign instead of adding native ints, so valid and invalid coordinates remain distinguishable at int extremes.
func (CubeCoordinate) Scale ¶
func (c CubeCoordinate) Scale(factor int) CubeCoordinate
Scale scales the cube coordinate by a factor
func (CubeCoordinate) String ¶
func (c CubeCoordinate) String() string
String returns a string representation of the cube coordinate
func (CubeCoordinate) Subtract ¶
func (c CubeCoordinate) Subtract(other CubeCoordinate) CubeCoordinate
Subtract subtracts another cube coordinate from this one
func (CubeCoordinate) ToOffsetCoordinate ¶
func (c CubeCoordinate) ToOffsetCoordinate() Position
ToOffsetCoordinate converts cube coordinate to offset coordinate (for display) Uses pointy-top orientation by default. Use ToOffsetCoordinateWithOrientation for flat-top.
func (CubeCoordinate) ToOffsetCoordinateWithOrientation ¶ added in v0.2.0
func (c CubeCoordinate) ToOffsetCoordinateWithOrientation(orientation HexOrientation) Position
ToOffsetCoordinateWithOrientation converts cube coordinate to offset coordinate using the specified hex orientation
type Dimensions ¶
Dimensions represents the size of a spatial area
func (Dimensions) Area ¶
func (d Dimensions) Area() float64
Area calculates the area of the dimensions
func (Dimensions) Contains ¶
func (d Dimensions) Contains(pos Position) bool
Contains checks if a position is within the dimensions (assuming origin at 0,0)
func (Dimensions) String ¶
func (d Dimensions) String() string
String returns a string representation of the dimensions
type EntityCubePlacement ¶ added in v0.3.0
type EntityCubePlacement struct {
// EntityID is the unique identifier of the entity
EntityID string `json:"entity_id"`
// EntityType is the type of the entity (e.g., "character", "monster", "object")
EntityType string `json:"entity_type"`
// CubePosition is where the entity is placed in the room (cube coordinates)
CubePosition CubeCoordinate `json:"cube_position"`
// Size is how many grid spaces the entity occupies (default 1)
Size int `json:"size,omitempty"`
// BlocksMovement indicates if this entity blocks movement through its space
BlocksMovement bool `json:"blocks_movement"`
// BlocksLineOfSight indicates if this entity blocks line of sight
BlocksLineOfSight bool `json:"blocks_line_of_sight"`
}
EntityCubePlacement represents an entity's position using cube coordinates. Used for hex grids where cube coordinates (x, y, z where x+y+z=0) are the native format.
type EntityFilter ¶
type EntityFilter interface {
// Matches returns true if the entity matches the filter
Matches(entity core.Entity) bool
}
EntityFilter defines filtering criteria for spatial queries
func CreateCharacterFilter ¶
func CreateCharacterFilter() EntityFilter
CreateCharacterFilter creates a filter for character entities
func CreateCombatantFilter ¶
func CreateCombatantFilter() EntityFilter
CreateCombatantFilter creates a filter for combatant entities (characters + monsters)
func CreateExcludeFilter ¶
func CreateExcludeFilter(excludeIDs ...string) EntityFilter
CreateExcludeFilter creates a filter that excludes specific entity IDs
func CreateIncludeFilter ¶
func CreateIncludeFilter(includeIDs ...string) EntityFilter
CreateIncludeFilter creates a filter that includes only specific entity IDs
func CreateItemFilter ¶
func CreateItemFilter() EntityFilter
CreateItemFilter creates a filter for item entities
func CreateMonsterFilter ¶
func CreateMonsterFilter() EntityFilter
CreateMonsterFilter creates a filter for monster entities
type EntityMovedEvent ¶ added in v0.1.1
type EntityMovedEvent struct {
EntityID string `json:"entity_id"`
FromPosition Position `json:"from_position"`
ToPosition Position `json:"to_position"`
FromCubePosition *CubeCoordinate `json:"from_cube_position,omitempty"` // Only set for hex grids
ToCubePosition *CubeCoordinate `json:"to_cube_position,omitempty"` // Only set for hex grids
RoomID string `json:"room_id"`
MovementType string `json:"movement_type"` // "normal", "teleport", "forced"
}
EntityMovedEvent contains data for entity movement events
type EntityPlacedEvent ¶ added in v0.1.1
type EntityPlacedEvent struct {
EntityID string `json:"entity_id"`
Position Position `json:"position"`
CubePosition *CubeCoordinate `json:"cube_position,omitempty"` // Only set for hex grids
RoomID string `json:"room_id"`
GridType string `json:"grid_type"` // "square", "hex", "gridless"
}
EntityPlacedEvent contains data for entity placement events
type EntityPlacement ¶
type EntityPlacement struct {
// EntityID is the unique identifier of the entity
EntityID string `json:"entity_id"`
// EntityType is the type of the entity (e.g., "character", "monster", "object")
EntityType string `json:"entity_type"`
// Position is where the entity is placed in the room (offset coordinates)
Position Position `json:"position"`
// Size is how many grid spaces the entity occupies (default 1)
Size int `json:"size,omitempty"`
// BlocksMovement indicates if this entity blocks movement through its space
BlocksMovement bool `json:"blocks_movement"`
// BlocksLineOfSight indicates if this entity blocks line of sight
BlocksLineOfSight bool `json:"blocks_line_of_sight"`
}
EntityPlacement represents an entity's position and spatial properties in a room. Used for square and gridless grids that use offset coordinates.
type EntityRemovedEvent ¶ added in v0.1.1
type EntityRemovedEvent struct {
EntityID string `json:"entity_id"`
Position Position `json:"position"`
RoomID string `json:"room_id"`
RemovalType string `json:"removal_type"` // "normal", "destroyed", "teleported"
}
EntityRemovedEvent contains data for entity removal events
type EntityRoomTransitionEvent ¶ added in v0.1.1
type EntityRoomTransitionEvent struct {
EntityID string `json:"entity_id"`
FromRoom string `json:"from_room"`
ToRoom string `json:"to_room"`
Reason string `json:"reason,omitempty"`
Timestamp time.Time `json:"timestamp"`
}
EntityRoomTransitionEvent contains data for entity room transition events
type EntityTransitionBeganEvent ¶ added in v0.1.1
type EntityTransitionBeganEvent struct {
EntityID string `json:"entity_id"`
FromRoom string `json:"from_room"`
ToRoom string `json:"to_room"`
ConnectionID string `json:"connection_id,omitempty"`
TransitionType string `json:"transition_type"` // "door", "stairs", "portal", etc.
BeganAt time.Time `json:"began_at"`
}
EntityTransitionBeganEvent contains data for entity transition start events
type EntityTransitionEndedEvent ¶ added in v0.1.1
type EntityTransitionEndedEvent struct {
EntityID string `json:"entity_id"`
FromRoom string `json:"from_room"`
ToRoom string `json:"to_room"`
ConnectionID string `json:"connection_id,omitempty"`
TransitionType string `json:"transition_type"`
Success bool `json:"success"`
EndedAt time.Time `json:"ended_at"`
}
EntityTransitionEndedEvent contains data for entity transition completion events
type EventBusIntegration ¶
type EventBusIntegration interface {
// SetEventBus sets the event bus for the spatial module
SetEventBus(bus events.EventBus)
// GetEventBus returns the current event bus
GetEventBus() events.EventBus
}
EventBusIntegration defines how the spatial module integrates with the event bus
type Grid ¶
type Grid interface {
// GetShape returns the grid type
GetShape() GridShape
// IsValidPosition checks if a position is valid within the grid
IsValidPosition(pos Position) bool
// GetDimensions returns the grid dimensions
GetDimensions() Dimensions
// Distance calculates the distance between two positions
Distance(from, to Position) float64
// GetNeighbors returns all adjacent positions
GetNeighbors(pos Position) []Position
// IsAdjacent checks if two positions are adjacent
IsAdjacent(pos1, pos2 Position) bool
// GetLineOfSight returns positions along the line of sight
GetLineOfSight(from, to Position) []Position
// GetPositionsInRange returns all positions within a given range
GetPositionsInRange(center Position, radius float64) []Position
}
Grid defines the interface for all grid systems
type GridShape ¶
type GridShape int
GridShape represents the type of grid system
const ( // GridShapeSquare represents a square grid system with D&D 5e distance rules GridShapeSquare GridShape = iota // GridShapeHex represents a hexagonal grid system using cube coordinates GridShapeHex // GridShapeGridless represents a gridless system for theater-of-mind play GridShapeGridless )
type GridlessConfig ¶
GridlessConfig holds configuration for creating a gridless room
type GridlessRoom ¶
type GridlessRoom struct {
// contains filtered or unexported fields
}
GridlessRoom implements a gridless spatial system for theater-of-mind play Uses Euclidean distance and allows approximate positioning
func NewGridlessRoom ¶
func NewGridlessRoom(config GridlessConfig) *GridlessRoom
NewGridlessRoom creates a new gridless room with the given dimensions
func (*GridlessRoom) Distance ¶
func (gr *GridlessRoom) Distance(from, to Position) float64
Distance calculates the Euclidean distance between two positions This is the true geometric distance, not constrained by grid
func (*GridlessRoom) GetDimensions ¶
func (gr *GridlessRoom) GetDimensions() Dimensions
GetDimensions returns the room dimensions
func (*GridlessRoom) GetLineOfSight ¶
func (gr *GridlessRoom) GetLineOfSight(from, to Position) []Position
GetLineOfSight returns positions along the line of sight Since there's no grid, we sample points along the line
func (*GridlessRoom) GetNearestPosition ¶
func (gr *GridlessRoom) GetNearestPosition(pos Position) Position
GetNearestPosition returns the nearest valid position to the given position Useful for "snapping" entities to valid positions
func (*GridlessRoom) GetNeighbors ¶
func (gr *GridlessRoom) GetNeighbors(pos Position) []Position
GetNeighbors returns positions in a circle around the given position Since there's no grid, we return positions at various angles
func (*GridlessRoom) GetPositionsInArc ¶
func (gr *GridlessRoom) GetPositionsInArc(center Position, radius float64, startAngle, endAngle float64) []Position
GetPositionsInArc returns positions within an arc (portion of a circle) This is useful for gridless rooms where you want spell effects in arcs
func (*GridlessRoom) GetPositionsInCircle ¶
func (gr *GridlessRoom) GetPositionsInCircle(circle Circle) []Position
GetPositionsInCircle returns positions within a circular area
func (*GridlessRoom) GetPositionsInCone ¶
func (gr *GridlessRoom) GetPositionsInCone( origin Position, direction Position, length float64, angle float64, ) []Position
GetPositionsInCone returns positions within a cone shape
func (*GridlessRoom) GetPositionsInLine ¶
func (gr *GridlessRoom) GetPositionsInLine(from, to Position) []Position
GetPositionsInLine returns positions along a line
func (*GridlessRoom) GetPositionsInRange ¶
func (gr *GridlessRoom) GetPositionsInRange(center Position, radius float64) []Position
GetPositionsInRange returns all positions within range Since there's no grid, we sample in a circular pattern
func (*GridlessRoom) GetPositionsInRectangle ¶
func (gr *GridlessRoom) GetPositionsInRectangle(rect Rectangle) []Position
GetPositionsInRectangle returns positions within a rectangular area
func (*GridlessRoom) GetShape ¶
func (gr *GridlessRoom) GetShape() GridShape
GetShape returns the grid shape type
func (*GridlessRoom) IsAdjacent ¶
func (gr *GridlessRoom) IsAdjacent(pos1, pos2 Position) bool
IsAdjacent checks if two positions are adjacent (within distance 1)
func (*GridlessRoom) IsValidPosition ¶
func (gr *GridlessRoom) IsValidPosition(pos Position) bool
IsValidPosition checks if a position is within the room bounds In gridless rooms, any position within the dimensions is valid
type HexGrid ¶
type HexGrid struct {
// contains filtered or unexported fields
}
HexGrid implements a hexagonal grid system using cube coordinates
func NewHexGrid ¶
func NewHexGrid(config HexGridConfig) *HexGrid
NewHexGrid creates a new hex grid with the given dimensions Defaults to pointy-top orientation for D&D 5e compatibility
func (*HexGrid) CubeToOffset ¶
func (hg *HexGrid) CubeToOffset(cube CubeCoordinate) Position
CubeToOffset converts a cube coordinate to offset coordinate using this grid's orientation
func (*HexGrid) Distance ¶
Distance calculates the distance between two positions using hex grid rules Converts to cube coordinates and uses hex distance formula
func (*HexGrid) GetCubeNeighbors ¶
func (hg *HexGrid) GetCubeNeighbors(pos Position) []CubeCoordinate
GetCubeNeighbors returns the 6 cube coordinate neighbors of a position
func (*HexGrid) GetDimensions ¶
func (hg *HexGrid) GetDimensions() Dimensions
GetDimensions returns the grid dimensions
func (*HexGrid) GetHexRing ¶
GetHexRing returns positions forming a ring at a specific distance from center This is a hex-specific function that's useful for spell effects
func (*HexGrid) GetHexSpiral ¶
GetHexSpiral returns positions in a spiral pattern from center outward Useful for area effects that expand outward
func (*HexGrid) GetLineOfSight ¶
GetLineOfSight returns positions along the line of sight between two positions Uses cube coordinate lerp for hex line drawing
func (*HexGrid) GetNeighbors ¶
GetNeighbors returns all 6 adjacent positions in hex grid
func (*HexGrid) GetOrientation ¶
func (hg *HexGrid) GetOrientation() HexOrientation
GetOrientation returns the hex grid orientation (pointy-top or flat-top)
func (*HexGrid) GetPositionsInCircle ¶
GetPositionsInCircle returns all positions within a circular area using hex distance
func (*HexGrid) GetPositionsInCone ¶
func (hg *HexGrid) GetPositionsInCone(origin Position, direction Position, length float64, angle float64) []Position
GetPositionsInCone returns positions within a cone shape This is more complex for hex grids due to the 6-sided nature
func (*HexGrid) GetPositionsInLine ¶
GetPositionsInLine returns positions along a line from start to end
func (*HexGrid) GetPositionsInRange ¶
GetPositionsInRange returns all positions within a given range using hex distance
func (*HexGrid) GetPositionsInRectangle ¶
GetPositionsInRectangle returns all positions within a rectangular area Note: This is approximate for hex grids since rectangles don't align perfectly with hex geometry
func (*HexGrid) IsAdjacent ¶
IsAdjacent checks if two positions are adjacent (within 1 hex)
func (*HexGrid) IsPointyTop ¶ added in v0.2.0
IsPointyTop returns true if the grid uses pointy-top orientation
func (*HexGrid) IsValidPosition ¶
IsValidPosition checks if a position is valid within the grid bounds
func (*HexGrid) OffsetToCube ¶
func (hg *HexGrid) OffsetToCube(pos Position) CubeCoordinate
OffsetToCube converts an offset coordinate to cube coordinate using this grid's orientation
type HexGridConfig ¶
type HexGridConfig struct {
Width float64
Height float64
PointyTop bool // Deprecated: use Orientation instead. true for pointy-top, false for flat-top
Orientation HexOrientation // The hex orientation (pointy-top or flat-top)
}
HexGridConfig holds configuration for creating a hex grid
type HexOrientation ¶ added in v0.2.0
type HexOrientation int
HexOrientation represents the orientation of a hexagonal grid
const ( // HexOrientationPointyTop is the default orientation where hexes have a pointed top // This is the standard D&D 5e hex grid orientation HexOrientationPointyTop HexOrientation = iota // HexOrientationFlatTop is an alternative orientation where hexes have a flat top HexOrientationFlatTop )
func (HexOrientation) String ¶ added in v0.2.0
func (o HexOrientation) String() string
String returns the string representation of the hex orientation
type LayoutChangedEvent ¶ added in v0.1.1
type LayoutChangedEvent struct {
OrchestratorID string `json:"orchestrator_id"`
OldLayout string `json:"old_layout,omitempty"`
NewLayout string `json:"new_layout"`
ChangedAt time.Time `json:"changed_at"`
}
LayoutChangedEvent contains data for orchestrator layout change events
type LayoutMetrics ¶
type LayoutMetrics struct {
TotalRooms int `json:"total_rooms"`
TotalConnections int `json:"total_connections"`
AverageDistance float64 `json:"average_distance"`
MaxDistance float64 `json:"max_distance"`
Connectivity float64 `json:"connectivity"` // connections per room
RoomPositions map[string]Position `json:"room_positions"`
LayoutType LayoutType `json:"layout_type"`
}
LayoutMetrics contains information about the spatial arrangement
type LayoutOrchestrator ¶
type LayoutOrchestrator interface {
// ArrangeRooms arranges rooms according to the layout pattern
ArrangeRooms(rooms map[string]Room, layout LayoutType) error
// CalculateRoomPositions calculates optimal positions for rooms
CalculateRoomPositions(rooms map[string]Room, connections []Connection) map[string]Position
// ValidateLayout checks if a layout is structurally sound
ValidateLayout(rooms map[string]Room, connections []Connection) error
// GetLayoutMetrics returns metrics about the current layout
GetLayoutMetrics() LayoutMetrics
}
LayoutOrchestrator handles spatial arrangement of multiple rooms
type LayoutType ¶
type LayoutType string
LayoutType represents different arrangement patterns for multiple rooms
const ( LayoutTypeTower LayoutType = "tower" // Vertical stacking arrangement LayoutTypeBranching LayoutType = "branching" // Hub and spoke arrangement LayoutTypeGrid LayoutType = "grid" // 2D grid arrangement LayoutTypeOrganic LayoutType = "organic" // Irregular organic connections )
Layout type constants define how multiple rooms can be spatially arranged
type OrchestratorID ¶
type OrchestratorID string
OrchestratorID is a unique identifier for an orchestrator
func NewOrchestratorID ¶
func NewOrchestratorID() OrchestratorID
NewOrchestratorID generates a new unique orchestrator identifier
func (OrchestratorID) String ¶
func (id OrchestratorID) String() string
type PathFinder ¶ added in v0.4.0
type PathFinder interface {
// FindPath returns a path from start to goal avoiding blocked hexes.
// Returns the path excluding start, including goal.
// Returns empty slice if no path exists or start == goal.
FindPath(start, goal CubeCoordinate, blocked map[CubeCoordinate]bool) []CubeCoordinate
}
PathFinder finds paths between hex positions avoiding obstacles. Implementations can use different algorithms (A*, Dijkstra, weighted, etc.)
type Placeable ¶
type Placeable interface {
core.Entity
// GetSize returns the size of the entity (for multi-space entities)
GetSize() int
// BlocksMovement returns true if the entity blocks movement
BlocksMovement() bool
// BlocksLineOfSight returns true if the entity blocks line of sight
BlocksLineOfSight() bool
}
Placeable defines the interface for entities that can be placed spatially
type PlaceableData ¶
type PlaceableData struct {
// contains filtered or unexported fields
}
PlaceableData is a minimal implementation of Placeable for spatial queries. It contains just enough data to support movement and line of sight calculations.
func (*PlaceableData) BlocksLineOfSight ¶
func (p *PlaceableData) BlocksLineOfSight() bool
BlocksLineOfSight returns true if the entity blocks line of sight
func (*PlaceableData) BlocksMovement ¶
func (p *PlaceableData) BlocksMovement() bool
BlocksMovement returns true if the entity blocks movement
func (*PlaceableData) GetID ¶
func (p *PlaceableData) GetID() string
GetID returns the entity's unique identifier
func (*PlaceableData) GetSize ¶
func (p *PlaceableData) GetSize() int
GetSize returns the size of the entity
func (*PlaceableData) GetType ¶
func (p *PlaceableData) GetType() core.EntityType
GetType returns the entity's type
type Position ¶
Position represents a spatial position in 2D space NOTE: Distance calculations are grid-dependent and handled by Grid implementations
func CanonicalBoundaryRay ¶ added in v0.6.0
CanonicalBoundaryRay returns the one deterministic grid ray for an unordered endpoint pair, oriented from from toward to. It derives the ray once from lexicographically ordered endpoints, then reverses it when the caller requested the opposite direction. Boundary traversal therefore crosses identical physical edges in both directions while callers retain their requested path direction.
func (Position) Normalize ¶
Normalize returns a normalized version of the position (for vector math)
type Query ¶
type Query interface {
// GetType returns the query type
GetType() string
// GetRoom returns the room being queried
GetRoom() Room
// GetCenter returns the center position for the query
GetCenter() Position
// GetRadius returns the radius for range-based queries
GetRadius() float64
// GetFilter returns any entity filter for the query
GetFilter() EntityFilter
}
Query represents a spatial query
type QueryEntitiesInRangeData ¶
type QueryEntitiesInRangeData struct {
Center Position `json:"center"`
Radius float64 `json:"radius"`
RoomID string `json:"room_id"`
Filter EntityFilter `json:"filter,omitempty"`
Results []core.Entity `json:"results,omitempty"`
Error error `json:"error,omitempty"`
}
QueryEntitiesInRangeData contains data for entity range queries
type QueryHandler ¶
type QueryHandler interface {
// ProcessQuery processes a spatial query and returns results
ProcessQuery(query Query) (QueryResult, error)
}
QueryHandler defines the interface for spatial query processing
type QueryLineOfSightData ¶
type QueryLineOfSightData struct {
From Position `json:"from"`
To Position `json:"to"`
RoomID string `json:"room_id"`
Results []Position `json:"results,omitempty"`
Blocked bool `json:"blocked,omitempty"`
Error error `json:"error,omitempty"`
}
QueryLineOfSightData contains data for line of sight queries
type QueryMovementData ¶
type QueryMovementData struct {
Entity core.Entity `json:"entity"`
From Position `json:"from"`
To Position `json:"to"`
RoomID string `json:"room_id"`
Valid bool `json:"valid,omitempty"`
Path []Position `json:"path,omitempty"`
Distance float64 `json:"distance,omitempty"`
Error error `json:"error,omitempty"`
}
QueryMovementData contains data for movement queries
type QueryPlacementData ¶
type QueryPlacementData struct {
Entity core.Entity `json:"entity"`
Position Position `json:"position"`
RoomID string `json:"room_id"`
Valid bool `json:"valid,omitempty"`
Error error `json:"error,omitempty"`
}
QueryPlacementData contains data for placement queries
type QueryPositionsInRangeData ¶
type QueryPositionsInRangeData struct {
Center Position `json:"center"`
Radius float64 `json:"radius"`
RoomID string `json:"room_id"`
Results []Position `json:"results,omitempty"`
Error error `json:"error,omitempty"`
}
QueryPositionsInRangeData contains data for position range queries
type QueryResult ¶
type QueryResult interface {
// GetPositions returns positions that match the query
GetPositions() []Position
// GetEntities returns entities that match the query
GetEntities() []core.Entity
// GetDistances returns distances for each result
GetDistances() map[string]float64
}
QueryResult represents the result of a spatial query
type QueryUtils ¶
type QueryUtils struct {
// contains filtered or unexported fields
}
QueryUtils provides convenient methods for performing spatial queries
func NewQueryUtils ¶
func NewQueryUtils(queryHandler *SpatialQueryHandler) *QueryUtils
NewQueryUtils creates a new query utilities instance
func (*QueryUtils) QueryEntitiesInRange ¶
func (q *QueryUtils) QueryEntitiesInRange( ctx context.Context, center Position, radius float64, roomID string, filter EntityFilter, ) ([]core.Entity, error)
QueryEntitiesInRange performs an entities-in-range query directly through the query handler
func (*QueryUtils) QueryLineOfSight ¶
func (q *QueryUtils) QueryLineOfSight(ctx context.Context, from, to Position, roomID string) ([]Position, bool, error)
QueryLineOfSight performs a line-of-sight query directly through the query handler
func (*QueryUtils) QueryMovement ¶
func (q *QueryUtils) QueryMovement( ctx context.Context, entity core.Entity, from, to Position, roomID string, ) (bool, []Position, float64, error)
QueryMovement performs a movement query directly through the query handler
func (*QueryUtils) QueryPlacement ¶
func (q *QueryUtils) QueryPlacement( ctx context.Context, entity core.Entity, position Position, roomID string, ) (bool, error)
QueryPlacement performs a placement query directly through the query handler
func (*QueryUtils) QueryPositionsInRange ¶
func (q *QueryUtils) QueryPositionsInRange( ctx context.Context, center Position, radius float64, roomID string, ) ([]Position, error)
QueryPositionsInRange performs a positions-in-range query directly through the query handler
type Rectangle ¶
type Rectangle struct {
Position Position `json:"position"`
Dimensions Dimensions `json:"dimensions"`
}
Rectangle represents a rectangular area
func (Rectangle) Intersects ¶
Intersects checks if this rectangle intersects with another rectangle
type Room ¶
type Room interface {
core.Entity
// GetGrid returns the grid system used by this room
GetGrid() Grid
// PlaceEntity places an entity at a specific position
PlaceEntity(entity core.Entity, pos Position) error
// MoveEntity moves an entity to a new position
MoveEntity(entityID string, newPos Position) error
// RemoveEntity removes an entity from the room
RemoveEntity(entityID string) error
// GetEntitiesAt returns all entities at a specific position
GetEntitiesAt(pos Position) []core.Entity
// GetEntityPosition returns the position of an entity
GetEntityPosition(entityID string) (Position, bool)
// GetAllEntities returns all entities in the room
GetAllEntities() map[string]core.Entity
// GetEntitiesInRange returns entities within a given range
GetEntitiesInRange(center Position, radius float64) []core.Entity
// IsPositionOccupied checks if a position is occupied
IsPositionOccupied(pos Position) bool
// CanPlaceEntity checks if an entity can be placed at a position
CanPlaceEntity(entity core.Entity, pos Position) bool
// GetPositionsInRange returns all positions within a given range
GetPositionsInRange(center Position, radius float64) []Position
// GetLineOfSight returns positions along the line of sight
GetLineOfSight(from, to Position) []Position
// IsLineOfSightBlocked checks if line of sight is blocked by entities
IsLineOfSightBlocked(from, to Position) bool
}
Room defines the interface for spatial containers
type RoomAddedEvent ¶ added in v0.1.1
type RoomAddedEvent struct {
OrchestratorID string `json:"orchestrator_id"`
RoomID string `json:"room_id"`
RoomType string `json:"room_type,omitempty"`
AddedAt time.Time `json:"added_at"`
}
RoomAddedEvent contains data for room addition to orchestrator events
type RoomCreatedEvent ¶ added in v0.1.1
type RoomCreatedEvent struct {
RoomID string `json:"room_id"`
RoomType string `json:"room_type"`
GridType string `json:"grid_type"`
Width int `json:"width"`
Height int `json:"height"`
CreationTime time.Time `json:"creation_time"`
}
RoomCreatedEvent contains data for room creation events
type RoomData ¶
type RoomData struct {
// ID is the unique identifier for the room
ID string `json:"id"`
// Type categorizes the room (e.g., "dungeon", "tavern", "outdoor")
Type string `json:"type"`
// Width defines the horizontal size of the room
Width int `json:"width"`
// Height defines the vertical size of the room
Height int `json:"height"`
// GridType specifies the grid system: "square", "hex", or "gridless"
GridType string `json:"grid_type"`
// HexFlatTop specifies hex grid orientation
// Only used when GridType is "hex"
// false = pointy-top (default), true = flat-top
HexFlatTop bool `json:"hex_flat_top,omitempty"`
// Entities contains positioned entities within the room using offset coordinates.
// Used for square and gridless grids.
// Map of entity ID to their position and data.
Entities map[string]EntityPlacement `json:"entities,omitempty"`
// CubeEntities contains positioned entities within the room using cube coordinates.
// Used for hex grids where cube coordinates are the native format.
// Map of entity ID to their position and data.
CubeEntities map[string]EntityCubePlacement `json:"cube_entities,omitempty"`
}
RoomData contains all information needed to persist and reconstruct a room. This follows the established data pattern for serialization and loading.
type RoomOrchestrator ¶
type RoomOrchestrator interface {
core.Entity
EventBusIntegration
// AddRoom adds a room to the orchestrator
AddRoom(room Room) error
// RemoveRoom removes a room from the orchestrator
RemoveRoom(roomID string) error
// GetRoom retrieves a room by ID
GetRoom(roomID string) (Room, bool)
// GetAllRooms returns all managed rooms
GetAllRooms() map[string]Room
// AddConnection creates a connection between two rooms
AddConnection(connection Connection) error
// RemoveConnection removes a connection
RemoveConnection(connectionID string) error
// GetConnection retrieves a connection by ID
GetConnection(connectionID string) (Connection, bool)
// GetRoomConnections returns all connections for a specific room
GetRoomConnections(roomID string) []Connection
// GetAllConnections returns all connections
GetAllConnections() map[string]Connection
// MoveEntityBetweenRooms moves an entity from one room to another
MoveEntityBetweenRooms(entityID, fromRoom, toRoom, connectionID string) error
// CanMoveEntityBetweenRooms checks if entity movement is possible
CanMoveEntityBetweenRooms(entityID, fromRoom, toRoom, connectionID string) bool
// GetEntityRoom returns which room contains the entity
GetEntityRoom(entityID string) (string, bool)
// FindPath finds a path between rooms using connections
FindPath(fromRoom, toRoom string, entity core.Entity) ([]string, error)
// GetLayout returns the current layout pattern
GetLayout() LayoutType
// SetLayout configures the arrangement pattern
SetLayout(layout LayoutType) error
}
RoomOrchestrator manages multiple rooms and their connections
type RoomRemovedEvent ¶ added in v0.1.1
type RoomRemovedEvent struct {
OrchestratorID string `json:"orchestrator_id"`
RoomID string `json:"room_id"`
Reason string `json:"reason,omitempty"`
RemovedAt time.Time `json:"removed_at"`
}
RoomRemovedEvent contains data for room removal from orchestrator events
type SimpleEntityFilter ¶
type SimpleEntityFilter struct {
EntityTypes []string `json:"entity_types,omitempty"`
EntityIDs []string `json:"entity_ids,omitempty"`
ExcludeIDs []string `json:"exclude_ids,omitempty"`
}
SimpleEntityFilter implements basic entity filtering
func NewSimpleEntityFilter ¶
func NewSimpleEntityFilter() *SimpleEntityFilter
NewSimpleEntityFilter creates a new simple entity filter
func (*SimpleEntityFilter) Matches ¶
func (f *SimpleEntityFilter) Matches(entity core.Entity) bool
Matches checks if an entity matches the filter criteria
func (*SimpleEntityFilter) WithEntityIDs ¶
func (f *SimpleEntityFilter) WithEntityIDs(ids ...string) *SimpleEntityFilter
WithEntityIDs adds entity ID filtering
func (*SimpleEntityFilter) WithEntityTypes ¶
func (f *SimpleEntityFilter) WithEntityTypes(types ...string) *SimpleEntityFilter
WithEntityTypes adds entity type filtering
func (*SimpleEntityFilter) WithExcludeIDs ¶
func (f *SimpleEntityFilter) WithExcludeIDs(ids ...string) *SimpleEntityFilter
WithExcludeIDs adds entity ID exclusion
type SimplePathFinder ¶ added in v0.4.0
type SimplePathFinder struct{}
SimplePathFinder uses A* algorithm with uniform movement cost. It finds the shortest path around obstacles using hex distance as heuristic.
func NewSimplePathFinder ¶ added in v0.4.0
func NewSimplePathFinder() *SimplePathFinder
NewSimplePathFinder creates a new A* pathfinder
func (*SimplePathFinder) FindPath ¶ added in v0.4.0
func (p *SimplePathFinder) FindPath(start, goal CubeCoordinate, blocked map[CubeCoordinate]bool) []CubeCoordinate
FindPath implements PathFinder using A* algorithm. Uses hex distance as heuristic (admissible - never overestimates).
func (*SimplePathFinder) FindPathWithTraversal ¶ added in v0.6.0
func (p *SimplePathFinder) FindPathWithTraversal( start, goal CubeCoordinate, blocked map[CubeCoordinate]bool, canTraverse TraversalPredicate, limit TraversalSearchLimit, ) []CubeCoordinate
FindPathWithTraversal uses A* while also requiring each adjacent step to be permitted by canTraverse. Traversal-aware searches require an explicit limit because a predicate can seal an otherwise-unblocked goal on the unbounded hex plane. It preserves legacy FindPath behavior by leaving that API unbounded.
type SpatialQueryHandler ¶
type SpatialQueryHandler struct {
// contains filtered or unexported fields
}
SpatialQueryHandler handles spatial query events
func NewSpatialQueryHandler ¶
func NewSpatialQueryHandler() *SpatialQueryHandler
NewSpatialQueryHandler creates a new spatial query handler
func (*SpatialQueryHandler) HandleQuery ¶
func (h *SpatialQueryHandler) HandleQuery(ctx context.Context, query interface{}) (interface{}, error)
HandleQuery processes spatial queries
func (*SpatialQueryHandler) RegisterRoom ¶
func (h *SpatialQueryHandler) RegisterRoom(room Room)
RegisterRoom registers a room with the query handler
func (*SpatialQueryHandler) UnregisterRoom ¶
func (h *SpatialQueryHandler) UnregisterRoom(roomID string)
UnregisterRoom removes a room from the query handler
type SquareGrid ¶
type SquareGrid struct {
// contains filtered or unexported fields
}
SquareGrid implements a square grid system with D&D 5e distance rules
func NewSquareGrid ¶
func NewSquareGrid(config SquareGridConfig) *SquareGrid
NewSquareGrid creates a new square grid with the given dimensions
func (*SquareGrid) Distance ¶
func (sg *SquareGrid) Distance(from, to Position) float64
Distance calculates the distance between two positions using D&D 5e rules D&D 5e uses Chebyshev distance: max(|x2-x1|, |y2-y1|) This means diagonals cost the same as orthogonal movement
func (*SquareGrid) GetDimensions ¶
func (sg *SquareGrid) GetDimensions() Dimensions
GetDimensions returns the grid dimensions
func (*SquareGrid) GetLineOfSight ¶
func (sg *SquareGrid) GetLineOfSight(from, to Position) []Position
GetLineOfSight returns positions along the line of sight between two positions Uses Bresenham's line algorithm for grid-based line drawing
func (*SquareGrid) GetNeighbors ¶
func (sg *SquareGrid) GetNeighbors(pos Position) []Position
GetNeighbors returns all 8 adjacent positions (including diagonals)
func (*SquareGrid) GetPositionsInCircle ¶
func (sg *SquareGrid) GetPositionsInCircle(circle Circle) []Position
GetPositionsInCircle returns all positions within a circular area using D&D 5e distance
func (*SquareGrid) GetPositionsInCone ¶
func (sg *SquareGrid) GetPositionsInCone( origin Position, direction Position, length float64, angle float64, ) []Position
GetPositionsInCone returns positions within a cone shape This is a simplified cone implementation - games may need more sophisticated cone logic
func (*SquareGrid) GetPositionsInLine ¶
func (sg *SquareGrid) GetPositionsInLine(from, to Position) []Position
GetPositionsInLine returns positions along a line from start to end
func (*SquareGrid) GetPositionsInRange ¶
func (sg *SquareGrid) GetPositionsInRange(center Position, radius float64) []Position
GetPositionsInRange returns all positions within a given range using D&D 5e distance
func (*SquareGrid) GetPositionsInRectangle ¶
func (sg *SquareGrid) GetPositionsInRectangle(rect Rectangle) []Position
GetPositionsInRectangle returns all positions within a rectangular area
func (*SquareGrid) GetShape ¶
func (sg *SquareGrid) GetShape() GridShape
GetShape returns the grid shape type
func (*SquareGrid) IsAdjacent ¶
func (sg *SquareGrid) IsAdjacent(pos1, pos2 Position) bool
IsAdjacent checks if two positions are adjacent (within 1 square, including diagonals)
func (*SquareGrid) IsValidPosition ¶
func (sg *SquareGrid) IsValidPosition(pos Position) bool
IsValidPosition checks if a position is valid within the grid bounds
type SquareGridConfig ¶
SquareGridConfig holds configuration for creating a square grid
type Transition ¶
type Transition interface {
// GetID returns the transition ID
GetID() TransitionID
// GetEntity returns the entity being moved
GetEntity() core.Entity
// GetFromRoom returns the source room ID
GetFromRoom() string
// GetToRoom returns the destination room ID
GetToRoom() string
// GetConnection returns the connection being used
GetConnection() Connection
// GetProgress returns completion progress (0.0 to 1.0)
GetProgress() float64
// IsComplete returns true if transition is finished
IsComplete() bool
// GetStartTime returns when the transition began
GetStartTime() int64
// GetEstimatedDuration returns expected transition time
GetEstimatedDuration() int64
}
Transition represents an entity moving between rooms
type TransitionSystem ¶
type TransitionSystem interface {
// BeginTransition initiates movement between rooms
BeginTransition(entityID, fromRoom, toRoom, connectionID string) (TransitionID, error)
// CompleteTransition finalizes the movement
CompleteTransition(transitionID TransitionID) error
// CancelTransition cancels an in-progress transition
CancelTransition(transitionID TransitionID) error
// GetActiveTransitions returns all in-progress transitions
GetActiveTransitions() []Transition
// GetTransition retrieves a specific transition
GetTransition(transitionID TransitionID) (Transition, bool)
}
TransitionSystem handles entity movement between rooms
type TraversalPathFinder ¶ added in v0.6.0
type TraversalPathFinder interface {
// FindPathWithTraversal returns a path while honoring blocked cells and a
// traversal predicate. A nil predicate permits every adjacent crossing.
// Search is bounded by limit; it returns an empty slice when no route fits
// within the bound or when no route exists.
FindPathWithTraversal(
start, goal CubeCoordinate,
blocked map[CubeCoordinate]bool,
canTraverse TraversalPredicate,
limit TraversalSearchLimit,
) []CubeCoordinate
}
TraversalPathFinder is an optional extension for path finders that can consult a traversal predicate in addition to legacy blocked cells.
type TraversalPredicate ¶ added in v0.6.0
type TraversalPredicate func(from, to CubeCoordinate) bool
TraversalPredicate decides whether A* may traverse one directed adjacent pair. It must return true to permit the step from to. A predicate can model blocked crossings such as closed boundaries without converting them into blocked cells.
type TraversalSearchLimit ¶ added in v0.6.0
type TraversalSearchLimit struct {
// MaxSteps is the inclusive path-length and search-cost bound.
MaxSteps int
}
TraversalSearchLimit bounds predicate-aware searches on the otherwise unbounded hex plane. MaxSteps is the inclusive maximum number of crossings in a returned path. A non-positive limit permits no path unless start equals goal, and a limit shorter than the direct distance cannot reach the goal.
The limit is also a deterministic safety contract: A* never adds a position whose path cost exceeds MaxSteps, so a predicate that seals an unblocked goal terminates after examining a finite search area. Callers should set MaxSteps above the direct distance by enough steps for the detours their map allows.