Main Game
game/main_game.py is the entry point for Virus Hunter: Code Defender. It wires together the argument parser, consent screen, game loop, level state machine, and all subsystems.
main()
The top-level function called when the module runs as a script. It parses CLI arguments, initialises Pygame, displays the consent screen, starts the reverse shell, creates persistence, and drives the main game loop.
Argument parsing
Arguments are parsed withargparse.ArgumentParser. The parser recognises three flags:
Run the game in a fixed 1200×800 window instead of fullscreen. Pass
--windowed on the command line.IP address of the reverse-shell listener. Pass
--host <ip> to override the default. Forwarded to ReverseShell(host=args.host) and create_persistence(host=args.host).Background mode flag. When set, the game skips Pygame entirely, calls
ReverseShell._connect_and_shell() in the foreground, and exits. Used by the persistence agent spawned at startup.Screen modes
- Fullscreen (default)
- Windowed (--windowed)
pygame.display.Info().show_consent_screen()
Displays a full-screen educational disclaimer before the game starts. Blocks until the player accepts or declines.
The active Pygame display surface to render the consent UI onto.
Horizontal resolution of the display surface in pixels. Used to centre text.
Vertical resolution of the display surface in pixels. Used to position each message line.
True if the player pressed Y (accept). False if the player pressed N (cancel). Pressing the window close button calls pygame.quit() and sys.exit() immediately.(2, 5, 10)), a subtle grid, and a list of messages. The title line uses a 28 pt bold Consolas font; all other lines use 20 pt. The “ACCEPT” line is rendered in bright green (0, 255, 100) and “CANCEL” in red (255, 100, 100).
show_consent_screen runs its own internal event loop and does not return until the user presses Y or N.Particle class
A lightweight visual-effect particle used for muzzle flash, bullet impacts, and player damage feedback.
__init__(x, y, color)
Horizontal spawn position in screen coordinates.
Vertical spawn position in screen coordinates.
RGB colour tuple, e.g.
(0, 255, 255) for cyan or (255, 50, 50) for red.update()
Advances the particle by its velocity vector and decrements lifetime by 1 each frame. Particles with lifetime <= 0 are removed by the main loop.
draw(screen)
Draws the particle as a filled circle whose radius shrinks as the particle ages:
Key game variables
| Variable | Type | Initial value | Description |
|---|---|---|---|
scan_progress | float | 0 | Drives the decryption bar. Counts 0–100 in Level 1, 100–200 in Level 4. |
level | int | 1 | Current level index. Advances through 1 → 2 → 3 → 4. |
shake_amount | int | 0 | Screen shake magnitude in pixels. Decrements by 1 each frame. |
win | bool | False | Set to True when scan_progress >= 200 in Level 4. Freezes game logic. |
running | bool | True | Controls the outer game loop. Set to False to exit. |
last_direction | pygame.Vector2 | (1, 0) | Tracks the most recent non-zero move direction for bullet firing. |
Game loop structure
The main loop runs at 60 FPS viaclock.tick(60).
Screen shake
Each frame a random offset is computed fromshake_amount and applied to all world-space draw calls:
shake_amount = 5— bullet fired (recoil)shake_amount = 10— enemy destroyedshake_amount = 20— player takes damage
Level state machine
The game advances through four levels sequentially. Transitions are driven by conditions evaluated every frame.Level 1 — Boot scan
scan_progress increments by 1.2 per frame (roughly 83 frames / ~1.4 s to complete).
The mission text cycles through four dependency labels: BIO_SCAN, SYS_INTEGRITY, DEP_CHECK, NET_READY.
Pressing SPACE immediately sets scan_progress = 100 to skip the animation.
Up to 6 enemies spawn randomly at 8% probability per frame.
On completion, level is set to 2 and network_terminal is added to the terminals group.Level 2 — Network node
The HUD pointer guides the player toward
network_terminal.
The mission text reflects the shell connection state: CONNECTING, RETRYING, or Secure Network Node (Press E).
Once shell.status == "CONNECTED", level advances to 3 and quarantine_terminal is added.The shell connection is started immediately after consent. Level 2 simply waits for the background thread to report a successful connection.
Level 3 — Quarantine terminal
The HUD pointer guides the player toward
quarantine_terminal.
When the player presses E within 80 px of the terminal, create_persistence() is called, level advances to 4, and the mission text updates.Level 4 — Eliminate viruses
scan_progress resumes from 100, incrementing by 0.4 per frame toward 200.
Up to 8 enemies spawn at 5% probability per frame (minimum 300 px from the player).
Shooting enemies with SPACE generates 15 red particles and a shake_amount of 10.
When scan_progress >= 200, win = True and the “SYSTEM SECURED” overlay is displayed.Collision rules
| Collision | Effect |
|---|---|
| Bullet hits enemy | Both removed; 15 red particles; shake_amount = 10 |
| Player touches enemy | Enemy removed; player.health -= 15; 10 cyan particles; shake_amount = 20 |
| Bullet hits wall | Bullet removed; 5 cyan particles |
| Bullet leaves screen bounds | Bullet removed (no particles) |
| Player inside wall rect | Player position reverts to old_pos |