{"id":51344069,"url":"https://github.com/therezor/hazke","last_synced_at":"2026-07-02T10:02:20.883Z","repository":{"id":361392964,"uuid":"1254262902","full_name":"therezor/hazke","owner":"therezor","description":"An open-universe space-sim game for the M5Stack Cardputer - trade, fight and exploreWritten in C++.","archived":false,"fork":false,"pushed_at":"2026-06-25T11:10:33.000Z","size":339,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-25T13:07:07.115Z","etag":null,"topics":["cardputer","cardputer-adv","game","space-sim"],"latest_commit_sha":null,"homepage":"https://hazke.com","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/therezor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-30T10:51:03.000Z","updated_at":"2026-06-25T12:24:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/therezor/hazke","commit_stats":null,"previous_names":["therezor/hazke"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/therezor/hazke","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therezor%2Fhazke","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therezor%2Fhazke/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therezor%2Fhazke/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therezor%2Fhazke/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/therezor","download_url":"https://codeload.github.com/therezor/hazke/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/therezor%2Fhazke/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35041999,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cardputer","cardputer-adv","game","space-sim"],"created_at":"2026-07-02T10:02:20.053Z","updated_at":"2026-07-02T10:02:20.876Z","avatar_url":"https://github.com/therezor.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hazke\n\n**Trade. Hunt. Survive.** An open-universe space sim for the M5Stack\nCardputer, inspired by *Parkan: Imperial Chronicles* and *Galaxy on\nFire 2*. Fly between sixteen procedurally-generated star systems, land\non planets, run cargo or hunt pirates for one of four factions, and\nshape your standing across the galaxy — all on a 240×135 display.\n\nNo assets or code are copied from the inspirations; the galaxy,\ncommodity table, ship silhouettes and faction roster are all original.\n\n---\n\n## Hardware\n\n- **Board:** M5Stack Cardputer (ESP32-S3, ST7789 240×135 display,\n  56-key keyboard, PWM beeper).\n- Built with the Arduino IDE / Arduino CLI against the `M5Cardputer`\n  / `M5Unified` libraries.\n\n## Build \u0026 flash\n\n1. Open `hazke.ino` in the Arduino IDE.\n2. Install the **M5Cardputer** library via Library Manager (pulls\n   `M5Unified` and `M5GFX` automatically).\n3. Board: `M5Stack` → `M5Cardputer`. Port: whichever USB-C tty your\n   Cardputer enumerates as.\n4. Upload. The first boot drops you on the title screen.\n\n## Saving\n\nThe game has 5 save slots on each of two storage backends: **internal\nflash** (LittleFS on the stock `spiffs` partition, formatted on first\nuse) and the **microSD card**. Saving happens while landed on a planet\n(`SAVE GAME` on the landing menu); loading (`LOAD GAME` on the title\nscreen) puts you back docked at that planet. In the slot picker,\nLEFT/RIGHT switches the storage backend and `ENTER` on a slot offers\nLOAD/SAVE, COPY (backup/restore the slot to the other backend), and\nDELETE.\n\nSave files (`/hazke/saves/slotN.sav`, ~100 bytes) carry a format\nversion and a CRC. When a future release changes the format, old files\nare upgraded automatically at load time through chained transformers in\n`SaveFormat.h` — a save from any older version keeps working. Files\nwritten by a *newer* firmware show as `NEWER VERSION` and are left\nuntouched.\n\n## Controls\n\nCardputer keycaps in brackets show the arrow legend printed on the\ndevice.\n\n| Key                | Action |\n|--------------------|--------|\n| `;` / `.` (↑ / ↓)  | Pitch up / down |\n| `,` / `/` (← / →)  | Roll left / right |\n| `L` / `'`          | Yaw left / right |\n| `E`                | Accelerate |\n| `S`                | Brake |\n| `W` or `Space`     | Fire laser |\n| `R`                | Cycle missile lock |\n| `A`                | Fire missile at current lock |\n| `Q`                | Fire ECM burst (if installed) |\n| `Tab`              | Cycle target POI |\n| `H`                | Dock with nearby ship (trade / loot) |\n| `M`                | Open local system map |\n| `Enter`            | Confirm in menus |\n| `` ` ``             | Back / pause |\n\n---\n\n## How it plays\n\nYou start in your ship at a jump gate with 100 CR and an empty hold.\nFrom there you can:\n\n- **Trade.** Buy commodities cheap in their home market and sell them\n  where they're rare. Agricultural goods are cheap on farm worlds and\n  dear on industrial worlds, and vice versa. Hailing an NPC in flight\n  opens a separate buy/sell dialog with its own spread.\n- **Run quests.** Land on a planet, open its quest board, and accept\n  one of four offered contracts. Quests are local-system-only and\n  return-to-origin: you take a job at planet A, complete it somewhere\n  in the same system, and fly back to A for payment.\n- **Hunt.** Kill pirates for bounties and reputation with lawful\n  factions. Patrol quests force a fixed pirate roster to spawn after\n  launch, so the hunt is winnable even in peaceful systems. NPCs are\n  slower than you at full throttle, so you can always either outrun a\n  fight or close in on a wounded one. Damage thresholds apply to both\n  sides: below 50% hull engines drop to half thrust, below 25% hull\n  weapons go offline. A ship that's been beaten below 25% can no\n  longer shoot back — `H` then opens a loot dialog where you grab its\n  cargo for free.\n- **Travel.** Pay 10 CR per LY at a jump gate to hyperspace to a\n  neighbouring system. Only direct gate links are reachable; the\n  galaxy is a graph, not a free-distance grid.\n- **Upgrade.** Spend earnings at the EQUIP shop on missiles, an ECM,\n  a larger hold, better lasers, or hull and shield repairs.\n\nDie (hull → 0) and the game-over screen offers a restart.\n\n---\n\n## Game systems\n\n### Galaxy\n\nSixteen systems generated deterministically from a single LCG seed.\nEach has a name, government, economy, tech level, population, and\nproductivity. A gate adjacency graph (2–4 neighbours per system, made\nsymmetric) is the only path between systems — the chart screen draws\nthis graph and dims any system without a direct link to your current\nlocation.\n\nCoordinates live in a 256×256 map; one map unit is roughly 0.1 LY,\nso a typical neighbour is 2–5 LY away.\n\n### Solar systems\n\nEach system is a 3D volume (about 48 km on a side) containing:\n\n- a star at the origin,\n- one to three planets on inclined orbits (some with rings, moonlets,\n  or asteroid belts),\n- one or more Coriolis stations,\n- a jump gate (the only way out).\n\nLayouts are re-derived on demand from the system seed, so the same\nsystem always looks the same.\n\n### Free flight\n\nThe cockpit shows a starfield, HUD bars (shield, hull, heat,\nthrottle, laser cooldown), a 3D radar of nearby ships and POIs, and a\nmode banner stack for contextual prompts (`H=HAIL`, `BELT`, `WARP`,\n`ENTER GATE`, `HEAT!`). Landing on a planet and jumping at a gate are\nautomatic — drift into range and the screen hand-off fires itself.\n\nPressing `Tab` cycles a target POI.\n\n### Combat\n\n- **Lasers** come in three tiers: Pulse (start), Beam (1000 CR),\n  Military (6000 CR; requires Beam first). Each tier raises damage,\n  range, and cooldown speed.\n- **Missiles** are racked up to four. `R` cycles a lock onto the\n  nearest target in front; `A` fires.\n- **ECM** is unlimited but cooldown-throttled, blanketing incoming\n  missiles in a single burst.\n- **Shields** absorb damage first and regenerate slowly (~37 s for a\n  full top-up) **while still active** — once a shield is depleted to\n  0 it stays down until you buy `REPAIR SHIELD` at the EQUIP shop.\n  **Hull** only goes down — repair it the same way.\n- **Sun heat** builds while skimming the star. Past 1.0 hullHeat\n  forward shields drain, then aft. A `HEAT!` banner blinks faster\n  as you approach the threshold.\n\n### NPCs and factions\n\nEvery system spawns 1–4 NPC ships, roles weighted by government\n(anarchy → mostly pirates; corporate → mostly patrols). Pirates are\nalways Cartel; everyone else inherits the system's faction.\n\nThere are four factions: **Imperium**, **Federation**, **Cartel**,\n**Free Traders**. Your standing with each runs from -100 to +100 and\nshifts on kills, trades, and quest payouts. Patrols turn hostile to\nyou once their faction's standing drops past -30, and market prices\nflex up to ±20% with standing.\n\n### Market\n\nSeventeen commodities, from Food and Textiles up through Gold,\nPlatinum, and Aliens. Three are illegal (Slaves, Narcotics, Firearms)\nand shrink under stable governments. Prices and stock are\ndeterministic per (system, commodity, market epoch); each hyperspace\njump bumps the epoch so prices shift slightly on a return visit.\n\n### Quests\n\nOne active quest at a time. Accept at a planet, complete the\nobjective, and return to that same planet for the payout. Five\nquest types are implemented (see `Quest.h`):\n\n| Type        | Objective | Return required? |\n|-------------|-----------|------------------|\n| Patrol      | Kill N pirates in this system. | Yes |\n| Delivery    | Drop N tons of a commodity at another planet POI. | Yes |\n| VisitPlanet | Touch down at a specified planet POI. | Yes |\n| Courier     | One-way drop of a passenger / packet at a planet POI. | **No** — paid on arrival |\n| Scavenge    | Bring N tons of a commodity not stocked locally. | Yes |\n\nEach quest carries a *difficulty* (EASY / MED / HARD / ELITE) derived\nfrom distance from system 0, which scales both the size of the\nobjective and the payout. Patrol contracts also arm a one-shot pirate\nspawn on the first launch after acceptance — killed pirates do not\nrespawn for that contract.\n\nThe pause menu always shows the single next step (e.g. `GO TO TRIX II`,\n`KILL 2/4 PIRATES`, `RETURN TO TRIX`). The board itself renders the\nnarrative title (`COURIER PACKET TO TRIX II`, `BOUNTY: 3 PIRATES`,\netc.). Completion fires a modal popup on landing — press `Enter` to\ndismiss before the docked menu becomes usable again.\n\n### Equipment shop\n\nReached from the docked menu (`EQUIP`). All purchases debit\n`game.credits` in tenths of a credit.\n\n| Item        | Price | Effect |\n|-------------|-------|--------|\n| REPAIR HULL   | 10 CR per +10% | Patches hull damage (full repair = ~100 CR). |\n| REPAIR SHIELD | 100 CR         | One-shot full recharge — required after depletion. |\n| MISSILE     | 30 CR each, cap 4 | Adds one homing missile. |\n| ECM SYSTEM  | 600 CR | Enables the ECM burst (one-time install). |\n| LARGE HOLD  | 400 CR | Cargo capacity 20 t → 35 t. |\n| BEAM LASER  | 1000 CR | Mid-tier laser. |\n| MIL LASER   | 6000 CR | Top-tier laser (requires Beam). |\n\n### Rank\n\nThe kill counter feeds a seven-tier rank ladder (Harmless → Mostly\nHarmless → Poor → Average → Competent → Dangerous → Deadly). Crossing\na tier surfaces a `PROMOTED: \u003cRANK\u003e` banner in flight; the status\ncard shows your current tier and kills-to-next.\n\n### Audio\n\nA PWM beeper drives small SFX through the M5Unified speaker class:\nlaser zap (pitched per tier), shield hit, missile launch, ECM burst,\ndock chime, witchspace whoosh, hostility alarm, quest accept /\ncomplete chimes, and a denied-action buzz. Volume is fixed at 80/255;\nthe engine has no mute toggle yet.\n\n---\n\n## Code structure\n\nMost code lives in single-header `.h` files included from `hazke.ino`,\nthe top-level state machine. Each module owns its own state and\nexposes inline functions — there's no build system beyond the Arduino\nIDE.\n\n```\nhazke.ino           top-level state machine + frame loop\nConfig.h            screen, frame, viewport constants\nInput.h             keyboard polling + edge detection\nGameMode.h          enum of screen states\nGameState.h         mutable player state (credits, cargo, ship, faction)\n\nGalaxy.h            16-system procgen + gate adjacency graph\nSolarSystem.h       per-system POI table\nFaction.h           faction map + standing nudges\nMarket.h            commodity table + deterministic pricing\nHyperspace.h        jump cost + neighbour gating\nRank.h              kill-tier ladder + promotion banner\nQuest.h             quest data model + onDock / onPirateKill hooks\nNPCShip.h           in-flight roster + AI (trader / pirate / patrol)\nCombat.h            laser + missile damage resolution\nMissile.h           homing missile motion + ECM\nParticles.h         tiny pixel explosion / debris system\nAudio.h             PWM SFX wrappers\nSDCard.h            shared lazy microSD bring-up (screenshots + saves)\nSaveFormat.h        versioned save payloads + CRC + upgrade transformers\nSaveStore.h         save-slot IO on LittleFS/SD + game\u003c-\u003epayload marshalling\nShip3D.h            wireframe ship renderer (6 hull silhouettes)\nStarfield.h         parallax stars\nCockpit.h           HUD overlay (bars, banners, rank toast)\nSystemFlight.h      the actual 3D flight loop + landing-range checks\n\nTitleScreen.h       title menu\nInfoScreen.h        controls help\nAboutScreen.h       about / credits\nChartScreen.h       galactic gate-graph map\nSystemDataScreen.h  per-system info panel\nMapScreen.h         in-system top-down map\nMarketScreen.h      commodity buy/sell UI\nNPCTradeScreen.h    hail-in-flight buy/sell dialog\nEquipScreen.h       equipment shop (includes REPAIR HULL)\nStatusScreen.h      commander card\nLandingScreen.h     planet surface menu\nQuestScreen.h       planet quest board\nPauseMenu.h         in-flight pause overlay (shows active quest step)\nWitchspaceScreen.h  hyperspace transit cinematic\nGameOverScreen.h    death + restart prompt\nSaveMenuScreen.h    save/load slot picker (backend tabs, copy, delete)\nMenuUI.h            shared menu chrome (headers, footers, toasts)\n```\n\n## Design constraints\n\n- ~320 KB usable RAM on the ESP32-S3. POI tables stay small (≤ 16\n  POIs per system, ≤ 4 active NPCs).\n- 240×135 @ 16 bpp via an `M5Canvas` double-buffer. Target ~30 FPS in\n  flight; menus may drop to 15.\n- Game state lives in RAM during play; landed-only saves keep the save\n  format tiny (~100 B) and free of transient flight state.\n\n## License\n\nOriginal work. No code or art from the inspirations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftherezor%2Fhazke","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftherezor%2Fhazke","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftherezor%2Fhazke/lists"}