Skip to content

Mini Space Shooter: a pixel-art Linux space shooter whose enemies learn how you fly

Open-source software · 2 min read · updated

Mini Space Shooter is a small pixel-art space shooter for Linux, written in C11 and C++17. It has endless levels, and its enemies use online learners to adapt their movement and tactics to how you fly. Raw difficulty is capped by hard limits, so later levels add tactical variety rather than unlimited speed or bullet counts.

Platform
Linux (Wayland and X11)
Language
C / C++
Licence
MIT
Requires
  • build-essential, libx11-dev, libxext-dev
  • Optional: SDL2 runtime for native Wayland
Run
./run.sh from the repository folder
Mini Space Shooter title screen: pixel-art logo, menu with Start Run, Leaderboard, Medal Wall, Controls and Quit.

How do I run it?

./run.sh

Building needs build-essential, libx11-dev and libxext-dev. On a Wayland desktop the game uses the optional SDL2 runtime (libsdl2-2.0-0) for a native window and needs no SDL headers; on X11, or when native Wayland is unavailable, it uses its Xlib renderer. Audio loads ALSA or PulseAudio dynamically and can run silently.

If an icon appears but no window opens, choose the backend explicitly: MSS_VIDEO_BACKEND=wayland ./run.sh or MSS_VIDEO_BACKEND=x11 ./run.sh. The README documents a GNOME/Wayland case where the X11 window stayed unmapped, which the native Wayland path bypasses.

What limits keep the difficulty fair?

LimitValue
Enemy bullet speed, including horizontal movement74 px/s
Enemy horizontal / vertical speed36 / 46 px/s
Minimum time between volleys from one enemy0.55 s
Enemies / enemy bullets on screen12 / 24
Minimum spawn interval0.85 s
Minimum new-shot reaction time0.30 s
Post-hit ceasefire1.10 s
Scheduled inbound corridors per arrival windowAt most 4 of 5

The README is explicit that the corridor rule concerns straight bullet trajectories at the bottom row. It is not a proof that a player can reach the corridor from every position, and human playtesting is still needed for balance and feel.

How do the enemies learn?

All gameplay learners are allocation-free and written in the project's own src/cpp/ml.*:

  • A two-layer MLP chooses advance, strafe left or right, or retreat, trained by policy gradient (the full softmax entropy derivative, checked against finite differences).
  • An intent model learns from features 15 simulation steps earlier and predicts from current features.
  • A stress model uses a 120-step delayed window of recent damage.
  • An eight-arm bandit ages its evidence, so it can change preference as the player changes.
  • Online k-means with bounded history groups play styles; tactics follow the cluster's measured style.

Learning survives restarts within the same process but is not saved between launches.

What are the controls?

KeyAction
Arrows or WASDMove
Space, Z or JFire
Esc or PPause
1, 2, 3, 4Buy Scout, Wing, Cruiser, Titan
M, NMute all audio, toggle music
F1Learning and difficulty overlay

How is it tested, and where is progress saved?

./run.sh test runs headless regression tests (35 according to the README), and strict, sanitize, shots, audio-test and window-test cover warnings-as-errors builds, AddressSanitizer and UBSan, screenshots of every screen, audio, and a real-window input test. The save is ~/.local/share/mini-space-shooter/save.txt (or under $XDG_DATA_HOME); writes use a temporary file and an atomic rename, and --reset-save explicitly replaces it with defaults.

Quick answers

Does the game keep getting harder forever?
No. Raw difficulty has hard limits, such as an enemy bullet speed of 74 px/s and a minimum of 0.55 s between volleys from one enemy. Later levels add tactical variation instead.
Does the enemy learning carry over between sessions?
Not across launches. Learning survives restarts in the same process but is not persisted to disk.
Where is my progress saved?
In ~/.local/share/mini-space-shooter/save.txt, or under $XDG_DATA_HOME/mini-space-shooter/save.txt.
What if no window opens on Wayland?
Select the backend explicitly with MSS_VIDEO_BACKEND=wayland ./run.sh or MSS_VIDEO_BACKEND=x11 ./run.sh. The default launcher already picks native Wayland when WAYLAND_DISPLAY is set.

More on Downloads