The mandatory map alphabet defines the only symbols accepted before bonus map
extensions are considered. In the mandatory build, that rule is exact because
the shared bonus tile helper is linked as a no-op compatibility layer.
Mandatory alphabet
Seven symbols define the mandatory map language
Before bonus extensions, validation accepts only floor, wall, one player orientation marker, and explicit void/space cells used around irregular maps. In the mandatory build, the shared bonus tile helper is a no-op, so this alphabet stays exact.
0 Empty floor
traversable cell, no wall render, reachable by player and BFS
1 Solid wall
blocks DDA, collision, BFS traversal, and renders as textured wall
' ' Void / padding
outside-map cell; if BFS reaches it, closure validation fails
N North spawn
dir(0,-1), plane(+fov,0), then treated as floor
S South spawn
dir(0,+1), plane(-fov,0), then treated as floor
E East spawn
dir(+1,0), plane(0,+fov), then treated as floor
W West spawn
dir(-1,0), plane(0,-fov), then treated as floor
Any other character
validate_chars() rejects immediately.
error 01 behavior by subsystem Each symbol has a clear role in BFS, collision, and DDA rendering.
| Symbol | BFS | Collision | DDA render |
0 | traversable | free | floor / ceiling |
1 | solid stop | blocked | hit -> texture |
N/S/E/W | spawn start | free (= 0) | floor / ceiling (= 0) |
' ' | leak -> reject | outside map | must not be reached |
02 mandatory vs bonus Mandatory alphabet stays strict; bonus symbols are accepted only when the bonus-aware helper is replaced by the real bonus implementation.
mandatory alphabet = { 0, 1, N, S, E, W, ' ' }
unknown character = validation error
bonus extension = bonus_is_valid_map_char(...)
✓ post-validation invariant Every cell belongs to the accepted mandatory alphabet, so BFS closure can run safely.
0 for empty floor
1 for solid wall
N, S, E, W for the single player spawn and initial orientation
- space for padded or out-of-map cells
Any unknown symbol is rejected by map character validation.
Spawn symbols are used to initialize player position and camera orientation.
The grid still stores them as N/S/E/W, but movement, BFS traversal, and
rendering treat them as open floor-like cells.