Dev Log 9: One Pipeline, Real Scenes

January 4th, 2026

Merry Christmas!

Over the last couple weeks, I took it slow as it was Christmas, but did make some art in my engine to celebrate!

After Cameras, Another Problem Became Obvious

After the holidays, I looked at the current state of things. After cameras became real scene entities, one thing still stood out.

Lighting was still global.

It worked. It was adjustable. But it wasn’t authored.

That meant lighting changes leaked between scenes, couldn’t be reasoned about in isolation, and didn’t actually belong to the data model yet.

If cameras needed to live in the SceneGraph to be real, lighting needed to follow the same rule.

Lighting Becomes Scene Data

RetroEngine now treats lighting as part of the scene itself.

Each scene owns its own lighting state, serialized directly into the .scene.json file alongside entities.

When a scene is loaded, its lighting is restored exactly. When a scene has no lighting block, the engine falls back to sensible defaults.

No global state leaks. No surprises.

Lighting That Fits the Engine’s Goals

RetroEngine isn’t chasing modern physically based lighting.

That would be dishonest to the aesthetic and unnecessary for the kinds of scenes this engine is meant to build.

The lighting model is intentionally simple:

This mirrors how many 90s-era games were authored, even if the underlying hardware details varied.

The result is predictable, controllable lighting that works across low-poly meshes, sprites, and CRT output without fighting the style.

Lit vs Unlit Is Now Intentional

Another important distinction landed alongside scene lighting.

By default:

That matches how these elements are usually meant to behave. Backgrounds and parallax layers stay stable. Foreground geometry gains depth and form.

For edge cases, materials can explicitly opt out of lighting. Nothing is forced, but the defaults are sane.

Sprite Features Move Into the Core Pipeline

This update also marks the end of RetroEngine’s separate 2D test renderer.

That pipeline existed for a reason. Early on, the 3D renderer couldn’t yet express everything sprites needed:

Rather than forcing those concepts into an incomplete system, a small isolated 2D path made experimentation safer.

That phase is now over.

All sprite behavior is fully supported by the same unified render path used for meshes.

Sprites are no longer special cases. They are just entities.

One Renderer, One Set of Rules

With sprite features folded into the main renderer:

Removing code is always better than keeping temporary systems alive.

From this point forward, everything that draws is part of the engine proper.

Fixing the Hard Problems: Entity Lifetime

Unifying pipelines exposed a deeper issue that couldn’t be ignored anymore.

Entity duplication and deletion were fragile. In some cases, entities could end up sharing IDs. In others, deleting an entity could crash the renderer outright.

These weren’t cosmetic bugs. They were ownership problems.

The fix wasn’t a patch. It required making entity identity and GPU ownership explicit.

Deleting an entity no longer risks invalid memory or stale GPU state.

The editor can finally be trusted not to hurt the engine.

Editor Quality-of-Life Improvements

Alongside the structural fixes, several editor pain points were cleaned up.

None of these are flashy.

But when tools lie to you, you stop trusting them.

The editor now reflects the real state of the scene accurately.

Where RetroEngine Stands Now

None of this is glamorous.

But it removes entire classes of future problems.

RetroEngine now feels less like a renderer with tools, and more like a place where a real game could live.