From Runtime to Export: vix/game V4 and V5
vix/game started as a clean game application foundation for Vix.cpp.
The first versions focused on the base runtime pieces:
- application lifecycle
- game loop
- frame timing
- scenes
- events
- assets
- jobs
- input
- window abstraction
- renderer abstraction
- runtime layers
That foundation matters because C++ game projects often become complex before the first real feature is even built.
But a foundation is only useful if it can grow.
V4 and V5 move vix/game from a simple runtime base toward something more complete:
- V4 connects the runtime to real window and rendering backends.
- V5 adds project export, asset scanning, package metadata, and CLI workflow.
The goal is still the same:
Build the foundation, not the prison.
vix/gameis not trying to become a locked game engine. It gives developers the runtime pieces needed to build games, simulations, tools, prototypes, and custom engines on top of Vix.cpp.
Why V4 matters
Before V4, the module already had a strong internal structure.
It had:
AppGameLoopSceneManagerAssetManagerInputSystemWindowRendererRenderer2DGameContextGameRuntimeEditorRuntime
But most of the architecture was still backend-independent.
That was intentional. The first job was to define the runtime surface before attaching it to real platform backends. V4 is where the module starts crossing that line. It keeps the clean abstractions, but adds the first real backend path.
Runtime coordination
V4 makes GameRuntime the main runtime coordinator.
Instead of pushing every responsibility into App, runtime orchestration lives in dedicated objects.
This keeps the architecture clean.
App
├── GameLoop
├── EventBus
├── SceneManager
├── AssetManager
├── AsyncAssetLoader
└── JobSystem
GameContext
├── App access
├── InputSystem
├── Window
├── Renderer
└── Renderer2D
GameRuntime
└── Coordinates runtime frame phasesApp remains the lifecycle root.
GameContext gives systems access to shared runtime services.
GameRuntime coordinates the higher-level execution flow.
This separation is important because the module will later need editor tools, scripting, audio, physics, packaging, and diagnostics without turning App into a giant engine object.
Backend installation through GameContext
V4 improves GameContext so runtime backends can be installed cleanly.
That means a game can run with:
- a null window
- a null renderer
- an SDL window
- an SDL renderer
- future custom backends
This matters for testing and CI. A game module should not require a graphical backend just to validate core logic. Headless execution remains possible, while real rendering becomes available when a backend is installed.
GameContext
├── InputSystem
├── Window
├── Renderer
└── Renderer2DThis gives Vix a runtime model that can work both for local development and automated builds.
SDL window backend
V4 adds the first SDL window backend path. The module can now create an SDL-backed window while keeping the public API backend-independent. The high-level code should not be forced to know whether the window comes from SDL, GLFW, a null backend, or a future platform layer. That is the point of the abstraction.
Game code
-> Window interface
-> SDLWindow backendThe result is simple:
- game code targets
vix/game - backend code handles SDL details
- tests can still use null backends
- future backends can be added without changing the mental model
SDL input mapping
Windowing alone is not enough.
A real runtime also needs input.
V4 connects SDL input events to the backend-independent InputSystem.
The input layer supports:
- key state
- pointer button state
- pointer position
- pointer delta
- wheel delta
- action bindings
- pressed, down, and released queries
Game code can bind actions without being tied directly to SDL events.
Example:
input.bind_key("jump", vix::game::InputKey::Space);
if (input.action_pressed("jump"))
{
// jump
}This keeps the game-facing API stable. SDL becomes an implementation detail.
SDL renderer backend
V4 also introduces an SDL renderer backend. This is a major step because the module moves from abstract rendering concepts to visible output. The rendering path becomes:
Renderer2D
-> DrawSpriteCommand
-> Renderer
-> SDLRendererRenderer2D stays as the high-level 2D rendering API.
SDLRenderer handles the backend-specific rendering work.
This gives Vix a first real path toward 2D games, tools, and simulations without locking the architecture to SDL forever.
Sprite rendering
V4 adds sprite rendering through the SDL renderer path.
The flow is:
AssetManager
-> Asset bytes
-> Renderer::upload_texture()
-> SDLRenderer texture store
-> Sprite
-> Renderer2D
-> DrawSpriteCommand
-> SDLRenderer::draw_sprite()This is important because it connects multiple systems together:
- assets
- renderer abstraction
- texture upload
- 2D command collection
- backend drawing
That means vix/game is no longer only a runtime skeleton.
It can now demonstrate a real rendering pipeline.
Runtime diagnostics and inspection
V4 also adds runtime diagnostics and inspection APIs. This prepares the module for more serious tooling. A game runtime should not be a black box. Developers need to inspect:
- runtime state
- scene state
- editor state
- backend state
- frame behavior
- active systems
This is especially important for future editor tools. The editor layer cannot be added cleanly if the runtime cannot expose useful information. V4 starts preparing that surface.
Why V5 matters
V4 makes the runtime more real. V5 makes the workflow more complete. A game project is not only code that runs locally.
It also needs:
- project metadata
- asset metadata
- generated templates
- export output
- inspectable manifests
- CLI commands
- predictable project layout
V5 adds that layer. The main feature is:
vix game exportThis command turns a game project into an exported directory with copied assets, package metadata, and an export manifest.
Game package metadata
V5 builds on GamePackage.
A game project can describe itself with metadata such as:
- name
- version
- author
- entry scene
- asset root
- output directory
- scene list
- asset list
This metadata is the base for future workflows:
- project creation
- game export
- packaging
- editor loading
- release preparation
- distribution metadata
The important part is that this metadata is explicit. Vix should not guess everything silently. The project should be inspectable.
vix new --game template
V5 also improves the generated game template. A new game project can be created with:
vix new mario --game
cd mario
vix build
vix dev
vix game exportThe generated layout is simple:
mario/
assets/
game.package.json
README.md
src/
main.cpp
vix.app
vix.jsonThe generated project uses:
vix/gameGameRuntimeSceneSceneManagerGamePackagevix.appvix.json
That matters because Vix is not only a library collection. It is also a workflow. The developer should be able to create a game project, build it, run it, and export it without manually wiring every file.
vix.app for game projects
The generated game project uses vix.app.
Example:
name = "mario"
type = "executable"
standard = "c++20"
sources = [
"src/main.cpp",
]
include_dirs = [
"src",
]
compile_features = [
"cxx_std_20",
]
packages = [
"vix",
]
links = [
"vix::game",
"vix::io",
]
resources = [
"assets=assets",
"game.package.json=game.package.json",
]
output_dir = "bin"This keeps the project readable. The developer sees a small manifest. Vix handles the native build structure internally. That is the direction of Vix:
Keep the workflow simple without removing the power of C++.
Game export workflow
V5 adds a complete export workflow. A game can now be exported with:
vix game exportThe command reads game.package.json, scans the asset root, copies exportable files, and generates an export manifest.
Example output:
✔ Game exported.
• Output : ./dist/mario
• Name : mario
• Version : 0.1.0
• Asset root: assets
• Copied files: 4
• Copied directories: 1Generated layout:
dist/
mario/
assets/
game.package.json
README.md
export.jsonThis is the first step toward real packaging. It is not yet a full release builder. It does not try to solve everything immediately. But it gives the project a stable export shape.
export.json
The generated export.json makes the export inspectable.
It can contain:
- game name
- version
- asset root
- output path
- copied file count
- copied directory count
- build date
- exported asset list
This matters because export should not be a hidden copy operation. A developer should be able to inspect what was exported and why. That also prepares future features:
- asset hashing
- asset bundling
- release profiles
- editor export tools
- distribution metadata
- reproducible packaging
Asset export pipeline
V5 adds a small asset export pipeline. The pipeline scans the configured asset root and classifies exported assets. Supported asset categories include:
- image
- text
- binary
Example exported asset metadata:
{
"path": "player.png",
"type": "image",
"size_bytes": 1024
}The pipeline also ignores temporary and cache files.
Examples:
.gitkeep.DS_StoreThumbs.dbcache/tmp/temp/build/dist/*.tmp*.cache*.log
This keeps the export clean. The first version does not transform, compress, hash, or bundle assets yet. It only discovers, classifies, copies, and records them. That is enough for a clear V5 export foundation.
vix dev behavior for games
V5 also fixes vix dev behavior for short-lived game applications.
This is important because the default generated game template may run for only a few frames and then stop.
That is normal for a smoke test or generated starter project.
A development command should handle that cleanly instead of treating every short-lived run as a broken workflow.
This improves the first experience after:
vix new mario --game
cd mario
vix devThe generated application can initialize, run, print frames, and shut down cleanly. Expected output:
Main scene loaded
game app initialized title=mario
frame: 0
frame: 1
frame: 2
frame: 3
frame: 4
frame: 5
game app shutdown title=marioWhat V4 and V5 prove
Together, V4 and V5 prove that vix/game is moving in the right direction.
V4 proves the runtime can connect to real backends:
- SDL window
- SDL input
- SDL renderer
- texture upload
- sprite rendering
- runtime diagnostics
- scene inspection
V5 proves the workflow can become complete:
- game project template
- package metadata
- asset scanning
- export manifest
vix game export- generated export directory
- cleaner
vix devbehavior
This is the bridge between a runtime foundation and a real game development workflow.
What comes next
V6 should build on this foundation.
The next logical steps are:
- scripting backend integration
- audio backend integration
- physics backend integration
- editor tool APIs
- asset hashing
- asset bundling
- export profiles
- release packaging
- richer project templates
The important thing is that these features now have a place to live.
They do not need to be forced into App.
They can build on the existing runtime layers, package metadata, and export pipeline.
Why this matters for Vix.cpp
Vix.cpp is not only about making C++ builds easier.
It is about making C++ application development feel more direct.
vix/game shows that this philosophy can apply to games and real-time software:
- explicit APIs
- backend independence
- simple project creation
- clean runtime architecture
- native C++ control
- generated templates
- exportable projects
- inspectable metadata
The goal is not to compete directly with Unity, Unreal, or Godot.
The goal is different.
vix/game is the layer before the engine.
It gives C++ developers a foundation they can understand, extend, and control.
Final note
V4 made the runtime visible. V5 made the project exportable. That is an important step for Vix.cpp. A C++ game project should not begin with build system pain, backend confusion, and scattered runtime code.
It should begin with a clean foundation:
vix new mario --game
cd mario
vix dev
vix game exportThat is the direction of vix/game.