Introducing NullG

My anti-gravity racing engine, the simulator I want to build around it, and how AI-assisted development grew into tools for inspecting and testing the game.

By Daniel Chote

In Game Sim Racing

I've been building an anti-gravity racing engine called NullG. It's written in C++20 with Vulkan rendering, and currently combines imported game assets with racing physics, weapons, multiplayer and replay tools.

The longer-term idea is a motion simulator pod, with acceleration, braking, cornering and impacts driving physical movement. Positional audio and multiple displays are part of that plan. My Car-cade and motion rig explored the hardware side of racing; this time I'm working on the engine that would feed it.

Development started in January 2026 with AI-assisted planning and implementation. I've used coding agents throughout, with a large part of the work going into the references, constraints and tools they need to make changes that can actually be inspected and tested.

Original NullG ship artwork

Getting started

The first git commit was on January 22. It contained the outline, research files, architecture notes and initial application code: a window, Vulkan setup, input, configuration and logging. The plans already included asset conversion, audio, networking, computer-controlled opponents and motion output.

I put the race simulation at the center of the design. Graphics and sound consume its state, and the eventual motion hardware would read from the same data. That kept the simulator idea part of the engine rather than something to bolt on after the rendering worked.

Early development used Cursor, with commands for planning, preparation and review. Preparation meant reading the relevant references and tracing the code before making changes. Smaller tasks, examples and written decisions gave the next session something useful to start from.

Early NullG team-selection screen with FEISAR selected

Asset conversion and the first renderer pass arrived on January 23. Menus, model loading, asset management and track parsing followed over the next few days. Existing WipEout research and community projects supplied references for the ships, tracks, textures and scenery.

By February 8, NullG could load PlayStation assets directly. That work covered track geometry, scene objects, sprites and texture transparency. With those pieces in the renderer, the imported data could finally be compared with what appeared on screen. The file-format notes and agent rules grew alongside the loaders.

Getting a race working

March was more about how the ship moved: hover height, coasting, weight, jumps, boost, recovery and tunnel-wall collisions. There was also work on scenery placement, skies, pickups, boost pads and the track camera behind the menus.

Lighting, shadows and GPU particles were added to the presentation. By March 6, the code included race-session flow and a weapon system, including getting into a race and back to the menus. The changes were handled as individual tasks with code review and updated notes, rather than expecting one session to keep the whole engine in context.

In May I split the original engine plan into focused documents with a shared status index. Renderer work covered dynamic rendering, geometry access, material organization and moving runtime shaders to Slang. Animated scene lights, illuminated pickups, shields and scenery shadows on ships received attention too.

An entity/component scene system and render snapshots were added during that period. A render snapshot holds the data needed for a frame, including ship and object positions, so the renderer has a consistent state to draw.

By May 28 there were headless tests for the job system, memory and asset handling. Agents could run them after an edit and read the results. The inspection tools grew from there.

June brought Jolt collision integration and more GPU effects work. Research notes on effects, shadows and physics kept established examples available for implementation tasks. On June 9, XL became the default asset source. Each source supplied the information the menus needed to show its available choices. Waterfall texture scrolling and the starting-grid camera were among the other changes.

The next concentrated stretch started on October 9, bringing the agent guidance into Codex, adding native engine inspectors and establishing the fixed 60 Hz race setup. Multiplayer followed on October 10, with more XL reconstruction work on October 11.

Letting the agent inspect the result

In October I switched NullG's coding-agent work exclusively to OpenAI Codex. The planning commands, rules and research notes came across from Cursor. The next step was giving Codex access to the engine tools it needed to check its own work.

I'd recently watched videos about Blender MCP showing an agent working directly with a scene and inspecting the result. That helped shape both the model-authoring process and the decision to connect agents to NullG's native tools.

MCP, the Model Context Protocol, connects AI applications to external tools and data. In NullG it exposes inspection windows, track validators, model viewers and controlled race sessions. The agent can load a track, pick a camera, inspect geometry and save a frame. For a model, it can look at materials, bounds and different angles.

NullG Track Validator showing track geometry, texture inspection, and timeline controls

The weapon harness opens a paused production race. It lets the agent deploy a weapon and advance a few frames at a time, then inspect a projectile, impact or Quake effect at a particular moment. The simulation state is available beside the picture.

Reactive engine plumes in the MCP harness.

For a weapon-effect fix, the process is to set up the scene, fire the weapon, step through it and follow the responsible code. After an edit, the agent builds the affected code and repeats the same case. Reports keep the inputs and settings so another session can reproduce it.

The different checks answer different questions. Physics tests compare movement with expected values; track checks look at road geometry. Replaying the same inputs helps find changes in behaviour. I still need to review appearance and handling, but the agent can do more of the setup and leave the reports and captures for me to inspect.

