16 KiB
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
BLENDERCMake 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
- Install OGRE3D SDK with Bites, Paging, Terrain, MeshLodGenerator components
- Install dependencies: Jolt Physics, Flecs, Assimp, pugixml, OgreProcedural, Tracy, SDL2, ZLIB
- Set
CMAKE_PREFIX_PATHto OGRE installation - Configure Blender path in CMake (default:
${CMAKE_SOURCE_DIR}/../../blender-bin/bin/blender)
Build Commands
# 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 executablebuild/resources/- Staged game resourcesbuild/characters/- Processed character modelsbuild/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 *ptrnotint* ptr) - Namespaces: No indentation inside namespaces
Example
void myFunction(int arg)
{
if (arg > 0) {
doSomething();
return;
}
for (int i = 0; i < arg; i++) {
process(i);
}
}
Running clang-format
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 stateEngineData- Engine configuration (SceneManager, delta time, debug draw)Input- Input state (keyboard, mouse, controls)Camera- Camera node and configurationRenderWindow- Window and DPI informationCollisionShape- Physics shape referencesEditorSceneSwitch- Editor scene switchingGameState- 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:
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 inAnimationTreeRegistry.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):
// 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
- Main Render: Standard OGRE render with RTSS (Real Time Shader System)
- Water: Reflection/refraction with custom shaders
- Sky: Dynamic skybox with day/night cycle
- Shadows: Configurable shadow techniques
Asset Pipeline
- Source: Blender
.blendfiles inassets/ - Export: Python scripts in
assets/blender/scripts/export_buildings.py- Building export to glTFexport_characters_ogre.py- Character export to OGRE formatexport_vehicles.py- Vehicle exportimport_vrm.py- VRM character import
- Build: CMake processes assets during build
- Runtime: Assets loaded from
resources.cfgpaths
Key Conventions
Module Registration
Modules register themselves with Flecs using the FLECS_CPP_NO_AUTO_REGISTRATION macro:
// 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:
// 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
- Create/modify
.blendfile inassets/blender/ - Add export logic to relevant Python script if needed
- Add CMake custom command in
CMakeLists.txtif new asset type - Rebuild to process assets
Debugging
- Use
ECS::EngineData.enableDbgDrawfor 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/