-
Notifications
You must be signed in to change notification settings - Fork 1
Codebase Observations
Audience: Programmers | Mixed
Thread Context: N/A (audit/reference)
Platform/Backend Scope: All platforms / all backends
Non-obvious facts about SparkEngine's codebase structure, conventions, and tooling that are easy to get wrong. These are things not immediately apparent from reading CLAUDE.md or the rest of the wiki, or things that contradict common assumptions. Check these before making assumptions about how the engine builds, where subsystems live, or which files are safe to edit by hand.
Several major engine systems are gated behind CMake toggles. A build can succeed even if code in a disabled system is broken, because that code is never compiled.
Current default toggle state (verify with cmake --preset linux-gcc-release -N):
ENABLE_NETWORKING=ON ← now ON by default (was OFF at the time of the original observation)
ENABLE_DXR=ON ← on by default (SDFGI fallback when no D3D12/DXR hardware)
ENABLE_VR=OFF ← VR is implemented and wired in, but disabled by default
ENABLE_METAL=OFF ← experimental, off by default
The original observation flagged networking as the most common trap because it was off by default. That has since changed — ENABLE_NETWORKING is ON by default today, so networking code now compiles in standard CI builds. The general lesson still holds: if code in a disabled system silently breaks, it won't show up in CI; and if a subsystem "doesn't exist," check the CMake toggle first.
Legacy free-floating globals (g_graphics, g_input, g_timer, g_eventBus, g_audioEngine, g_audioBackend, g_moduleManager, g_moduleHotReload, g_physicsOwned) have been removed. Engine-lifetime ownership now lives in an EngineRuntime struct (SparkEngine/Source/Core/EngineRuntime.h), accessed via GetEngineRuntime(), intended for Core/ entry-point and lifecycle files only.
All other code accesses subsystems through the EngineContext service locator:
// WRONG — removed globals (no longer declared anywhere):
g_graphics->RenderFrame();
// CORRECT — EngineContext service locator:
auto* graphics = EngineContext::Get()->GetGraphics();
auto* input = EngineContext::Get()->GetInput();-
EngineContextlives inSparkEngine/Source/Core/EngineContext.h. -
EngineRuntime(private ownership container) lives inSparkEngine/Source/Core/EngineRuntime.h. - Do not introduce new file-scope
g_*subsystem globals.
.claude/ is NOT excluded from .promptignore — Claude reads these files at session start to load persistent context. Do not add .claude/ to .promptignore.
.promptignore excludes ThirdParty/, Shaders/Compiled/, build/, IDE config dirs, .git/, binary files, and generated docs/html/ + docs/xml/. Everything else (including .claude/) is visible.
Every file under docs/api/ is generated by docs/generate-api-docs.sh. Never edit them by hand — changes are overwritten on the next run. To change API documentation, edit the Doxygen comments (@brief, @param, @return) in the header files under SparkEngine/Source/; the generation script extracts from there.
The script uses checksum-based caching (docs/generate-api-docs.sh check) and only regenerates pages whose headers changed. Note: docs/api/ is a generated artifact and may be absent from a fresh checkout until the script runs.
The same hands-off rule applies to <!-- AUTO:* --> sections in wiki files — they are written by docs/sync-wiki.sh sync.
Wiki pages are mostly hand-written, but specific sections are auto-generated and fenced by markers:
<!-- AUTO:component-list -->
... generated content, do not edit ...
<!-- /AUTO:component-list -->- Outside
<!-- AUTO:* -->blocks: edit freely. - Inside them: do not edit —
docs/sync-wiki.sh syncwill overwrite. - During rebase conflicts in wiki files, take upstream for AUTO: sections.
- To add a new page: create the file in
wiki/, then add it towiki/_Sidebar.md.
| Directory | Contents | Purpose |
|---|---|---|
tools/ (lowercase) |
validate-prompts.sh, check-*.sh, asset generators, wine-run.sh
|
Validation and dev scripts |
Tools/ (uppercase) |
spark-cli/spark_cli.py |
Developer CLI utility |
CI references tools/validate-prompts.sh --ci — always lowercase. On case-insensitive filesystems (macOS) these may appear merged; they are distinct on Linux/CI.
The pre-commit format step uses head -50, checking only the first 50 files by modification time. CI's check-format checks all files (including .hpp). It is possible to pass the local shortcut and fail CI. Run the full CI-matching command (no head -50) before pushing.
ThirdParty/ mixes git submodules and vendored single-header/snapshot code. After cloning, initialize submodules before CMake configure:
git submodule update --init --recursiveIf a ThirdParty/ directory looks empty or CMake reports missing files there, an uninitialized submodule is almost always the cause. There is now a single source of truth at ThirdParty/dependencies.lock plus a configure-time audit (cmake/SparkThirdPartyAudit.cmake) — see the ThirdParty Dependencies Audit page. ThirdParty/ is in .promptignore, so Claude does not see its contents (correct — it is not project code).
A multi-agent defect sweep (2026-07-18) confirmed and fixed 41 local defects across 31 files, plus three architectural ones that were fixed in follow-up commits the same day:
-
Per-client reliable-message state was server-wide (fixed). Receive-side dedup/ACK/ordered state lived per-
NetworkManager, not per sender, so with ≥2 clients, client B's sequence N was dropped as a duplicate of client A's and the merged broadcast ACK silently cancelled B's retransmit. Now all reliability state (dedup windows, reorder buffers, outgoing sequences, unacked/retransmit maps) lives in a per-peerPeerStatekeyed by ClientID, with per-peer unicast ACKs. Regression tests:Tests/TestReliableChannel.cpp(overlapping sequence spaces, ordered independence, ACK isolation). -
Core ECS phase systems were never registered in production (fixed).
CreatePhaseSystemManagerhad no non-test callers. The gameplay lifecycle (GameplayLifecycleShared.cpp) now creates the manager during init and pumpsUpdateAlleach frame in the documented phase order; the deadStageBasedExecutorwas deleted. Regression test:Tests/harden/Test_lifecycle_ecs_phase_wiring.cpp. -
Delta snapshot ACKs were never wired (fixed). Deltas now have their own ack echo —
MessageType::DeltaAckcarries the delta sequence (a different sequence space than transport ACKs, which would falsely advance baselines); clients echo it for applied Unreliable entity-state updates and the server routes the trusted sender toDeltaSnapshotManager::AcknowledgeSequence(cumulative, stale acks ignored).pendingDeltasis bounded at 256/connection. Regression tests:Tests/TestNetworkReplicationIntegration.cpp.
Six split waves reduced the over-threshold file count from 104 to 1 (103 files split into coherent sibling TUs plus small internal headers, all moves byte-identical and build+test verified). The final wave split the 18 Windows-only files (*Windows.cpp, ProcessWin32.cpp) using the MinGW cross-build (linux-mingw-release preset) for compile verification — each split TU was checked with x86_64-w64-mingw32-g++ -fsyntax-only against the real build flags, and the full cross-build stays green. The only remaining violation is GameModules/SparkGameMMOFPS/Source/Core/TFTypes.h (301 lines, a FROZEN CONTRACT header deliberately left alone). Gotchas discovered: (1) Tests/CMakeLists.txt links some module .cpp files by explicit path (e.g. TFOutfitStore.cpp), so splitting one of those requires adding the new sibling TU there too; (2) exe-only entry files (SparkEngineWindows.cpp) are listed in SPARK_ENGINE_ENTRY_POINTS, not globbed into the lib — their split parts must be added to that list; (3) in a network-restricted container, stage DirectXMath headers into build/.dxmath-cache/extract/DirectXMath-oct2024/Inc/ (plus a placeholder oct2024.zip) — the NuGet directxmath package is a working source when GitHub is blocked.
-
Original observation:
.claude/knowledge/codebase-observations.md, last updated 2026-03-19. - Re-measured against codebase 2026-06-08.
- Changes since the original:
-
ENABLE_NETWORKINGdefault OLDOFF→ NEWON(networking now compiles in standard CI). Updated the most-common-trap framing accordingly. - Removed-globals list,
EngineContext/EngineRuntimesplit,.promptignorescope, twotools/dirs, and thehead -50partial-check note all re-verified as still accurate. - ThirdParty note expanded: now backed by
ThirdParty/dependencies.lock+cmake/SparkThirdPartyAudit.cmake(both confirmed present). - Noted
docs/api/may be empty on a fresh checkout (0 generated pages present in the working tree at re-measure time).
-
Published from 8fd2c5bdc5cd. Edit the canonical source in wiki/.
- Documentation
- Docs route
- Wiki index
- Guides
- Tutorials
- Samples
- Examples
- API Reference
- API route
- Reference
- Build Guide
- Dependencies
- FAQ
- Changelog
- Roadmap
- Contributing
- Code of Conduct
- Home
- FAQ
- Getting Started
- Quick-Start Tutorial
- Making Your First Game
- Making Your First Multiplayer Game
- Artist Workflow Guide
- Editor Walkthrough
- Migration Guide
- How SparkEngine Works
- Architecture Overview
- Engine Architecture Flowchart
- Creating a Game Module
- Game Modules (catalog)
- Entity Component System
- Rendering and Graphics
- Physics
- Cloth Simulation
- Audio
- Input System
- Camera System
- Scripting with AngelScript
- Visual Scripting
- AI and Navigation
- Animation
- 2D Systems
- Networking
- Dedicated Server
- Multiplayer Quick Start
- Area Server Architecture
- Scene Management
- Large World Support
- Collaborative Editing
- Coroutine System
- Event System
- Event Response System
- Job System
- UI System
- UI Layout Extensions
- Localization
- Dialogue System
- Destruction System
- Replay System
- Achievement System
- Loading System
- Mod System
- Content Delivery
- Tween System
- Memory Integrity
- Gameplay Systems
- Terrain and Procedural Generation
- Save System
- Persistence System
- Day Night Cycle and Weather
- Cinematic Sequencer
- Runtime Prefabs
- SparkEditor
- Editor Tutorials
- SparkConsole
- SparkDaemon
- Shader Pipeline
- Asset Pipeline
- Asset Validation
- Asset Migration
- Game Packaging
- Online Services
- DataTable System
- Loot and Crafting System
- CSG System
- Font System
- Timer Manager
- Movie Render Pipeline
- HLOD and World Partition
- Remote Debug System
- Selection Manager
- Asset Dependency Graph
- Editor Automation
- File Watcher
- Project Templates
- System Requirements
- VR Support
- Mobile Platform
- Accessibility
- Platform Input
- Cross-Compilation: Wine Testing
- RHI Abstraction Layer
- D3D11 Backend
- D3D12 Backend
- Vulkan Backend
- OpenGL Backend
- Metal Backend
- DXR Raytracing
- Hybrid Ray Tracing
- Upscaling (DLSS/FSR)
- Render Graph
- Shader Graph
- GPU Particles
- GPU-Driven Rendering
- Volumetric Fog
- Volumetric Clouds
- Global Illumination
- Virtual Texturing
- Water Rendering
- Clustered Lighting
- Material System
- Post-Processing
- Shadow System
- Particle System
- Decal System
- Sky and Atmosphere
- Foliage System
- Mesh Shaders
- Neural Rendering
- Configuration Reference
- Performance Tips
- Benchmark Framework
- Threading Model
- Memory Safety
- Memory Management Patterns
- Build System and CMake Modules
- Profiler and Debugging
- Performance Profiling Guide
- Telemetry System
- Golden Image Testing
- Utilities
- Testing
- Codebase Statistics
- Codebase Health
- Error Handling Patterns
- Hot Reload Overview
- Troubleshooting
- Contributing
- Workflow Patterns
- Build Optimizations
- CI Reproducible Builds
- GitHub API and PR Checks
- Git Rebase Conflicts
- Clang-Format
- Code Quality Violations
- AI Bloat Pattern
- MinGW + Wine Cross-Compilation
- Live Editor Testing
- Engine & Renderer Landscape
- DuetOS Portability Catalog
- Five-Engine Analysis
- Eleven-Engine Analysis
- ThorVG / Unity Graphics Analysis
- Advanced Techniques Catalog
- Third-Party Library Evaluation
- Engine Viability Evaluation
- Engine Feature Recommendations
- Project Recommendations
- Mac Compatibility Analysis
- Codebase Observations
- Codebase Bloat Audit
- Test Suite Audit
- Documentation Coverage Audit
- ThirdParty Dependencies Audit
- Load Test Baseline
- Gameplay Systems Status
- SparkGame Module Status
- Stub and Abandoned Features
- Memory Integrity System
- Memory Safety Evaluation
- Hardware Acceleration Systems
- Jolt Physics Integration
- GPU/CPU Separation Plan
- Daemon Services Architecture
- Reflection & Polymorphism Refactoring Plan
- SparkBuild In-Tree
- Wine No-JobSystem Breakthrough
- Wine Role and Fallback Tiers