Categories
Game Development

Building “Hello World Chase”: A libGDX Mini-Game, and a QA Pass on My Own Code

I recently put together a tiny arcade game in libGDX called Hello World Chase. The premise is simple: you’re the text string “Hello World”, dodging (and shooting) enemies made of literal bug names — “Bug”, “Lag”, “Error”, “Crash”, “Null” — while the game speeds up the longer you survive. It’s a fun little exercise in game-loop basics: input handling, collision detection, spawning, and UI with libGDX’s Scene2D.

What the game actually does

  • Main extends libGDX’s Game class and owns a shared Skin (fonts, colors, button styles) so both screens can reuse the same look.
  • MenuScreen is a simple Scene2D Stage with a title label and two buttons: New Game and Exit.
  • GameScreen is where the action happens:
  • The player is literally the string “Hello World”, moving at a constant speed in whatever direction you last pressed (arrow keys or WASD).
  • Enemies spawn from screen edges at random angles and bounce off walls.
  • Pressing Space fires a bullet (“*”) in the player’s current direction, on a cooldown.
  • Bullets that hit enemies remove both and award bonus points.
  • Touching an enemy, or drifting off the edge of the screen, ends the run.
  • Everything ramps up over time: player speed increases, enemy spawn interval shrinks, enemy speed scales with elapsed time.
  • A HUD (score, speed, enemy count) and a Game Over overlay round it out.
  • It’s a compact, self-contained example of a full mini game loop — menu, gameplay, restart, all in one file.

The QA pass

To make the game’s behavior actually testable, I pulled the core simulation out of the libGDX GameScreen and into its own file, GameLogic.java — a plain Java class with no rendering dependencies, just player movement, enemy spawning, bullet updates, collisions, and scoring. Alongside it, I wrote GameLogicTest.java, a JUnit 5 suite that exercises GameLogic directly: movement and boundary checks, shooting cooldown timing, enemy spawning with a seeded Random for determinism, bullet-enemy collisions and scoring, and precise edge cases around player-enemy collision (like adjacent-but-not-touching versus one-pixel-overlap). Separating logic from rendering this way meant I could test the actual rules of the game.

None of these issues stop the game from working — it runs fine and is fun to play for a few minutes. But that’s the point of a QA pass: small bugs that don’t matter now are the ones that confuse players later or cause problems once you add more features. Reviewing your own project like it’s someone else’s pull request is a simple way to catch that stuff early.

RunOnuR / Summer of 2026