// blog2026-05-29
Image
Image

Return Echo Development #4

This past week with Return Echo was one of those gritty periods where I dove deep into fixing nagging issues and refining the foundation beneath everything. I spent a fair bit of time cleaning up old event handling and sharpening the separation between simulation and ECS boundaries, which was a bit of a headache but ultimately feels worthwhile. It's not flashy but it's the kind of groundwork that keeps the whole thing running smoothly as I keep building out the game's core systems.

What I fixed and improved

I tackled a bunch of issues around the galaxy map and UI rendering. For example, the map now correctly uses the right font, which was surprisingly tricky to pin down given the layered rendering approach. I also pushed it fully grayscale, which really suits the style I want for the GUI and gives the visuals a more consistent, cinematic feel-especially with the custom grayscale shader I added.

On the visual effects side, the bloom renderer got some love, and it now looks much closer to what I imagine-bright and atmospheric without overpowering the scene. The engine trails and hyperspace effects are cleaned up too, fixing bugs where trails were shrinking or fading in odd ways. Tweaking the render pass orders and updating lens flare handling were all part of smoothing out the polish.

On the code architecture side, I made significant headway in clearing up event handling. I removed lots of old global events that cluttered interaction logic, replacing them with more targeted listeners and snapshot-based state tracking. This was part of a broader effort to split out concerns better, like how I made a new `GuiFocusSnapshot` to separate GUI focus from player ship control, and dec coupled the station HUD from docked ships by creating a dedicated `DockedShipSnapshot` store.

Speaking of snapshots, I also advanced the move away from using the ECS directly in simulation modules. The static scan highlighted boundary leaks where simulation code still dealt directly with ECS concepts or entity IDs. I'm working through those by pushing simulation to rely on stable ObjectId references or registries instead, which should cut cross-module coupling and reduce risk down the line.

One major hop was upgrading to lwjgl3 and updating libgdx to 1.14.1. It's a boost on the graphics side and also lays the path for more modern input and rendering capabilities.

What I learned

One big takeaway is how deeply the old global event system still influenced a lot of the game logic-even in places where a more focused approach would be cleaner. Trying to untangle that has been a slow burn but is definitely making the code more modular and easier to reason about.

Working through the ECS and simulation boundary highlights how easily subtle dependencies creep in. It's not just about entity IDs leaking out but about making sure simulation stays freely refactorable and independent of the ECS's lifecycle. Using generic snapshot stores to replace ECS entity references helps a lot with that, but it's a process that will take time to commit fully across the codebase.

The rendering improvements confirmed the value of moving constants and magic numbers into a dedicated tuning class. It makes experimentation much easier and the rendering pipeline less brittle.

What I got wrong

I underestimated how much old patterns like global events and ECS entanglement would slow me down. I thought cleaning those up would be faster-turns out they're woven into many subsystems in ways that aren't always obvious. Some parts of the code got more complex temporarily as I moved listeners to snapshot stores and reworked event flows.

On the visual side, the bloom and trail fixes involved trial and error, and I initially introduced some side effects in the rendering order that broke other UI elements. I had to backtrack and rethink the render pass approach.

Also, I pushed the font and grayscale UI changes too quickly on top of other refactors, which caused a few rendering glitches in the galaxy map before I fixed the font usage properly.

Why it matters for Return Echo

All this cleanup and architecture tightening is far from glamorous but absolutely essential for Return Echo's long-term stability and flexibility. Getting the ECS-simulation separation right will make future NPC and world simulation features more scalable and less error-prone. Improving rendering fidelity and UI consistency enhances player immersion without wasting resources or causing bugs.

By reducing reliance on global events and shifting toward snapshots and targeted listeners, I'm setting up the codebase to handle more complex game states and multisession flows more confidently. Plus, upgrading the graphics stack is a small but meaningful investment toward smoother performance and better visual effects that'll help Return Echo stand out.

Where I'm heading next

Next up, I want to double down on pushing the simulation module fully out of directly referencing ECS entities. That means refactoring classes flagged by the static scan, especially around bubble and galaxy sector logic, to rely solely on ObjectIds or dedicated registries. This will be fiddly but it pays off in modularity and easier testing.

On the gameplay front, I'm going to start building out richer NPC behavior now that the core snapshot and event infrastructure is more robust and less tangled. Also aiming to improve camera tour features next-fixing some lingering bugs and making transitions smoother-to better showcase the galaxy map and star systems in-game.

Finally, I'll continue refining the UI look and feel, experimenting with grayscale shaders and maybe adding some subtle color highlights to bring out important information without losing the style consistency I want.