Futura is a work-in-progress classic FPS engine/game written in C++ and OpenGL. The project is mainly a learning ground for understanding how older FPS engines were structured, especially the rendering and world-building ideas behind games like Quake, Half-Life, and Counter-Strike 1.6.
The current codebase is in the middle of a refactor from a direct OpenGL demo/game loop into a small engine-style architecture. Some systems are useful and worth keeping, while others are placeholders or partially migrated.
The project is not yet a complete game. It is currently focused on rebuilding the foundation:
- Window/application abstraction
- Event and layer system
- OpenGL graphics wrappers
- Renderer abstraction
- Texture handling
- FPS camera/input
- Static world geometry and collision acceleration
- Future BSP-style world rendering
The most important development goal right now is to prepare the static world path for BSP work without starting BSP-specific loading yet.
Futura/
src/ Game executable entry point
assets/ Game shaders and textures
FuturaLibrary/
src/FuturaLibrary/core/ Application, window, input, camera, layers
src/FuturaLibrary/events/ Event types and dispatcher
src/FuturaLibrary/graphics/ Low-level OpenGL wrappers
src/FuturaLibrary/renderer/ Higher-level renderer abstraction work
src/FuturaLibrary/utils/ Logging, file IO, instrumentation
vendor/ Third-party dependencies
docs/ MkDocs documentation
Futura uses Premake to generate Visual Studio project files.
GenerateProjects.batThen open Futura.sln and build the Futura project.
The workspace currently targets C++20 and uses:
- GLFW for window creation and input
- GLAD for OpenGL function loading
- GLM for math
- stb_image for image loading
- spdlog for logging
Recommended next steps:
- Restore the concrete GLFW window implementation.
- Fix the application run loop so it updates layers and swaps/polls the window.
- Move the old working cube/camera render path into a game layer.
- Keep the renderer abstraction small until the basic scene works again.
- Finish the texture wrapper after the basic render path is stable.
- Start static brush/world geometry before BSP loading.
- Keep the current static-world acceleration grid collision-first, then reuse the same world-query boundary for visibility/culling when renderer profiling requires it.
Avoid adding BSP, multiplayer, entity systems, or large renderer abstractions until a basic textured 3D scene works through the refactored architecture.
The project documentation is in docs/ and is intended to help you re-enter the project without guessing what each part does.
To preview it locally:
pip install mkdocs
mkdocs serveThen open the local URL printed by MkDocs.
Start here:
docs/index.mddocs/getting-started.mddocs/architecture.mddocs/current-progress.md
Source files should keep the existing project convention of file-level comment headers explaining:
- file name
- purpose
- high-level responsibility
- author/date information when useful
- important development notes
Prefer explicit namespaces in source code. Avoid using namespace ... in project code because this codebase is meant to stay readable while learning engine architecture.
Phase 1: Rendering pipeline + FPS controls
Phase 2: Runtime foundation, event flow, renderer/resource cleanup
Phase 3: Static world geometry + collision prototype
Phase 4: BSP world system: rendering, collision, PVS
Phase 5: Entity System + map/gameplay scripting foundation
Phase 6: FPS gameplay: weapons, health, teams, rounds, damage
Phase 7: Network-ready simulation architecture
Phase 8: Multiplayer implementation
Phase 9: Multiplayer gameplay polish
Phase 10: Optimization, tools, and content pipeline
This roadmap is flexible. Phase 3 now has a static world path with collision queries accelerated by a simple hashed grid; BSP loading/traversal remains Phase 4.