feat: add requirements and technical baseline
This commit is contained in:
@@ -0,0 +1,280 @@
|
||||
# maze32 MVP
|
||||
|
||||
## 1. Product goal
|
||||
|
||||
maze32 is a local browser-based multiplayer maze race hosted by one ESP32-C6.
|
||||
Two players explore the same maze in real time, search for their own keys and
|
||||
exits, and try to leave first. Up to four observers may watch the complete
|
||||
match.
|
||||
|
||||
The MVP must produce a fair, playable match whose normal target duration is
|
||||
approximately five minutes. There is no match time limit.
|
||||
|
||||
## 2. Runtime model
|
||||
|
||||
- One ESP32-C6 runs the HTTP server, WebSocket server, maze generator, and the
|
||||
authoritative game simulation.
|
||||
- Both players and all observers use ordinary web browsers.
|
||||
- Clients send intentions such as move or drop-key; they never determine the
|
||||
result of an action locally.
|
||||
- The server validates action order, movement cooldowns, collisions, item
|
||||
ownership, visibility, victory, and draws.
|
||||
- The server must never send hidden game state to a player client. Fog of war
|
||||
is enforced when constructing the server response, not merely by hiding
|
||||
elements in the browser.
|
||||
|
||||
## 3. Roles and lobby
|
||||
|
||||
### Players
|
||||
|
||||
- Exactly two player slots exist: Player 1 and Player 2.
|
||||
- A player joins with a unique display name and receives a temporary session
|
||||
token.
|
||||
- The UI may suggest humorous available names.
|
||||
- The first player becomes the lobby owner and is the only player who may
|
||||
start the match.
|
||||
- The second player is a participant without start authority.
|
||||
- The match can start only when both player slots are occupied.
|
||||
- Refreshing the browser restores the same player, slot, position, inventory,
|
||||
and match state through the session token.
|
||||
|
||||
### Observers
|
||||
|
||||
- Up to four observers may connect without a password.
|
||||
- Observers do not consume player slots.
|
||||
- Observers are read-only: they cannot start, pause, or control a match.
|
||||
- An observer sees the entire maze without fog of war, both current player
|
||||
positions, keys and their holders, exits, compasses, vision artifacts, match
|
||||
status, connection state, and final result.
|
||||
- An observer disconnect does not pause the match.
|
||||
|
||||
### Start sequence
|
||||
|
||||
- When the lobby owner starts a ready match, both players receive the same
|
||||
`3-2-1` countdown.
|
||||
- Movement is rejected until the countdown completes.
|
||||
- Both players become active at the same authoritative server instant.
|
||||
|
||||
## 4. Maze
|
||||
|
||||
### Dimensions and representation
|
||||
|
||||
- The initial configuration is `width = 128`, `height = 64`, or 8,192 cells.
|
||||
- Width and height are runtime configuration values and must not be hard-coded
|
||||
into game logic.
|
||||
- Movement is orthogonal between cells; diagonal movement does not exist.
|
||||
- Every playable cell and required object must be reachable.
|
||||
|
||||
### Symmetry and topology
|
||||
|
||||
- Geometry uses central symmetry under a 180-degree rotation:
|
||||
`(x, y) -> (width - 1 - x, height - 1 - y)`.
|
||||
- Player 2's start, key, exit, and other fairness-relevant placements are the
|
||||
rotated counterparts of Player 1's placements.
|
||||
- The maze contains cycles, alternative routes, dead ends, and many passages
|
||||
between its conceptual halves.
|
||||
- Players can enter either half through multiple routes, but the UI must not
|
||||
identify a cell as belonging to either player.
|
||||
- The maze is not a perfect maze with only one route between points.
|
||||
|
||||
### Starts, keys, and exits
|
||||
|
||||
- Players start at opposite, rotationally symmetric entrance cells.
|
||||
- An entrance is only the starting point; it is not the player's exit.
|
||||
- Each player has one unique key and one unique exit.
|
||||
- A key opens only its matching exit, and only the owner of that key and exit
|
||||
can win through them.
|
||||
- Key and exit pairs are placed rotationally symmetrically and at equal route
|
||||
distances for both players.
|
||||
- Each key begins outside its owner's initial field of view.
|
||||
- Each exit may be at any distant valid symmetric location.
|
||||
- Map generation must make finding the key at least as challenging as the
|
||||
subsequent search for the correct exit. Exact balance thresholds are
|
||||
tunable and must be validated through generation metrics and playtesting.
|
||||
|
||||
### Landmarks and generated objects
|
||||
|
||||
- The maze contains visually distinctive landmarks to support human spatial
|
||||
memory even though explored territory is not retained.
|
||||
- Fairness-relevant landmarks and vision artifacts are generated in
|
||||
rotationally symmetric pairs.
|
||||
- The exact number and density of landmarks and artifact pairs are tunable
|
||||
balance parameters. The MVP must place more than one vision artifact.
|
||||
|
||||
## 5. Movement and player interaction
|
||||
|
||||
- One accepted input moves a player by exactly one traversable cell in one of
|
||||
four directions: up, down, left, or right.
|
||||
- Players act independently; the server does not wait for alternating or
|
||||
simultaneous turns.
|
||||
- A small server-enforced minimum interval exists between accepted moves. Its
|
||||
value is configurable for playtesting.
|
||||
- Rejected movement into a wall does not change position and is not a
|
||||
successful move.
|
||||
- Players do not block each other and may occupy the same cell.
|
||||
- A meeting occurs when both players occupy the same cell.
|
||||
- There are no attacks, health, damage, or other combat mechanics in MVP.
|
||||
|
||||
Browser controls must support:
|
||||
|
||||
- keyboard movement on computers;
|
||||
- directional swipes on touchscreens;
|
||||
- an accessible drop-key action for both control modes.
|
||||
|
||||
## 6. Keys and inventory
|
||||
|
||||
- A player may carry at most one key.
|
||||
- A player may pick up either key if the inventory slot is empty.
|
||||
- The carried key disappears from its map cell and becomes server-owned
|
||||
inventory state.
|
||||
- A player always sees which key they carry.
|
||||
- A player may voluntarily drop either their own or the opponent's key. It is
|
||||
placed on the player's current cell.
|
||||
- Entering a cell containing a key while already carrying one does not pick up
|
||||
the second key.
|
||||
- A player may carry the opponent's key elsewhere and drop it as sabotage.
|
||||
- When players meet, every carried key is automatically transferred to its
|
||||
correct owner. If both carry each other's keys, the keys swap owners in the
|
||||
same authoritative event.
|
||||
- Outside the current field of view, a player receives no information that the
|
||||
opponent found, dropped, or carries a key.
|
||||
- When the opponent is visible, their carried key identity is visible too.
|
||||
- A player cannot open or use the opponent's exit, even while carrying the
|
||||
matching opponent key.
|
||||
|
||||
## 7. Fog of war
|
||||
|
||||
- Normal vision radius is three cells around the player.
|
||||
- Walls do not block vision.
|
||||
- For the MVP, radius uses a square/Chebyshev neighborhood: a radius of three
|
||||
exposes at most a `7 x 7` cell area, clipped by map boundaries.
|
||||
- Once a cell leaves the current vision area it becomes completely unknown
|
||||
again; there is no explored-map memory.
|
||||
- Hidden cells reveal neither maze geometry nor stale objects or player
|
||||
positions.
|
||||
- The opponent is visible only while inside the current vision area and
|
||||
disappears immediately after leaving it.
|
||||
- Observers are exempt from fog of war.
|
||||
|
||||
## 8. Vision artifacts and compasses
|
||||
|
||||
### Vision artifacts
|
||||
|
||||
- The map contains multiple one-use vision artifacts.
|
||||
- Entering an artifact cell activates it immediately and removes it from the
|
||||
map; it cannot be stored or reused.
|
||||
- The effect increases vision radius from three to six cells.
|
||||
- The effect lasts for the next ten successful moves by that player.
|
||||
- Failed move attempts do not consume an effect move.
|
||||
- Additional artifact types are outside the MVP.
|
||||
|
||||
### Compasses
|
||||
|
||||
- The maze contains two stationary compasses, one associated with each
|
||||
player's exit and placed fairly as a symmetric pair.
|
||||
- A compass cannot be picked up.
|
||||
- A player must enter the appropriate compass cell to activate its hint.
|
||||
- On activation, the UI displays an arrow pointing toward that player's own
|
||||
exit.
|
||||
- A compass does not reveal a route or the exit coordinates.
|
||||
|
||||
## 9. Exit, victory, and draw
|
||||
|
||||
- A player can open only their own exit and only with their own key.
|
||||
- Opening the exit is not itself a victory.
|
||||
- After opening it, the player must perform one additional valid outward move
|
||||
beyond the maze boundary through that exit.
|
||||
- The server records the authoritative exit time.
|
||||
- The first player to complete the outward move wins.
|
||||
- If both authoritative exit times fall within a 200 ms window, the result is
|
||||
a draw.
|
||||
- The normal target match duration is approximately five minutes, but a
|
||||
connected match continues indefinitely until victory or another defined draw
|
||||
condition.
|
||||
|
||||
## 10. Connectivity and recovery
|
||||
|
||||
### Wi-Fi provisioning
|
||||
|
||||
- In normal operation the ESP connects to a previously configured Wi-Fi
|
||||
network in station mode.
|
||||
- Network credentials are stored in NVS and reused after reboot.
|
||||
- When the configured network is unavailable or credentials have not been
|
||||
saved, the ESP starts a fallback access point.
|
||||
- The fallback web interface allows the user to configure and save an existing
|
||||
Wi-Fi network.
|
||||
|
||||
### Player disconnection
|
||||
|
||||
- Loss of either player's WebSocket connection pauses the authoritative match.
|
||||
- No player movement or turn-based effect duration advances while paused.
|
||||
- The disconnected player has 60 seconds to reconnect with the existing
|
||||
session token.
|
||||
- A successful reconnect restores the same slot and resumes the same match
|
||||
state.
|
||||
- If the player does not reconnect within 60 seconds, the match ends in a draw.
|
||||
- Reloading a page is treated as a reconnect, not as leaving the match.
|
||||
|
||||
## 11. Technical constraints
|
||||
|
||||
- Target: ESP32-C6FH4, 4 MB Flash, no required PSRAM.
|
||||
- Build: PlatformIO, `espressif32@7.0.1`, ESP-IDF, compatible
|
||||
`esp32-c6-devkitm-1` profile.
|
||||
- Flash layout: 2 MiB factory application and 1,984 KiB LittleFS; no OTA in
|
||||
MVP.
|
||||
- Static browser assets reside in LittleFS and should be compressed for the
|
||||
production image.
|
||||
- HTTP serves the application and provisioning pages; WebSocket carries live
|
||||
lobby, control, and match messages.
|
||||
- The initial LwIP socket limit is 16.
|
||||
- The implementation must be tested with two player connections and four
|
||||
simultaneous observer connections on the physical device.
|
||||
- Active lobby and match state may live in RAM and need not survive an ESP
|
||||
reboot. Wi-Fi settings must survive reboot.
|
||||
|
||||
## 12. MVP acceptance criteria
|
||||
|
||||
The MVP is accepted when all of the following are demonstrated on the target
|
||||
board:
|
||||
|
||||
1. The firmware builds with the locked PlatformIO configuration and fits the
|
||||
application and LittleFS partitions.
|
||||
2. Wi-Fi station setup persists in NVS, and failed station connection exposes
|
||||
the fallback access-point configuration flow.
|
||||
3. Two browsers can claim unique player names, restore their slots after page
|
||||
refresh, enter the lobby, and start through the owner-controlled countdown.
|
||||
4. Four additional browsers can observe the complete match simultaneously
|
||||
without receiving control authority.
|
||||
5. Repeatedly generated `128 x 64` maps are connected, centrally symmetric,
|
||||
contain cycles and multiple cross-half passages, and preserve equal
|
||||
player-relative placement metrics.
|
||||
6. Player clients never receive cells or dynamic objects outside their current
|
||||
allowed view; observer clients receive the complete state.
|
||||
7. Keyboard and touch controls produce server-validated single-cell movement
|
||||
with an enforced configurable cooldown.
|
||||
8. Key pickup, one-slot inventory, dropping, sabotage, automatic owner return,
|
||||
door restrictions, and visible-carried-key rules behave as specified.
|
||||
9. Vision artifacts expand the view for exactly ten successful moves, and
|
||||
compass cells display the correct direction to the activating player's own
|
||||
exit.
|
||||
10. An outward move through an opened own exit determines victory, and exits
|
||||
within 200 ms produce a draw.
|
||||
11. A player disconnect pauses the match, reconnection restores it, and a
|
||||
60-second reconnect timeout ends it as a draw.
|
||||
12. A representative match normally completes in approximately five minutes
|
||||
after balance tuning, without imposing a hard match timer.
|
||||
|
||||
## 13. Explicitly outside MVP
|
||||
|
||||
- More than two active players or more than one concurrent match.
|
||||
- More than four observers.
|
||||
- Persistent accounts, passwords, cloud services, matchmaking, or internet
|
||||
play.
|
||||
- Spectator control or moderation tools.
|
||||
- Physical display or gameplay buttons.
|
||||
- ESP-NOW, BLE multiplayer, or multiple-device game simulation.
|
||||
- Additional artifact types, combat, health, traps, or player elimination.
|
||||
- Persistent match recovery after ESP reboot.
|
||||
- OTA firmware partitions and OTA update flow.
|
||||
- Dependence on PSRAM, an unverified LED, or an assumed board pinout.
|
||||
|
||||
Reference in New Issue
Block a user