Coding and Debugging

Table of Contents

This week’s work turned out to be less about features and more about systems. From UI planning to debugging some stubborn worker unit behavior, the week was full of behind-the-scenes improvements — even if there’s not much new to show visually.

UI Planning (And Reworking Camera Controls)

My original UI was pretty simple: it displayed selected unit count and available resources. After implementing unit production, I added a contextual “produce unit” button — which worked fine for a time.

My next goal was to implement command buttons when units are selected: Move, Attack-Move, Stop, and Hold Position. But right away I hit a problem: my current camera controls use the WASD keys — which conflicted with the typical QWEASD layout I had in mind for unit commands.

Fix: Switched to Edge Scrolling

Before I could do anything UI-related, I had to swap keyboard navigation for edge-scrolling, which also opens the door for camera hotkeys in the future. It wasn’t planned, but necessary and didn’t want to postpone it.

Refactoring the Select Manager

During this process, I realized that my SelectManager was handling both unit selection and command issuing (which included unit production). That was a code I wrote for testing and I never had time to do it right. I decided to decouple these responsibilities using an interface for special commands.

This led to a broader refactor where I:

  • Changed SelectManager to broadcast selection changes via an event (observer pattern)
  • Allowed other UI systems to simply listen to selection updates
  • Re-routed unit production so the Production UI notifies the FactionManager, which then forwards signals to the correct ProductionManager based on selected units

This cleanup gives me much more flexibility and should reduce bugs in the long run — even if it ate a few days of dev time.

Combat Bug: Workers Were Ignoring Orders

While testing the new command system, I found that worker units weren’t entering combat when issued an attack-move command.

Some workers would just walk past enemies. Others switched to “move” instead of “attack-move.” Here’s what I discovered:

  • The command was being applied per unit in a loop, but inconsistently
  • The worker’s FSM (finite state machine) was immediately switching to its resource-gathering state, even during combat

Fixes:

  • Adjusted command dispatch logic so it treats all selected units consistently
  • Updated the worker FSM to make combat a priority if the worker is already in combat; otherwise it should be ok that worker will gather resources even when attacked

It took some time, but worker combat now works as expected again.

The Case of the Disappearing Units

During mass production testing, I noticed some units were spawning under the ground and falling endlessly.

Turns out instantiating hundreds of game objects in a single frame causes all sorts of problems.

Fix:

  • Limited instantiating to a single unit per frame (could be visually noticable but probably I will add some randomness to production time anyway)
  • Double checking unit spawn position; if the unit is too close to the ground it gets moved up before activation

Performance Gains (But Nothing to Show)

All these improvements (especially the event-based selection system) improved performance quite a bit — especially when controlling 100+ units. But since I haven’t shown videos with more than ~20 units yet, and because videos are recorded at fixed framerates, the gains aren’t something I can easily show.

Still, it feels good to know the engine is becoming more robust under the hood. Also adding new features should be less time consuming from now on.

TL;DR

  • Switched from keyboard map movement to edge scrolling
  • Refactored selection/command systems using observer pattern
  • Fixed worker combat bugs in FSM logic
  • Patched unit spawning to prevent falling through the ground
  • Improved performance at scale (even if it’s not visible yet)

Nothing flashy to show but I’m satisfied with overall progress.

Until next time!