381 lines
16 KiB
Markdown
381 lines
16 KiB
Markdown
# World2 Game Project - Agent Guide
|
||
|
||
## Project Overview
|
||
|
||
World2 is a 3D life simulation game built using the OGRE3D rendering engine. The project features an Entity-Component-System (ECS) architecture powered by Flecs, with Jolt Physics for simulation, Lua scripting for story content, and ImGui for user interfaces.
|
||
|
||
## Technology Stack
|
||
|
||
### Core Dependencies
|
||
- **Rendering**: OGRE3D 14.x+ (Object-Oriented Graphics Rendering Engine)
|
||
- **ECS Framework**: Flecs (Fast Lightweight Entity Component System)
|
||
- **Physics**: Jolt Physics with double precision support (JPH_DOUBLE_PRECISION)
|
||
- **Scripting**: Lua 5.4 with LPEG library
|
||
- **Audio**: miniaudio (single-header audio library)
|
||
- **UI**: ImGui (integrated via Ogre::ImGuiOverlay)
|
||
- **Model Loading**: Assimp with pugixml
|
||
- **Navigation**: Recast/Detour for crowd simulation
|
||
- **Procedural Generation**: OgreProcedural
|
||
- **Profiling**: Tracy frame profiler
|
||
|
||
### Build Requirements
|
||
- CMake 3.13+
|
||
- C++17 compatible compiler
|
||
- Blender (for asset processing, path configurable via `BLENDER` CMake variable)
|
||
- OGRE SDK with components: Bites, Paging, Terrain, MeshLodGenerator
|
||
|
||
## Project Structure
|
||
|
||
```
|
||
/
|
||
├── CMakeLists.txt # Main build configuration
|
||
├── resources.cfg # OGRE resource locations
|
||
├── .clang-format # Linux kernel code style config
|
||
│
|
||
├── Game.cpp # Main game executable entry point (legacy)
|
||
├── Editor.cpp # World editor executable (legacy)
|
||
├── Procedural.cpp # Procedural generation test / character controller demo (legacy)
|
||
├── Bootstrap.cpp # Legacy character controller demo (legacy)
|
||
├── terrain.cpp # Terrain system test executable (legacy)
|
||
│
|
||
├── src/ # Source code
|
||
│ ├── gamedata/ # Core ECS modules and game logic (legacy)
|
||
│ │ ├── GameData.cpp/h # ECS world setup and management (legacy)
|
||
│ │ ├── Components.h # ECS component definitions (legacy)
|
||
│ │ ├── *Module.cpp/h # Individual ECS modules (legacy)
|
||
│ │ └── items/ # Game item implementations (harbour, temple, town, etc.) (legacy)
|
||
│ ├── lua/ # Lua integration
|
||
│ │ ├── lua-5.4.8/ # Lua source code
|
||
│ │ └── lpeg-1.1.0/ # LPEG parsing library
|
||
│ ├── physics/ # Jolt Physics wrapper (physics.h/cpp) (legacy - for buildiung legacy code only)
|
||
│ ├── sound/ # Audio system (miniaudio)
|
||
│ ├── crowd/ # Recast/Detour navigation
|
||
│ │ ├── include/ # Crowd headers (OgreRecast, OgreDetourCrowd, etc.)
|
||
│ │ └── src/ # Crowd implementations
|
||
│ ├── editor/ # Editor-specific code (legacy)
|
||
│ │ ├── EditorGizmoModule.h/cpp
|
||
│ │ ├── EditorInputModule.h/cpp
|
||
│ │ └── main.cpp
|
||
│ ├── features/ # Feature modules
|
||
│ │ ├── characters/ # Character rendering test
|
||
│ │ ├── editScene/ # Scene editor with ECS, it has game mode and all features, current work is here
|
||
│ │ └── sceneEditor/ # some other editor code
|
||
│ ├── world/ # World generation and GOAP AI (legacy)
|
||
│ ├── terrain/ # Terrain system (legacy)
|
||
│ ├── tests/ # Test utilities
|
||
│ ├── text_editor/ # ImGui text editor component
|
||
│ ├── miniaudio/ # Audio library
|
||
│ ├── sceneloader/ # Scene loading utilitie (legacy)
|
||
│ ├── aitoolkit/ # AI utilities (GOAP, FSM, Behavior Trees) (legacy)
|
||
│ └── vehicles/ # Vehicle definitions (legacy)
|
||
│
|
||
├── assets/ # Source assets (Blender files)
|
||
│ ├── blender/ # Blender source files
|
||
│ │ ├── buildings/ # Building models (.blend)
|
||
│ │ ├── characters/ # Character models and clothes (characters asset pipeline)
|
||
│ │ ├── vehicles/ # Vehicle models
|
||
│ │ ├── scripts/ # Blender Python scripts for export
|
||
│ │ └── world/ # World terrain models
|
||
│ ├── textures/ # Source textures
|
||
│ └── fonts/ # Game fonts
|
||
│
|
||
├── lua-scripts/ # Lua game scripts
|
||
│ ├── narrator/ # Ink narrative parser
|
||
│ ├── stories/ # Story scripts (.ink format, compiled to .lua)
|
||
│ └── json/ # JSON library for Lua
|
||
│
|
||
├── water/ # Water rendering system (legacy)
|
||
│ ├── water.h/cpp # Water class
|
||
│ ├── *.frag, *.vert # GLSL shaders
|
||
│ └── water.compositor # OGRE compositor script
|
||
│
|
||
├── skybox/ # Sky rendering resources
|
||
├── resources/ # Runtime resources (build output)
|
||
├── audio/ # Audio resources
|
||
├── morph/ # Character morphing data
|
||
└── build/ # build directory
|
||
└── build-vscode/ # VSCode build directory
|
||
```
|
||
## Critical Constraints & Rules
|
||
- The source code is the only source of truth. Please check code as documentation might be out of sync.
|
||
- Do not modify legacy code. Current code is at src/features/editScene and its dependencies.
|
||
- Please ask questions if anything is unclear.
|
||
- Please update tests, documentation and examples every time API or modules and systems change.
|
||
|
||
|
||
## Build Instructions
|
||
|
||
### Prerequisites
|
||
1. Install OGRE3D SDK with Bites, Paging, Terrain, MeshLodGenerator components
|
||
2. Install dependencies: Jolt Physics, Flecs, Assimp, pugixml, OgreProcedural, Tracy, SDL2, ZLIB
|
||
3. Set `CMAKE_PREFIX_PATH` to OGRE installation
|
||
4. Configure Blender path in CMake (default: `${CMAKE_SOURCE_DIR}/../../blender-bin/bin/blender`)
|
||
|
||
### Build Commands
|
||
|
||
```bash
|
||
# Configure (adjust paths as needed)
|
||
cmake -B build -S . -DCMAKE_PREFIX_PATH=/path/to/ogre-sdk
|
||
|
||
# Build all targets
|
||
cmake --build build
|
||
|
||
# Build specific targets
|
||
cmake --build build --target Game # Main game executable (legacy)
|
||
cmake --build build --target Editor # World editor (legacy)
|
||
cmake --build build --target Procedural # Procedural test (legacy)
|
||
cmake --build build --target TerrainTest # Terrain test (legacy)
|
||
cmake --build build --target TerrainTest # Terrain test (legacy)
|
||
cmake --build build --target editSceneEditor # Current executable for scene editor and game
|
||
```
|
||
|
||
### Build Outputs
|
||
- `build/Game` - Main game executable (legacy)
|
||
- `build/Editor` - World editor executable (legacy)
|
||
- `build/Procedural` - Procedural generation test (legacy)
|
||
- `build/TerrainTest` - Terrain system test (legacy)
|
||
- `build//src/features/editScene/editSceneEditor` - current executable
|
||
- `build/resources/` - Staged game resources
|
||
- `build/characters/` - Processed character models
|
||
- `build/water/` - Water assets (legacy)
|
||
|
||
## Code Style Guidelines
|
||
|
||
This project follows the **Linux Kernel Coding Style** for C++:
|
||
|
||
### Formatting Rules
|
||
- **Indentation**: 8-character tabs (UseTab: Always)
|
||
- **Line Length**: 80 characters maximum
|
||
- **Braces**:
|
||
- Functions: Opening brace on new line
|
||
- Control structures: Opening brace on same line
|
||
- **Pointer Alignment**: Right (`int *ptr` not `int* ptr`)
|
||
- **Namespaces**: No indentation inside namespaces
|
||
|
||
### Example
|
||
```cpp
|
||
void myFunction(int arg)
|
||
{
|
||
if (arg > 0) {
|
||
doSomething();
|
||
return;
|
||
}
|
||
|
||
for (int i = 0; i < arg; i++) {
|
||
process(i);
|
||
}
|
||
}
|
||
```
|
||
|
||
### Running clang-format
|
||
```bash
|
||
clang-format -i src/gamedata/*.cpp src/gamedata/*.h
|
||
```
|
||
|
||
## Architecture
|
||
|
||
### ECS (Entity Component System)
|
||
|
||
The game uses Flecs for ECS architecture. Core systems:
|
||
|
||
#### Components (src/gamedata/Components.h) (legacy)
|
||
- `GameData` - Global game state
|
||
- `EngineData` - Engine configuration (SceneManager, delta time, debug draw)
|
||
- `Input` - Input state (keyboard, mouse, controls)
|
||
- `Camera` - Camera node and configuration
|
||
- `RenderWindow` - Window and DPI information
|
||
- `CollisionShape` - Physics shape references
|
||
- `EditorSceneSwitch` - Editor scene switching
|
||
- `GameState` - Game running state
|
||
|
||
#### Modules (src/gamedata/*Module.h) (legacy)
|
||
Modules are ECS systems organized by functionality:
|
||
|
||
| Module | Purpose |
|
||
|--------|---------|
|
||
| AppModule | Application context management |
|
||
| GUIModule | ImGui interface management |
|
||
| EditorGUIModule | Editor UI |
|
||
| PhysicsModule | Jolt physics integration |
|
||
| CharacterModule | Character spawning and management |
|
||
| CharacterManagerModule | Player/NPC character management |
|
||
| CharacterAnimationModule | Animation state machines |
|
||
| CharacterAIModule | AI behavior (GOAP-based) |
|
||
| TerrainModule | Terrain generation and rendering |
|
||
| WaterModule | Water surface and physics |
|
||
| SunModule | Day/night cycle and lighting |
|
||
| WorldMapModule | World map overlay |
|
||
| QuestModule | Quest system |
|
||
| EventModule | Game event handling |
|
||
| EventTriggerModule | Event triggers |
|
||
| SlotsModule | Inventory slot management |
|
||
| BoatModule | Boat physics and control |
|
||
| VehicleManagerModule | Vehicle management |
|
||
| PlayerActionModule | Player action handling |
|
||
| LuaModule | Lua scripting integration |
|
||
| StaticGeometryModule | Static geometry management |
|
||
|
||
### EditScene Modules (`src/features/editScene`)
|
||
The editor/game mode executable adds its own ECS components.
|
||
|
||
The editor/game mode executable adds its own ECS modules:
|
||
|
||
| Module | Purpose |
|
||
|--------|---------|
|
||
| CharacterSlotSystem | Catalog-driven multi-slot character mesh builder |
|
||
| CharacterSpawnerSystem | Distance-based spawn/despawn of registry characters |
|
||
| PlayerControllerSystem | Player input, camera, locomotion and animation state |
|
||
| ActuatorSystem | Player interaction prompts and smart-object/item actions |
|
||
| EditorUISystem | ImGui property panels and scene management |
|
||
| ProceduralTextureSystem | Runtime procedural texture generation |
|
||
| ProceduralMaterialSystem | Runtime procedural material creation |
|
||
| AnimationTreeRegistry | Global named animation tree definitions |
|
||
| AnimationTreeSystem | Runtime evaluation of registry-referenced animation trees |
|
||
|
||
#### PlayerControllerSystem
|
||
|
||
`PlayerControllerSystem` reads the shared `GameInputState`, drives the TPS/FPS
|
||
camera and sets the locomotion animation state (`idle`/`walking`/`running` and
|
||
the swim equivalents) on the controlled entity. In game mode it adds the
|
||
`PlayerControlledComponent` tag to the target so AI systems know to leave it
|
||
alone.
|
||
|
||
When a controller's `targetCharacterName` points at an entity with
|
||
`CharacterSpawnerComponent`, the system locks the spawner and forces an
|
||
immediate spawn; the actual controlled entity is the spawned character
|
||
instance, not the spawner.
|
||
|
||
#### Player Character Resolution
|
||
|
||
Systems that need the live player character (inventory UI, character sheet,
|
||
save/load, actuators) must not resolve the controller's
|
||
`targetCharacterName` against `EntityNameComponent` directly – that returns the
|
||
spawner entity when the controller targets a spawner. Instead use:
|
||
|
||
```cpp
|
||
flecs::entity player = editorApp->getPlayerCharacterEntity();
|
||
```
|
||
|
||
`EditorApp::getPlayerCharacterEntity()` returns the controller's current
|
||
target, spawning the character through `CharacterSpawnerSystem` if necessary.
|
||
`CharacterSpawnerSystem::getSpawnerForCharacter()` can be used in save/load to
|
||
keep the controller pointed at the spawner rather than the transient instance.
|
||
|
||
#### Game Mode Input
|
||
|
||
Game mode movement keys (`W`, `A`, `S`, `D`, left/right `Shift`) are handled
|
||
inside `keyPressed`/`keyReleased` by `keysym.sym`. Repeated `KEYDOWN` events
|
||
(`evt.repeat != 0`) are ignored for movement keys, because releasing `Shift`
|
||
while `W`/`A`/`S`/`D` is held can generate a repeated keydown with a different
|
||
symbol after the physical release, which would otherwise leave the key stuck.
|
||
One-shot actions (`E`, `F`, `I`, `Escape`) are still matched by `keysym.sym`.
|
||
|
||
#### CharacterSpawnerComponent
|
||
|
||
- `registryId` - Character registry ID to spawn.
|
||
- `spawnDistanceSq` - Squared distance to camera at which the character spawns (default 100²).
|
||
- `despawnDistanceSq` - Squared distance to camera at which the character despawns (default 200²).
|
||
|
||
The spawner uses the entity's `TransformComponent` for spawn position/rotation. When the spawner itself moves/rotates/scales in the editor, the spawned character is updated to match; when the spawner is stationary, the character is left alone so it can move on its own. Spawned characters are created without `EditorMarkerComponent` and removed from the editor UI cache so they remain visible but are not selectable/editable in the editor. Registry changes that bump the character version trigger an immediate respawn. Scene serialization stores plain `spawnDistance`/`despawnDistance` values for readability while the component keeps squared values for comparisons.
|
||
|
||
#### AnimationTreeComponent
|
||
|
||
- `treeName` - Name of the animation tree in `AnimationTreeRegistry`.
|
||
- `enabled` - Whether the tree is evaluated.
|
||
- `useRootMotion` - Whether root motion from the animation drives the character's linear velocity.
|
||
|
||
The actual tree definition (node hierarchy, state machines, animations) lives in the `AnimationTreeRegistry`, persisted to `animation_tree.json`. Trees are authored in the registry editor (**Tools -> Animation Tree Registry**), where each entry can also select a skeleton source from the `Characters` resource group (one representative mesh per skeleton) to populate animation-name dropdowns. Old scenes and prefabs that stored the tree inline or referenced an `AnimationTreeTemplate` are migrated automatically on load.
|
||
|
||
### Physics System
|
||
|
||
Uses Jolt Physics with custom wrapper (legacy - `src/physics/physics.h`, current - `src/features/editScene/physics/physics.h`):
|
||
|
||
```cpp
|
||
// Example: Creating a physics body
|
||
JoltPhysicsWrapper *physics = new JoltPhysicsWrapper(scnMgr, cameraNode);
|
||
JPH::ShapeRefC shape = physics->createBoxShape(Ogre::Vector3(1, 1, 1));
|
||
JPH::BodyID body = physics->createBody(shape, 1.0f, position, rotation,
|
||
JPH::EMotionType::Dynamic, Layers::MOVING);
|
||
```
|
||
|
||
### Rendering Pipeline
|
||
|
||
1. **Main Render**: Standard OGRE render with RTSS (Real Time Shader System)
|
||
2. **Water**: Reflection/refraction with custom shaders
|
||
3. **Sky**: Dynamic skybox with day/night cycle
|
||
4. **Shadows**: Configurable shadow techniques
|
||
|
||
### Asset Pipeline
|
||
|
||
1. **Source**: Blender `.blend` files in `assets/`
|
||
2. **Export**: Python scripts in `assets/blender/scripts/`
|
||
- `export_buildings.py` - Building export to glTF
|
||
- `export_characters_ogre.py` - Character export to OGRE format
|
||
- `export_vehicles.py` - Vehicle export
|
||
- `import_vrm.py` - VRM character import
|
||
3. **Build**: CMake processes assets during build
|
||
4. **Runtime**: Assets loaded from `resources.cfg` paths
|
||
|
||
## Key Conventions
|
||
|
||
### Module Registration
|
||
Modules register themselves with Flecs using the `FLECS_CPP_NO_AUTO_REGISTRATION` macro:
|
||
|
||
```cpp
|
||
// In module header
|
||
struct MyModule {
|
||
MyModule(flecs::world &ecs);
|
||
};
|
||
|
||
// In module implementation
|
||
MyModule::MyModule(flecs::world &ecs) {
|
||
// Register systems, components, etc.
|
||
}
|
||
```
|
||
|
||
### Scene Setup
|
||
Scenes are configured through ECS setup functions:
|
||
|
||
```cpp
|
||
// Setup exterior game scene
|
||
ECS::setupExteriorScene(scnMgr, cameraNode, camera, renderWindow);
|
||
|
||
// Setup interior scene
|
||
ECS::setupInteriorScene(scnMgr, cameraNode, camera, renderWindow);
|
||
|
||
// Setup editor
|
||
ECS::setupEditor(scnMgr, cameraNode, camera, renderWindow);
|
||
```
|
||
|
||
### Lua Scripting
|
||
Story content is written in Ink format and parsed to Lua:
|
||
- Source: `lua-scripts/stories/*.ink`
|
||
- Compiled: `lua-scripts/stories/*.lua`
|
||
- Runtime: Narrator parser loads and executes stories
|
||
|
||
## Development Workflow
|
||
|
||
### Adding Assets
|
||
1. Create/modify `.blend` file in `assets/blender/`
|
||
2. Add export logic to relevant Python script if needed
|
||
3. Add CMake custom command in `CMakeLists.txt` if new asset type
|
||
4. Rebuild to process assets
|
||
|
||
### Debugging
|
||
- Use `ECS::EngineData.enableDbgDraw` for physics debug visualization
|
||
- Tracy profiler integration for performance analysis
|
||
- FPS and draw call stats printed to console
|
||
|
||
## Security Considerations
|
||
|
||
- Lua scripts run in sandboxed environment
|
||
- File system access restricted to resource directories
|
||
- No network functionality currently implemented
|
||
|
||
## Additional Resources
|
||
|
||
- **OGRE3D Docs**: https://ogrecave.github.io/ogre/api/latest/
|
||
- **Flecs Manual**: https://www.flecs.dev/flecs/
|
||
- **Jolt Physics**: https://jrouwe.github.io/JoltPhysics/
|
||
- **Ink Narrative**: https://www.inklestudios.com/ink/
|