Ships racing with engine trails and a weapon effect in NullG Diagram showing an agent connected through MCP to native inspection and headless validation tools

Reconstructing XL behavior

October's research went further into WipEout XL / 2097 steering, weapon updates, starting positions and animated objects.

REA, Reverse Engineer Anything, was part of that setup, connecting agents to tools for investigating applications and binaries. The PlayStation executable decompilation used a PSX-aware Ghidra workflow. Scripts saved the instructions, references, annotations and findings so the investigation could be picked up again.

Starting-grid placement is a useful example. Following the original track numbering and route links established where the ships should start. Those findings became checks against the imported track, and the inspector could show the selected position on the road.

An overhead track inspection with a highlighted grid marker

The research covers USA and European editions, retaining the edition and executable details with each finding. A timing value from one build shouldn't quietly become a claim about every version.

The recovered calculations and state changes are first turned into small C++ reference models and tests, then integrated into NullG. The notes keep track of what came from the executable, what was adapted, and what was observed in the engine. Players supply their own game files; I'm developing original NullG content separately.

Other reconstruction projects

This was happening while agent-assisted software reconstruction was getting much more attention. Coverage of REA's growth described the interest around demonstrations of agents inspecting applications and reproducing their behavior.

ArtCraft's projects include photo, video and PDF tools, with WordCraft, GridCraft and DeckCraft targeting Word, Excel and PowerPoint-style work. October coverage connected those AI-assisted projects with interest in alternatives to Adobe and Microsoft software.

The work is similar in one respect: study how something behaves, implement it, then check whether it matches. With racing behaviour, that means taking the executable research into tests and the native inspectors.

Blender models

The first concrete use of those Blender MCP ideas was preparing original menu models. The assistant could inspect the scene, edit individual parts, export a candidate and produce comparison views in the same task.

The process starts with visual references and generated models where useful, followed by a Blender finishing pass. That covers shape, individual parts, surface cleanup, materials and polygon count. Saved revisions and repeatable exports make it possible to change one part and compare it with the previous version.

Four Blender review renders of the original monitor-shaped Graphics menu model

The model is then checked in NullG's Model Viewer and menus at its intended size. The source files, exports and comparison images are saved for each revision. A Blender viewport is useful, but the asset still has to work under the engine's lighting and at the size a player will see it.

Recording races

NullG can record a race, replay it with cinematic cameras and export video with titles and audio. The camera can follow a ship or cut to action elsewhere in the field. Landscape, portrait and square output cover the longer videos and shorter clips.

The XL cinematic race intro.

The screenshot tools cover menus, starting grids, tracks and weapon effects too. Agents can select and organize the captures with their settings and source details. A recorded race can be reviewed first, then used for footage in an update.

Learning pilots

There are two different uses of AI here. The development agent works on code and tools; the learned pilot is a model selecting controls during a race.

The pilot gets information about speed and direction, road geometry ahead, nearby ships and pickups. It selects throttle, steering, airbrakes, pitch and weapon commands, which enter the simulation as player-style inputs.

Training uses Python, Gymnasium, Stable-Baselines3 and PyTorch, with PPO as the learning algorithm. Native workers run NullG's race simulation, allowing several driving attempts in parallel while training updates the model.

RL evaluation replay on Gare d'Europa

A short run checks the setup and controls. Longer runs save checkpoints for evaluation on selected tracks and race configurations. Settings and seeds are retained so the checks can be repeated.

The evaluations measure completion, time, damage and steering smoothness. Traffic and combat runs also look at placing, pickups and weapon timing. A checkpoint is just a saved stage of training; it still needs evaluation before being approved for gameplay.

Replays help explain the numbers. A chase view shows the ship working through a corner, while an overhead view shows the surrounding traffic. Both can be compared with the controls and metrics recorded during the race.

Overhead RL evaluation replay with colored racer markers

The exported pilot runs in native C++, with Python handling the training. Saved checkpoints can be compared using the same race setup, and agents can run those comparisons and prepare the replays for review.

An AI-driving training clip from the NullG playlist.

The reinforcement-learning page covers the training integration, and the MCP tooling page describes the inspection tools.

Keeping the project updated

I'm also using the agent-assisted workflow for projectable.me. The agent starts with git history, project documentation and relevant captures, prepares an illustrated article and saves a draft. I can then review and edit it on the site before publication. This post was prepared that way, using repository history for the timeline and existing engine captures for the images.

There’s now a playable racer underneath all this tooling: weapons, computer-controlled opponents, local split-screen, LAN and private online rooms.

Two-player vertical split-screen racing with WipEout XL content in NullG

Original ships and tracks, sound, and handling for gamepad and simulator use remain part of the longer-term work. Motion output, positional audio and multiple displays are still part of the pod plan.

The project pages have the engine details, the video playlist has development footage, and further updates are collected in the project blog.