Toy Update, Part 2

Abstract

Problem: How do personal "toy" projects evolve through iteration, and what programming lessons emerge from casual game development?

Approach: Tim Cain walks through recent updates to his space combat toy game in Unity, covering new torpedo types, shield visuals, and the bugs that arose along the way.

Findings: Even throwaway projects benefit from iterative polish. Bugs often share root causes (invalid target states), and premature complexity (like color gradients for 1–5 hit shields) wastes effort. Code should match current needs, not imagined future ones.

Key insight: Don't write complex code early β€” keep it simple until the design demands complexity, because you'll change things later anyway.

Source: https://www.youtube.com/watch?v=wpbUuoyGPBM

Viral Photon Torpedo

Tim added a viral torpedo that converts enemy ships to fight for the player. The implementation was straightforward: he parameterized the enemy AI's target reference (previously hardcoded to the player ship) so that when hit by a viral torpedo, the enemy randomly selects another enemy ship as its new target.

Two Bugs, One Fix

Two distinct bugs emerged with similar root causes:

  • Bug 1: A converted ship destroys its target, then flies away forever β€” it had an invalid (destroyed) target and didn't know what to do.
  • Bug 2: Viral torpedo hits the last remaining enemy β€” Unity throws null reference errors because no other ships exist to target.

Both cases amounted to invalid targets (null or destroyed). The fix: when a converted ship's target becomes invalid, retarget the player. This created a nice emergent behavior β€” the viral effect "wears off" after the converted ship kills its target, and it turns hostile again.

Implosion Torpedo

The implosion torpedo went through several design iterations:

  1. First attempt: Torpedo flies a set distance, then explodes and pulls enemies in. Problem: hard to pick a good distance, and hitting an enemy before reaching it did nothing.
  2. Second attempt: Hitting an enemy disables and spins it, pulling other ships in. Problem: when the effect ended, the clustered ships just drifted apart anticlimactically.
  3. Final version: Hit an enemy β†’ implosion pulls all ships into a cluster β†’ they explode outward at high speed β†’ regain control and resume attacking. Much more satisfying.

Shield Color Changes

Tim updated enemy shields to change color based on remaining hit points: red β†’ blue β†’ white β†’ gone. He also scaled the shield size, though he found the size change wasn't very noticeable.

He's color-blind, so he relied on Unity's named color constants (Color.red, Color.blue, Color.white) rather than RGB values.

Why Not a Gradient?

Shields currently take only 1–5 hits, so Tim hardcoded color changes at fixed thresholds. He explicitly chose not to implement a smooth gradient because it's unnecessary at this scale. If shields later scale to 10–20 hits, that's when a gradient would matter.

This echoes his broader philosophy: don't add complexity before you need it. He compared it to his earlier talk about not implementing complex AI systems when simple ones suffice β€” you'll change things later, and premature complexity just makes code harder to debug.

Next Steps: Formation Flying

Tim's planned next feature is formation flying for enemy ships, where groups form up and fire simultaneously to increase damage output. This is something he implemented years ago on Star Trek: 25th Anniversary but found it made the game very difficult. He plans to integrate it into the enemy progression system, possibly having fighters launched from capital ships form formations naturally.

Takeaways for Toy Projects

  • Toys are for learning and fun β€” they don't need to ship
  • Even toys benefit from iterative improvement
  • Bugs in simple systems often share root causes
  • Keep code complexity proportional to current requirements
  • Play with your toys β€” progression happens naturally as you iterate