A space trading and combat game for the M5Stack Cardputer.
Fly between sixteen star systems, trade cargo, take jobs from planets and fight pirates.
The whole game runs on the device, with no phone, account or internet.
⬇️ Download firmware ·
Download the 41-second demo video, captured from the Cardputer's own screen at 25 frames per second.
In the demo:
- The ship flies through the asteroid belt of TRIX II and lands. The landing menu opens.
- Autolock turns the nose onto a pirate. A missile hits it and the lasers finish it, for a 25 CR bounty.
- The ship flies into the TRIX jump gate, picks ALTAAR on the galactic chart and jumps.
- Autolock again, then the 3D scanner while the ship pitches over in deep space.
- A red hit arc on the scanner rim follows an attacker as the ship turns.
- A missile launch, a hit, and a laser kill.
- The system map zooms in on the gate and marks a pirate as hostile.
- The HUD shows the distance to the sun in deep space, then "ENTERING ALTAAR" on the way back in.
Hazke is a space sim in the style of Elite, built for a 240×135 screen and a 56-key keyboard. You fly in full 3D with pitch, roll and yaw. Planets are shaded polygons with rings, moons and asteroid belts. Prices move with each system's economy and government and with your reputation, and pirates, traders and patrols fly their own routes.
The game draws every frame in code on the Cardputer's ESP32-S3 and loads no image files. It generates all sixteen systems from one seed, so the galaxy is the same on every device.
| Hazke | |
|---|---|
| 🌌 Galaxy | 16 star systems, linked by jump gates |
| 🪐 Each system | a sun, one to three planets, asteroid belts, and a jump gate |
| 💰 Market | 17 goods, 3 of them illegal |
| ⚔️ Weapons | 3 laser grades, up to 4 homing missiles, an ECM, autolock |
| 📜 Jobs | 5 kinds: hunt pirates, deliver, fetch, visit, courier |
| 🏳️ Factions | 4, each with a standing from -100 to +100 |
| 🎖️ Ranks | 7, from Harmless to Deadly |
| 🖥️ Frame budget | 16 ms, about 60 frames per second |
| 💾 Saves | 5 slots in flash and 5 on the SD card, about 100 bytes each |
| 📡 Internet | Not needed |
🧭 Gyro aiming on the Cardputer ADV. Turn GYRO on in the title or pause menu, and the ship
turns when you turn the Cardputer. Hold the Cardputer still and the ship holds its heading. The keys
still work, and their turns add to the gyro's. Hold Alt to stop gyro aiming while you shift your grip.
- GYRO has five settings: OFF, 0.5X, 1X, 2X and 3X. A higher setting turns the ship further.
- You can hold the Cardputer at any angle. The game finds the real vertical with the accelerometer. Turn the Cardputer left and the ship yaws left. Tip the top edge toward you and the nose comes up. Turn it like a steering wheel and the ship rolls.
- A quick turn of the Cardputer takes over from autolock, the same way the pitch and yaw keys do.
- The original Cardputer has no gyro, so its menu shows
GYRO: N/A. - The SOUND and GYRO settings now stay the same after a reboot.
🔊 Every sound effect is new too. Effects play on separate channels, so one no longer cuts off another, and the title and pause menus have a volume setting with four levels. The display is double-buffered now, so the game draws the next frame while the screen shows the last one.
| 👍 Has | 👎 Doesn't have (yet) |
|---|---|
| Free 3D flight with pitch, roll and yaw, on the keys or the ADV's gyro | Music. There are sound effects only. |
| Trading, bounties, and looting beaten ships | Jobs that span systems. Every job stays in one system. |
| Lasers, missiles, ECM and autolock | Other ships to buy. You fly one ship and upgrade it. |
| A reputation with four factions that changes prices and patrols | Saving in flight. You save while landed on a planet. |
- Get a Cardputer. Hazke runs on the M5Stack Cardputer and the Cardputer ADV. Gyro aiming needs the ADV.
- Flash it. Pick Hazke in your launcher's app list, or download
hazke-v1.4.0-cardputer.binfrom Releases and write it at address0x0with the ESP web flasher, M5Burner oresptool.py --chip esp32s3 write_flash 0x0 hazke-v1.4.0-cardputer.bin. - Choose NEW GAME and type a name. You start next to a jump gate with 100 credits. Fly into a planet to land and trade, and fly into a jump gate to travel.
Note
The full image clears the save slots in internal flash. To upgrade and keep them, write only the
game with esptool.py --chip esp32s3 write_flash 0x10000 hazke-v1.4.0-app.bin, or copy your slots
to the SD card first with COPY in the save menu.
To build it yourself, install the M5Cardputer library in the Arduino IDE, open hazke.ino, pick
the M5Cardputer board and upload. With arduino-cli:
arduino-cli compile --fqbn esp32:esp32:m5stack_cardputer --upload -p <port> .The arrow keys are ; , . /, marked with arrows on the Cardputer.
| Key | What it does |
|---|---|
↑ ↓ |
pitch |
← → |
roll |
L ' |
yaw |
E / S |
speed up / slow down |
W or Space |
fire laser |
R / A |
cycle missile lock through ships ahead / fire a missile |
Q |
ECM |
F |
autolock, or zoom on the system map |
Tab |
next target, ships and places |
H |
hail or loot a nearby ship |
M |
system map |
| turn the Cardputer ADV | aim, with GYRO on |
Alt (hold) |
stop gyro aiming |
Enter |
confirm |
` |
back / pause |
Ctrl + Space |
screenshot to the SD card |
- Trade. Buy goods where they're cheap and sell them where they're scarce. Farm worlds sell food cheap and pay well for machinery, and industrial worlds do the opposite. Three goods are illegal, and stable governments stock less of them.
- Take jobs. Land on a planet and open the job board. Most jobs pay when you return to the planet that offered them. Courier jobs pay on arrival.
- Fight. Pirates attack on sight. Below 50% hull a ship's engines drop to half power, and below 25%
its weapons stop working. Fly up to a beaten ship and press
Hto take its cargo. - Travel. Fly into a jump gate to open the galactic chart. You can jump only to systems linked by a gate, and a jump costs 10 CR per light year.
Kills, trades and jobs raise or lower your standing with four factions. If your standing with a faction drops below -30, its patrols attack you. Standing also moves prices by up to 20% either way.
A shield recharges fully in about 37 seconds as long as it stays above zero. Once it hits zero it stays down until you pay for a repair. Only the equipment shop can repair hull damage.
| Equipment | Price | What it does |
|---|---|---|
| Repair hull | 10 CR per 10% | fixes hull damage |
| Repair shield | 100 CR | brings a downed shield back |
| Missile | 30 CR | a homing missile, up to 4 |
| ECM | 600 CR | Q blows up nearby missiles |
| Autolock | 300 CR | F turns the ship onto your target |
| Large hold | 400 CR | cargo space from 20 t to 35 t |
| Beam laser | 1000 CR | more damage and range |
| Military laser | 6000 CR | the best laser, needs the beam laser first |
Save from the landing menu of any planet, and load from the title screen. There are five slots in
internal flash and five on the microSD card, and COPY in the save menu copies a slot from one to the
other. Saves from older versions load in newer ones. A save made by a newer version shows as
NEWER VERSION, and the game leaves it alone.
v1.4 uses the same save format as v1.3, so the two read each other's slots. v1.2 saves load in both, but once you save a slot in v1.3 or later, v1.2 can't read it. The SOUND and GYRO settings are kept apart from the slots and apply to every commander.
- One header per module.
hazke.inoruns the screen state machine and the frame loop. Each system and screen lives in its own.hfile, and the Arduino IDE is the only build tool. - The galaxy comes from one seed. The game regenerates systems, gate links, planets and prices from the seed when it needs them, so a save only stores your own state.
- 3D in software. Planets are shaded icospheres and ships are filled outlines with edges.
Raster.hclips every line and triangle to the view first. A shape far off-screen used to take about 4 ms to draw, and now takes 0.02 ms. - Two frame buffers. The game draws into one while DMA sends the other to the screen.
- Sound is synthesized at boot.
Audio.hbuilds every effect from oscillators and filtered noise into an 8-bit sample bank, and the speaker task mixes them on separate channels. - Saves carry a version and a checksum. When the format changes,
SaveFormat.hupgrades older saves step by step as they load.Settings.hkeeps SOUND and GYRO in NVS, outside the slots, so menu options never change the save format. - Gyro turns follow how you hold the Cardputer.
Gyro.htracks the vertical with a complementary filter on the accelerometer, then splits each gyro reading into yaw about that vertical, pitch and roll. While the Cardputer is still, it measures the gyro's drift and subtracts it.
🖥️ Serial console and frame capture
With the Cardputer connected over USB, a serial terminal at 115200 baud accepts these commands:
| Command | What it does |
|---|---|
status |
prints the commander, screen, credits and system |
credits <CR> |
sets your credits |
save [1-5] [sd|int] |
saves to a slot |
cap on / cap off |
pauses the game so it only advances on step / rec |
keys <chars> |
holds those keys down (T is Tab, N is Enter) |
step <n> / rec <n> |
runs n frames of 1/25 s each; rec also sends each frame |
shot |
sends the current frame |
imu |
prints the IMU reading, the gyro drift and the turn rates it adds |
The firmware sends frames as run-length packed RGB565, and Capture.h describes the format.
tools/capture.py sends these commands from a computer and saves the frames as PNGs. Every clip and
screenshot in this README comes from it.
python3 tools/capture.py autolock 'T*1' 'f*1r' '_*80r' # mark a target, press F, record 80 frames🗂️ Code map
hazke.ino state machine, frame loop, serial console
Config.h version, screen layout, build switches
Input.h keyboard polling and keys held by the console
Gyro.h gyro aiming on the Cardputer ADV
Settings.h SOUND and GYRO, kept in NVS
Capture.h frame capture over serial
GameState.h credits, cargo, ship, factions
Galaxy.h the 16 systems and their gate links
SolarSystem.h planets, belts and the gate in each system
SystemFlight.h 3D flight, camera, autolock, landing
NPCShip.h traders, pirates and patrols
Combat.h lasers and damage
Missile.h homing missiles and ECM
Radar.h 3D scanner and hit arcs
Cockpit.h gauges, missile rack, footer
Raster.h clipped line and triangle drawing
Ship3D.h ship models
Sky.h distant stars and space dust
Rocket.h missile art
Starfield.h hyperspace tunnel
Particles.h explosions and debris
Audio.h sound synthesis and mixing
Market.h prices and stock
Quest.h jobs
Faction.h faction standing
Rank.h combat rank
Hyperspace.h jump cost and range
SaveFormat.h save layout, checksum, upgrades between versions
SaveStore.h save slots on flash and SD
SDCard.h shared microSD setup
Screenshot.h Ctrl+Space screenshots
*Screen.h, MenuUI.h, PauseMenu.h menus and screens
📜 Changelog
- v1.4, gyro aiming
- Gyro aiming on the Cardputer ADV, with five settings and
Altto stop it. - SOUND and GYRO stay set after a reboot. Serial console
imucommand.
- Gyro aiming on the Cardputer ADV, with five settings and
- v1.3, a new cockpit and open space
- Autolock module, 3D scanner with hit arcs, segmented gauges and rocket missiles.
- A bigger system map with zoom, and red or green markers for hostile and friendly ships.
- No walls at the edge of a system, and a deep-space HUD past 30K from the sun.
- All sound effects rebuilt, with a volume setting. Double-buffered display.
- Serial console frame capture. Save format v2.
- v1.2, saves
- Five save slots in flash and five on the SD card, with copying between the two.
- A name for your commander, and yaw on
Land'.
- v1.1, controls
Tabcycles through ships as well as places. Docking prompt fixes. One back key,`.
- v1.0, the first release
- Sixteen star systems, 3D flight, a 17-good market, lasers, missiles and ECM, job boards, four factions and seven ranks.















