Projects
C Game Systems

Retro Game

A terminal retro game with a C game loop, map generation, monster timing, rendering, and multiplayer-oriented branches.

Problem

Lower-level game code breaks down when timing, input, rendering, state updates, and shutdown are blurred together; the project needed a readable loop with explicit system boundaries.

What I Built

Built and organized the C gameplay loop across input handling, map generation, frame rendering, timed monster movement, move resolution, multiplayer branches, and cleanup.

Hardest Tradeoff

I kept the main lifecycle explicit rather than abstracting it too early, because readable control flow is more valuable than clever structure in this kind of C system.

Result / Proof

The result is lower-level proof that I can reason about state, timing, lifecycle cleanup, and system boundaries outside a web application stack.

Outcomes
  • Improves workflow reliability by keeping input, render, timer, multiplayer, and shutdown paths explicit.
  • Tested as a lower-level C systems exercise across map generation, timed monster movement, and multiplayer-oriented branches.
  • Reduces debugging ambiguity by making lifecycle cleanup and state transitions visible in the main loop.
Architecture Sketch

The loop processes input, advances monster timing, rebuilds map state, renders the frame, applies player movement, and shuts down cleanly.

  1. Input
  2. Game state
  3. Timed monsters
  4. Map render
  5. Move result
  6. Shutdown
Recently Improved

What changed in the proof surface.

  • Framed the private source excerpt around lifecycle clarity instead of exposing private repository details.
  • Identified deterministic scripted tests as the most useful next hardening step.
Proof Points

What this project demonstrates.

  • Coordinates input, rendering, and game-state updates.
  • Uses timed monster movement through a thread manager.
  • Keeps multiplayer server behavior in the main gameplay flow.

The result is lower-level proof that I can reason about state, timing, lifecycle cleanup, and system boundaries outside a web application stack.

Retro Game / Chstephan23/retro-gaming-project
  1. void play_game(GameState* state, GameMode mode)
  2. {
  3. ThreadManager tm = { 0 };
  4. threading_manager_start(&tm);
  5. timeout(32);
  6. while (state->is_alive)
  7. {
  8. InputAction action = process_input(state);
  9. if (action == INPUT_QUIT)
  10. break;
  11. if (!move_monster_on_timer(state, &tm))
  12. break;
  13. create_map(state);
  14. render_game(state);
  15. int result = move_hero(state);
  16. apply_move_result(state, result);
  17. if (mode == MODE_MULTIPLAYER_SERVER)
  18. {
  19. int result_2 = move_hero_2(state);
  20. apply_move_result(state, result_2);
  21. }
  22. }
  23. render_game_over(state);
  24. threading_manager_shutdown(&tm);
  25. }
Line 14Lifecycle stays explicit.

Input, timed movement, rendering, state application, and shutdown remain visible in the main loop.

2026 · Harrison Stephan · Building Calm, Reliable Software Systems