Skip to content

Expose REST endpoint for client applications #231

@dmccoystephenson

Description

@dmccoystephenson

Summary

Expose a read-only REST API so external client applications (e.g. a world viewer or mapping tool) can query live game state without modifying it.

Background

Roam has no external API surface today. All game state lives in-memory (rooms, entities, player) and is only accessible via the pygame UI or JSON save files on disk. A lightweight read-only HTTP server embedded in the game process would allow external tools to consume live world data without coupling them to Roam's internals. Note: if PR #344 (structured logging via structlog) is merged before this, new log calls in this feature should use getLogger from src/gameLogging/logger.py.

Requirements

Server

  • Embed a lightweight HTTP server in the Roam process using Python's stdlib http.server module (no additional dependencies)
  • Run the server on a background ThreadPoolExecutor thread (consistent with the pattern used in MapImageUpdater and RoomPreloader) so it does not block the game loop
  • Configure the port via config.yml (e.g. restPort: 8080); if the port is already in use, log a warning and disable the REST server rather than crashing
  • Add a restEnabled boolean config option (default false) so the server is opt-in
  • Register the REST server as a singleton in the DI container via src/bootstrap.py and shut it down in WorldScreen.shutdown()

Endpoints

All endpoints return Content-Type: application/json and are read-only (GET only). No authentication is required for MVP.

Endpoint Description
GET /api/v1/world Current room coordinates, room type, tick count, and player location
GET /api/v1/rooms List of all loaded rooms with coordinates, type, and entity counts
GET /api/v1/rooms/{x}/{y} Full entity listing for a specific room by grid coordinates
GET /api/v1/player Player energy, direction, inventory item count, and current room coordinates
GET /api/v1/entities All entities across all loaded rooms with type, location, and room coordinates

Serialization

  • Responses should be plain Python dicts serialized via json.dumps — no third-party serialization library
  • Entity data should include at minimum: entityClass, name, locationId, roomX, roomY
  • All endpoints should return 404 with a JSON error body if the requested resource does not exist, and 503 if the game world is not yet initialized

Thread Safety

  • All reads from Map, Room, and Player must acquire Map._lock (already used by Map.getRoom() and Map.addRoom()) before reading shared state, consistent with the existing locking pattern

Acceptance Criteria

  • restEnabled: true in config.yml starts the HTTP server on the configured port when the world screen is active
  • All five endpoints return valid JSON matching the documented structure
  • The game loop frame rate is not measurably affected by the REST server running in the background
  • A port conflict logs a warning via gameLogging and disables the server without crashing
  • The REST server shuts down cleanly when WorldScreen.shutdown() is called
  • All existing tests pass; new tests cover endpoint responses for each route using a mock game state

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions