123 lines
5.4 KiB
Markdown
123 lines
5.4 KiB
Markdown
# Simple Village Simulation Architecture (MVP)
|
|
|
|
This document outlines the architecture for the Village Simulation based on [Village TZ v2](./village-tz-v2.md). 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):
|
|
1. **Backend (Server)**: Responsible for the entire simulation state, economic logic, AI decision-making (GOAP-based), and turn management.
|
|
2. **Frontend (Client)**: A web-based frontend (HTML/JavaScript) that queries the current state to render it and sends user commands to the server.
|
|
|
|
This separation allows replacing the web frontend with other technologies (React/Vue, Unity, etc.) 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
|
|
|
|
```text
|
|
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
|
|
|
|
1. **Domain Models (`domain/`)**:
|
|
* `Agent`: Stores state (Energy, Hunger, Money, Inventory). Contains methods like `eat()`, `work()`, but does *not* know about the game loop.
|
|
* `Resource`: Enum or classes defining resource properties (decay rate, base value).
|
|
|
|
2. **Core Engine (`core/`)**:
|
|
* `GameEngine`: Singleton that holds the `World` state.
|
|
* **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`.
|
|
|
|
3. **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 (Web)
|
|
|
|
The frontend acts as a **Visualizer**. It does not calculate simulation logic.
|
|
|
|
### 3.1. Structure
|
|
|
|
```text
|
|
web_frontend/
|
|
├── index.html # Main HTML page
|
|
├── goap_debug.html # GOAP debugging view
|
|
├── styles.css # Styling
|
|
└── src/
|
|
├── main.js # Application entry point
|
|
├── api.js # Network client (fetch API)
|
|
├── constants.js # Configuration constants
|
|
└── scenes/ # Game scenes (Phaser.js)
|
|
├── BootScene.js # Loading scene
|
|
└── GameScene.js # Main game visualization
|
|
```
|
|
|
|
### 3.2. Flow
|
|
|
|
1. **Network Step**:
|
|
* Call `GET http://localhost:8000/state`.
|
|
* Receive JSON: `{"turn": 5, "time_of_day": "day", "agents": [...], "market": [...]}`.
|
|
2. **Update Step**:
|
|
* Parse JSON into JavaScript objects.
|
|
3. **Draw Step**:
|
|
* Update Phaser.js game scene.
|
|
* Render Agents at their coordinates.
|
|
* Render UI overlays (e.g., "Day 1, Step 5", "Total Coins: 500").
|
|
|
|
---
|
|
|
|
## 4. Data Flow & Synchronization
|
|
|
|
Since the simulation involves AI agents acting autonomously, the Frontend is primarily an **Observer**.
|
|
|
|
1. **Initialization**: Server starts, generates N agents.
|
|
2. **Loop**:
|
|
* Server calculates the turn results (AI decisions -> Outcomes).
|
|
* Frontend polls `/state` every X milliseconds (or every frame).
|
|
* Frontend updates the screen.
|
|
|
|
### 4.1. The "God Mode" Problem
|
|
To test the simulation efficiently, the Server exposes a **Simulation Controller**:
|
|
* **Manual Mode**: The server waits for a `POST /next_step` call to advance. The User clicks the advance button in the web frontend -> Frontend sends request -> Server updates -> Frontend fetches new state.
|
|
* **Auto Mode**: Server runs a background thread updating every N seconds. Frontend just polls.
|
|
|
|
---
|
|
|
|
## 5. Technology Stack
|
|
|
|
* **Language**: Python 3.11+
|
|
* **Backend Framework**: FastAPI (for speed and auto-generated docs).
|
|
* **Data Validation**: Pydantic.
|
|
* **AI System**: GOAP (Goal-Oriented Action Planning).
|
|
* **Frontend**: HTML/JavaScript with Phaser.js for rendering.
|
|
* **Communication**: HTTP (Fetch API/Uvicorn).
|
|
|
|
## 6. Future Extensibility (Why this architecture?)
|
|
|
|
* **Switch to React/Vue**: Replace `web_frontend/` folder with a React app. The React app simply calls the same `GET /state` endpoint.
|
|
* **Switch to Unity**: Unity `UnityWebRequest` calls `GET /state`.
|
|
* **Database**: Currently state is in-memory (`core/engine.py`). Easy to swap for SQLite/Postgres later by adding a `repository` layer in Backend.
|
|
|