Week 6: Turning Knobs

I spent way too long building wheel controls for tuning the engine. But they work now!

A sketched engine tuning system: The pipes eventually lead to two engines, one labeled primary and the other labeled secondary. Therea are several magnetic coils surrounding the pipes.
I mean, it's... it's just a sketch, but it's something!

This week I wanted to add a screen to tune the ship engine in Running Late. I sketched out a UI, and then threw down some pipes and handwheels to open and close those pipes. I figured I'd spice it up a little and make it so turning the wheels meant "grabbing" them (clicking) and then moving the mouse around in a circle.

But making a wheel turn requires solving a bunch of problems I didn't see coming. I ended up deep in Unreal Motion Graphics lore, event architecture, and Blueprint refactoring.

Handwheels

A little wheel you can turn as a UI widget sounds straightforward, and maybe it would be if I were doing things in a normal way. I just needed to track where the mouse is relative to the wheel center, convert that to an angle, and map the angle to something useful. Turn the wheel in response to changes in that angle and it will feel like you've grabbed onto a physical object.

But I'm working with the diegetic UI system from Week 5, which adds layers of coordinate conversion and component chicanery. Plus, finding the widget center required some hierarchy traversal, and I had to do some value clamping and massaging to keep the wheels from spinning endlessly. The result is a fun little gizmo, but because a lot of these concepts were new to me, it took hours to get to a working widget.

Refactoring

Another place where things were more complex than hoped was with reusing the wheel logic in more than one place. I wanted to create a widget that I could embed in my UI multiple times. This would let me reuse the code from the first valve without having to copy and paste.

Each wheel controls a different parameter. One adjusts overall fuel mixture, while the other two handle catalyst ratios for each separate engine (sort of like the air/fuel balance in a car engine). It would be simpler to hardcode each wheel to its specific parameter. But I don't have a complete design up front, and I've already found three different wheels I want. Heaven forbid I decide to add a fourth for coolant and have to copy and paste all over again.

An editor showing the isolated handwheel widget that is reused several times in the engine tuning screen.
The venerable handwheel, in its native habitat, the widget designer.

Event Dispatchers

I wanted my valves to say "my value changed" without knowing who all might care. And anyone that does care can just ask to be told when the value is updated. UE5 has event dispatchers for exactly this situation. I threw a dispatcher onto my handwheel, and interested parties can ask to be told when the value changes.

The tricky part was setting up the connections at runtime. I've moved all the engine values out of Actor objects—the kinds of objects you see when the game is running—and into pure objects that only contain variables and logic. They don't have the same construction timing, and therefore, can't sign up for events themselves. I ended up cramming the wiring logic into the navigation console itself, which seems very fitting.

Engine Simulation

Once the events were firing, plugging in actual engine calculations was straightforward. There's a primary and a secondary engine, which both separately have inputs for fuel and catalyst. The closer they get to an optimal mix, the more "efficiency" they produce (and the faster the ship will go.) But also, the more heat they'll produce. Heat affects performance too, building up over time and requiring coolant management.

Or it will, once I make that happen. Right now only catalyst controls are working, but I've got a lot of additional controls to add, including engine timing, emergency cut-offs, and fuel enrichment.

Architecture vs Progress

Building all this took a lot longer than I expected. I spent hours on Blueprint event references when I could have connected handwheels directly to engine variables. It probably took half a day just to figure out how to map mouse inputs correctly. But that's the job. You learn something new every time you touch the editor. And the reusable architecture will pay off, either here in Running Late, or in another game down the road.

What It Actually Does

From the player's perspective, you can walk up to the navigation terminal, switch to engine tuning, and turn handwheels to adjust catalyst levels on both engines. The wheels rotate as you drag them and engine efficiency responds in real time.

An in-game computer screen showing the implemented engine tuning screen. All of the same systems are there, but the handwheels are textured graphics, as are the magnetic rings.
She may not look like much, but she's got it where it counts, kid.

It's a small piece of the full engine management system, but it works smoothly and feels responsive. The wheels behave like physical controls instead of abstract UI elements, which I personally love.

Soon I'll add fuel controls, temperature displays, and more. The propulsion system is ready for me to add more complexity. But I need to hit some basic affordances first - win/loss conditions, menus, that sort of thing. We're six weeks in and don't have a game loop yet. That changes next week.