5.3 KiB
Simple Village Simulation Architecture (MVP)
This document outlines the architecture for the Village Simulation based on Village TZ v2. The system follows a client-server model to ensure strict separation between the simulation logic (Backend) and the visualization (Frontend).
1. System Overview
The system consists of two distinct applications communicating via HTTP (REST API):
- Backend (Server): Responsible for the entire simulation state, economic logic, AI decision-making, and turn management.
- Frontend (Client): A "dumb" terminal using Pygame that queries the current state to render it and sends user commands (if any) to the server.
This separation allows replacing the Pygame frontend with Web (React/Vue) or Unity in the future without changing the backend logic.
2. Backend Architecture (Python)
We adhere to a simplified Clean Architecture to keep business logic isolated from the API framework.
2.1. Layered Structure
backend/
├── main.py # Entry point, API configuration
├── api/ # Interface Layer (FastAPI)
│ ├── routes.py # Endpoints (GET /state, POST /next_turn)
│ └── schemas.py # Pydantic models for request/response
├── core/ # Business Logic Layer (The "Brain")
│ ├── engine.py # Game Loop manager (Day/Night cycle)
│ ├── world.py # Container for all entities
│ └── market.py # Order Book matching logic
└── domain/ # Data Models (Pure Python)
├── agent.py # Agent logic (stats, inventory, survival rules)
├── resources.py # Resource definitions (Meat, Wood, etc.)
└── action.py # Action definitions (Hunt, Sleep, Trade)
2.2. Key Components
-
Domain Models (
domain/):Agent: Stores state (Energy, Hunger, Money, Inventory). Contains methods likeeat(),work(), but does not know about the game loop.Resource: Enum or classes defining resource properties (decay rate, base value).
-
Core Engine (
core/):GameEngine: Singleton that holds theWorldstate.- Turn Processing:
- The simulation is Turn-Based.
- The Engine waits for a "Next Turn" signal (or runs on a timer).
- Processing order:
Collect Actions->Resolve Market->Update Agent Stats->Remove Dead Agents.
-
API (
api/):GET /state: Returns the full snapshot of the world (Agents, Market Order Book, Global Stats) in JSON format.POST /control/next_step: Forces the simulation to advance one tick (useful for debugging/manual control).POST /market/order: (Optional) Allows manual intervention to place orders.
3. Frontend Architecture (Pygame)
The frontend acts as a Visualizer. It does not calculate simulation logic.
3.1. Structure
frontend/
├── main.py # Pygame Game Loop
├── client.py # Network Client (requests lib)
├── assets/ # Sprites/Fonts
└── renderer/ # Drawing Logic
├── map_renderer.py # Draws the grid/terrain
├── agent_renderer.py # Draws agents and their status bars
└── ui_renderer.py # Draws text info (Market prices, Day/Night)
3.2. Flow
- Network Step:
- Call
GET http://localhost:8000/state. - Receive JSON:
{"turn": 5, "time_of_day": "day", "agents": [...], "market": [...]}.
- Call
- Update Step:
- Parse JSON into local simplified objects.
- Draw Step:
- Clear screen.
- Render Agents at their coordinates.
- Render UI overlays (e.g., "Day 1, Step 5", "Total Coins: 500").
pygame.display.flip().
4. Data Flow & Synchronization
Since the simulation involves AI agents acting autonomously, the Frontend is primarily an Observer.
- Initialization: Server starts, generates N agents.
- Loop:
- Server calculates the turn results (AI decisions -> Outcomes).
- Frontend polls
/stateevery X milliseconds (or every frame). - Frontend updates the screen.
4.1. The "God Mode" Problem
To test the simulation efficiently, the Server will expose a Simulation Controller:
- Manual Mode: The server waits for a
POST /next_stepcall to advance. The User pressesSPACEin Pygame -> Pygame sends request -> Server updates -> Pygame fetches new state. - Auto Mode: Server runs a background thread updating every N seconds. Frontend just polls.
Recommended for MVP: Manual Mode (Spacebar to advance turn).
5. Technology Stack
- Language: Python 3.11+
- Backend Framework: FastAPI (for speed and auto-generated docs).
- Data Validation: Pydantic.
- Frontend: Pygame Community Edition (pygame-ce).
- Communication: HTTP (Requests/Uvicorn).
6. Future Extensibility (Why this architecture?)
- Switch to Web: Replace
frontend/folder with a React app. The React app simply calls the sameGET /stateendpoint. - Switch to Unity: Unity
UnityWebRequestcallsGET /state. - Database: Currently state is in-memory (
core/engine.py). Easy to swap for SQLite/Postgres later by adding arepositorylayer in Backend.