# Room System Design

## Overview

A room system for battle maps where rooms are defined as groups of tiles, walls exist on tile borders (not as tiles), and openings are explicitly marked doorways between rooms. Tiles outside rooms are impassable void.

## Data Model

### Room (Resource)

- `id: int` — unique room identifier
- `tiles: Array[Vector2i]` — tile coordinates belonging to this room

### MapLayout (Resource)

- `rooms: Array[Room]` — all rooms on the map
- `openings: Array` — list of tile-coordinate pairs (`[Vector2i, Vector2i]`) representing bidirectional doorways between adjacent tiles in different rooms

### Derived Wall Computation

A wall exists on a tile edge when:

1. One side is a room tile and the other is void (not in any room), OR
2. The two sides belong to different rooms AND the edge is not in the openings list

### MapLayout API

- `get_walls() -> Array` — computes all wall edge segments from room and opening data
- `is_passable(from: Vector2i, to: Vector2i) -> bool` — returns whether movement is allowed between two adjacent tiles (false if wall, false if either tile is void)
- `is_tile_valid(tile: Vector2i) -> bool` — returns whether a tile belongs to any room
- `get_room_at(tile: Vector2i) -> Room` — returns the room a tile belongs to, or null

## Integration with Movement

- `CombatMap` holds a reference to the `MapLayout`
- Before allowing a unit to move from tile A to tile B, the movement system calls `MapLayout.is_passable(a, b)`
- If there is a wall on that edge (and no opening), movement is blocked
- Tiles not belonging to any room are impassable — `is_tile_valid()` returns false for void tiles
- Future pathfinding uses the same `is_passable` check as its neighbor filter

## Wall Rendering

- `CombatMap` iterates over computed wall edges from `MapLayout.get_walls()`
- Each wall edge is defined by two adjacent tile coordinates — the wall is drawn on the border between them
- Openings have no wall drawn
- Initial implementation uses simple `Line2D` segments or sprite strips on tile edges
- Can be replaced with proper art assets later

## Design Decisions

- **Rooms are the primary data, walls are derived** — single source of truth, no sync issues
- **Openings are explicit** — all room boundaries are walls by default; doorways are punched explicitly as tile-coordinate pairs
- **Openings are always bidirectional**
- **No room metadata beyond ID** — tile ownership stays tile-level per existing system
- **Void tiles are impassable** — no hallway/corridor concept; all walkable tiles belong to a room
- **Room data is independent of rendering** — clean for future map editor serialization
