-
Notifications
You must be signed in to change notification settings - Fork 0
Rewrite README as a narrative cyberpunk tactics introduction #46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,66 +1,337 @@ | ||
| # HexWire | ||
| <div align="center"> | ||
|
|
||
| > Tactical cyberpunk hex-grid RPG for iOS — SwiftUI + SpriteKit. | ||
| > A pressure-driven combat loop where every action trades power for exposure: | ||
| > **Signal → Power → Trace → Escalation → Lay Low → Tempo Tradeoff.** | ||
| # HEXWIRE | ||
|
|
||
| ### Turn-based cyberpunk strategy tactics for iPhone and iPad | ||
|
|
||
| **Take the contract. Build the crew. Burn the signal. Get out before the city learns your name.** | ||
|
|
||
| [](https://github.com/scrimshawlife-ctrl/Hexwire/actions/workflows/hexwire-ci.yml) | ||
| [](project.yml) | ||
| [](project.yml) | ||
| [](#under-the-neon) | ||
| [](#under-the-neon) | ||
| [](plans.md) | ||
|
|
||
| [The World](#the-city-is-listening) · [The Crew](#four-runners-one-bad-plan) · [Combat](#every-turn-leaves-a-trace) · [Modes](#the-work-never-ends) · [Build](#jack-in) · [Atlas](#repository-atlas) | ||
|
|
||
| </div> | ||
|
|
||
| --- | ||
|
|
||
| ## The city is listening | ||
|
|
||
| The city sold its nervous system to the highest bidder. | ||
|
|
||
| Every camera is awake. Every transit gate keeps a memory. Every corporate district is a sealed machine built to recognize the wrong face at the wrong time. Data brokers trade reputations like ammunition. Private security responds before the law knows a crime happened. Somewhere above the rain, an executive dashboard is turning human movement into risk scores. | ||
|
|
||
| You are not here to fix that system. | ||
|
|
||
| You are here to rob it. | ||
|
|
||
| **HexWire** is a turn-based cyberpunk strategy tactics game built around small-team infiltration, authored multi-room operations, persistent consequences, and a combat economy where speed creates exposure. You command a crew of specialists across a hex-grid battlefield, spend scarce actions to break hostile positions, extract before the network closes around you, and carry the consequences into the next job. | ||
|
|
||
| The fantasy is not invincibility. It is competence under pressure. | ||
|
|
||
| A clean mission pays. A loud mission pays faster. A reckless mission changes what the city sends after you next. | ||
|
|
||
| --- | ||
|
|
||
| ## Four runners. One bad plan. | ||
|
|
||
| A HexWire crew is built from four complementary archetypes. None of them owns the battlefield alone; the game lives in the space between their abilities. | ||
|
|
||
| | Runner | Function | Battlefield identity | | ||
| |---|---|---| | ||
| | **Street Samurai** | Frontline pressure | Closes distance, absorbs risk, and turns positional advantage into decisive force. | | ||
| | **Mage** | Arcane control | Shapes contested space, punishes clustered threats, and bends the encounter outside ordinary rules. | | ||
| | **Decker** | Signal warfare | Exploits the network, accelerates tactical plays, and makes the fastest path the most dangerous one. | | ||
| | **Face** | Social and support leverage | Keeps the operation coherent, creates openings, and converts preparation into survival. | | ||
|
|
||
| The crew moves as a single operational system. Positioning, initiative, room sequencing, damage, extraction, economy, and persistence all feed forward. A mistake in one room becomes the shape of the next. | ||
|
|
||
| --- | ||
|
|
||
| ## Every turn leaves a trace | ||
|
|
||
| At the center of HexWire is a pressure loop built around two ways of acting: | ||
|
|
||
| ### STREET | ||
|
|
||
| Reliable. Controlled. Slow enough to disappear inside the noise. | ||
|
|
||
| Street actions resolve without increasing trace. They preserve operational safety but surrender tempo to the opposition. | ||
|
|
||
| ### SIGNAL | ||
|
|
||
| Fast. Powerful. Visible. | ||
|
|
||
| Signal actions create immediate tactical leverage while raising your trace level. Push it too far and the hostile network escalates: enemy awareness hardens, incoming damage increases, and the mission begins charging interest on every shortcut you took. | ||
|
|
||
| ### LAY LOW | ||
|
|
||
| You can reduce trace, but there is no free reset. Laying low consumes a full turn. The crew survives by deciding when tempo matters more than safety—and when one more aggressive action will turn a winning position into a collapse. | ||
|
|
||
| > **Signal → Power → Trace → Escalation → Lay Low → Tempo Tradeoff** | ||
|
|
||
|  | ||
|
|
||
| Trace is not a cosmetic alert meter. It is the combat clock the player chooses to wind. | ||
|
|
||
| --- | ||
|
|
||
| ## The shape of a run | ||
|
|
||
| Every operation follows a tactical rhythm: | ||
|
|
||
| 1. **Take the contract** — enter an authored story mission, side contract, arena, or gauntlet run. | ||
| 2. **Read the room** — study walls, lanes, enemy positions, initiative, objectives, and extraction conditions. | ||
| 3. **Commit the crew** — move across the hex grid, attack, cast, hack, support, or sacrifice tempo to reduce exposure. | ||
| 4. **Clear forward** — move through connected rooms while carrying damage, pressure, and mission state with you. | ||
| 5. **Hit the objective** — acquire data, eliminate resistance, survive the encounter logic, or satisfy the mission gate. | ||
| 6. **Reach extraction** — physically move a runner onto the armed extraction tile and resolve the operation. | ||
| 7. **Live with it** — collect nuyen, preserve progression, alter faction attention, upgrade the crew, and decide what risk comes next. | ||
|
|
||
| Victory is not simply killing the final enemy. The job ends when the crew gets out. | ||
|
|
||
| --- | ||
|
|
||
| ## Authored campaigns, unstable replays | ||
|
|
||
| HexWire currently contains **six machine-certified multi-room story missions**, supported by scene-driven interstitial operations and repeatable combat modes. | ||
|
|
||
| ### Story operations | ||
|
|
||
| Each mission is built as a connected room graph with authored enemies, boss or unique slots, objective logic, extraction conditions, payout, defeat handling, replay behavior, and save/resume persistence. | ||
|
|
||
| The story campaign is designed to feel deliberate rather than procedurally anonymous: rooms have authored tactical intent, while seeded replay rerolls vary ordinary opposition without replacing bosses, unique encounters, or mission structure. | ||
|
|
||
| ### Interstitial operations | ||
|
|
||
| Between major missions, the campaign shifts format through scene-driven encounters including: | ||
|
|
||
| - **Mirrorline** | ||
| - **The Drop** | ||
| - **Basement Brawl** | ||
| - **Cold Trace** | ||
|
|
||
| These sequences widen the fiction beyond the standard combat board while still routing rewards and objectives through the same authoritative progression system. | ||
|
|
||
| --- | ||
|
|
||
| ## The work never ends | ||
|
|
||
| The campaign is only one layer of the city. | ||
|
|
||
| | Mode | What it does | | ||
| |---|---| | ||
| | **Side Contracts** | Tiered operations generated from the contract board, built for repeatable risk and progression. | | ||
| | **Arenas** | Twenty validated combat spaces selected through seeded contract generation. | | ||
| | **Endless Gauntlet** | Escalating floors, shifting enemy composition, persistent best-floor tracking, and failure that sends the crew back to floor one. | | ||
| | **Seeded Replay** | Rerolls standard opposition while preserving authored structure, boss identity, positions, and mission logic. | | ||
| | **New Game+** | Carries the campaign forward into a higher-pressure progression cycle. | | ||
|
|
||
| The persistent layer includes **nuyen, black-market access, cyberware, faction heat, mission completion, replay state, and campaign scaling**. The city remembers both success and attention. | ||
|
|
||
| --- | ||
|
|
||
| ## Tactical identity | ||
|
|
||
| HexWire is built around a specific kind of strategy: | ||
|
|
||
| - **Turn-based, not twitch-based** — the player has time to read the board, but every action changes the pressure state. | ||
| - **Position-first combat** — walls, lanes, movement budgets, room topology, and extraction placement determine what is possible. | ||
| - **Small-team synergy** — runners are designed as interlocking roles rather than isolated damage engines. | ||
| - **Objective-driven missions** — combat is part of the operation, not always the complete operation. | ||
| - **Persistent consequence** — rewards, faction attention, upgrades, campaign progress, and replay state survive beyond the room. | ||
| - **Deterministic authority** — identical inputs and seeded conditions resolve consistently, making tactics testable rather than theatrical. | ||
|
|
||
| The intended feeling is a cyberpunk heist collapsing one measured decision at a time. | ||
|
|
||
| --- | ||
|
|
||
| ## Under the neon | ||
|
|
||
| HexWire is an iOS-native game built with: | ||
|
|
||
| | Layer | Technology | | ||
| |---|---| | ||
| | Application and campaign UI | **SwiftUI** | | ||
| | Tactical battlefield | **SpriteKit** | | ||
| | Core language | **Swift 5.9** | | ||
| | Project generation | **XcodeGen 2.46.0** | | ||
| | Minimum deployment target | **iOS 17.0** | | ||
| | Supported devices | **iPhone and iPad** | | ||
| | Build validation | **GitHub Actions on macOS** | | ||
|
|
||
| The gameplay architecture follows one hard rule: | ||
|
|
||
| > **`GameState` is the single gameplay authority.** | ||
|
|
||
| SwiftUI and SpriteKit do not independently decide outcomes. Presentation surfaces emit intents through the game-intent and combat-flow seams, then render the authoritative result. This prevents animation, touch handling, or scene timing from silently becoming a second rules engine. | ||
|
|
||
| ```mermaid | ||
| flowchart LR | ||
| P[Player input] --> I[Game intents] | ||
| I --> G[GameState authority] | ||
| G --> C[Combat and mission systems] | ||
| C --> G | ||
| G --> S[SpriteKit battlefield] | ||
| G --> U[SwiftUI campaign UI] | ||
| G --> V[Persistence and progression] | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ## Current state | ||
|
|
||
| ```yaml | ||
| product_name: HexWire | ||
| platform: iOS (iPhone + iPad) | ||
| minimum_os: iOS 17.0 | ||
| current_state: STABILIZED_VERTICAL_SLICE # was ADVANCED_PLAYABLE_PROTOTYPE pre-2026-07 | ||
| latest_verified_commit: see the latest green hexwire-ci run on main | ||
| latest_build_result: PASS — Debug+Release × iPhone+iPad + unsigned archive, hosted CI on every PR | ||
| latest_test_result: PASS — 94 deterministic tests, 0 flaky (unit + per-mission certification) | ||
| mission_certification: docs/audit/MissionCertificationMatrix.md (all 6 missions machine-certified; | ||
| touch-layer items listed for device pass) | ||
| supported_devices: iPhone (portrait, compact) + iPad (regular); verified on | ||
| iPhone 17 and iPad Pro 13-inch (M5) simulators, iOS 26.5 | ||
| known_release_blockers: | ||
| - owner device pass for touch-layer items (see certification matrix) | ||
| - devUnlockAllMissions=true must be flipped OFF for a ship build (HexwireApp.swift) | ||
| - App Store signing/metadata (outside stabilization scope) | ||
| HexWire is a **stabilized vertical slice**, not yet a finished App Store release. | ||
|
|
||
| The current repository includes: | ||
|
|
||
| - Six certified multi-room story missions | ||
| - Scene-driven interstitial missions | ||
| - Deterministic combat and seeded replay behavior | ||
| - Twenty validated arenas | ||
| - Side-contract tiers 1–3 | ||
| - Gauntlet progression across the tested scaling band | ||
| - Persistent economy, campaign, and upgrade state | ||
| - iPhone and iPad layouts | ||
| - Debug and Release simulator builds | ||
| - Unsigned release archive generation | ||
| - Hosted CI on every pull request and push to `main` | ||
|
|
||
| Remaining release work is concentrated around the owner’s real-device pass, ship configuration, signing, and App Store metadata. See [`plans.md`](plans.md) for the active release frontier. | ||
|
|
||
| --- | ||
|
|
||
| ## Jack in | ||
|
|
||
| ### Requirements | ||
|
|
||
| - macOS | ||
| - Xcode with an iOS 17+ SDK | ||
| - XcodeGen **2.46.0** | ||
|
|
||
| ### Generate the project | ||
|
|
||
| ```bash | ||
| xcodegen generate | ||
| ``` | ||
|
|
||
| `HexWire.xcodeproj` is generated from [`project.yml`](project.yml). After adding or removing files, regenerate and commit the project. CI rejects project drift. | ||
|
|
||
| ### Build | ||
|
|
||
| ```bash | ||
| xcodebuild \ | ||
| -project HexWire.xcodeproj \ | ||
| -scheme HexWire \ | ||
| -destination 'platform=iOS Simulator,name=iPhone 17' \ | ||
| build | ||
| ``` | ||
|
|
||
| ### Test | ||
|
|
||
| ```bash | ||
| xcodebuild \ | ||
| -project HexWire.xcodeproj \ | ||
| -scheme HexWire \ | ||
| -destination 'platform=iOS Simulator,name=iPhone 17' \ | ||
| test | ||
| ``` | ||
|
|
||
| For repeated test runs, pre-boot the simulator to avoid cold-launch instability: | ||
|
|
||
| ```bash | ||
| xcrun simctl boot <udid> || true | ||
| xcrun simctl bootstatus <udid> -b | ||
| ``` | ||
|
|
||
| ### Launch directly into a mission | ||
|
|
||
| Debug builds honor `SR_AUTOSTART_MISSION_ID`: | ||
|
|
||
| ```bash | ||
| SR_AUTOSTART_MISSION_ID=Mission003 | ||
| ``` | ||
|
|
||
| ## Working on this repo | ||
|
|
||
| - **Project generation:** `HexWire.xcodeproj` is generated from `project.yml` by | ||
| **XcodeGen 2.46.0**. After adding/removing files: `xcodegen generate` and commit | ||
| the regenerated project — CI fails on drift. | ||
| - **Build:** `xcodebuild -project HexWire.xcodeproj -scheme HexWire -destination | ||
| 'platform=iOS Simulator,name=iPhone 17' build` | ||
| - **Test:** same command with `test`. If running repeatedly, pre-boot the | ||
| simulator (`xcrun simctl boot <udid> && xcrun simctl bootstatus <udid> -b`) — | ||
| cold-sim launches flake before tests run. | ||
| - **CI:** `.github/workflows/hexwire-ci.yml` runs hygiene checks, the XcodeGen | ||
| drift gate + tests, a Debug/Release × iPhone/iPad build matrix, and an | ||
| unsigned archive on every PR. | ||
| - **Architecture rule:** `GameState` is the single gameplay authority. UI and | ||
| SpriteKit layers emit intents (`Game/GameIntents.swift`) and render from | ||
| state — never mutate authority state directly. See | ||
| `docs/audit/GameStateAuthorityMutationLedger.md`. | ||
| - **Debug autostart:** DEBUG builds honor the `SR_AUTOSTART_MISSION_ID` | ||
| environment variable (e.g. `Mission003`) to launch straight into a mission. | ||
|
|
||
| ## The game | ||
|
|
||
| Four runners (street samurai, mage, decker, face) run six authored multi-room | ||
| missions plus interstitial scene-missions, with a persistent economy (nuyen, | ||
| black market, cyberware), faction heat that carries between missions, seeded | ||
| replay rerolls, an endless gauntlet, and New Game+ scaling. The trace/heat | ||
| pressure loop is documented in `docs/TraceSystem.md`. | ||
|
|
||
|  | ||
|
|
||
| ## Documentation map | ||
|
|
||
| | Doc | What it is | | ||
| Use `Mission001` through `Mission006` to bypass campaign navigation and enter a mission directly. | ||
|
|
||
| --- | ||
|
|
||
| ## Validation is part of the design | ||
|
|
||
| HexWire treats gameplay claims as executable obligations. | ||
|
|
||
| The hosted `hexwire-ci` workflow checks: | ||
|
|
||
| | Gate | Coverage | | ||
| |---|---| | ||
| | `plans.md` | Current mission, verified baseline, next actions | | ||
| | `AGENTS.md` | Contributor/agent workflow rules | | ||
| | `docs/audit/` | Stabilization evidence: repo baseline, build baseline, test coverage map, authority ledger, mission certification, persistence certification, repo/asset report | | ||
| | `docs/architecture/StabilizationExtractionMap.md` | Decomposition status + deferred candidates | | ||
| | `docs/TraceSystem.md` | Trace/heat pressure-loop design | | ||
| | `docs/archive/` | Historical audits and handoffs (superseded — do not act on) | | ||
| | Repository hygiene | Nested repositories, tracked build output, user state, backup projects, and stray workspaces | | ||
| | Mission data | JSON validity and unique mission identifiers | | ||
| | Asset safety | Duplicate runtime asset-name detection | | ||
| | Project reproducibility | XcodeGen regeneration and drift rejection | | ||
| | Deterministic tests | Combat, authority, economy, persistence, missions, replay modes, and player movement semantics | | ||
| | Device matrix | Debug and Release builds for iPhone and iPad simulators | | ||
| | Archive path | Unsigned generic-iOS Release archive | | ||
| | Resource integrity | Missing-resource warning gate | | ||
|
|
||
| The authoritative status signal is the live CI badge at the top of this README. Historical documents may contain older test-count snapshots; green CI on `main` is the current truth surface. | ||
|
|
||
| --- | ||
|
|
||
| ## Repository atlas | ||
|
|
||
| ```text | ||
| Hexwire/ | ||
| ├── Game/ # Intents, combat flow, authority-facing systems | ||
| ├── Missions/ # Authored mission JSON | ||
| ├── Sprites/ # SpriteKit runtime art | ||
| ├── Assets.xcassets/ # Asset catalog | ||
| ├── tests/ # Deterministic and certification suites | ||
| ├── docs/ | ||
| │ ├── TraceSystem.md # Signal, trace, escalation, and Lay Low loop | ||
| │ ├── architecture/ # Extraction and authority architecture | ||
| │ ├── audit/ # Build, test, mission, persistence, and repo evidence | ||
| │ └── archive/ # Superseded historical material | ||
| ├── .github/workflows/ # Hosted CI | ||
| ├── project.yml # Canonical XcodeGen specification | ||
| ├── AGENTS.md # Contributor and coding-agent rules | ||
| └── plans.md # Current verified baseline and next actions | ||
| ``` | ||
|
|
||
| ### Start here | ||
|
|
||
| | Document | Purpose | | ||
| |---|---| | ||
| | [`plans.md`](plans.md) | Current mission, verified baseline, blockers, and next actions | | ||
| | [`AGENTS.md`](AGENTS.md) | Repository workflow and authority invariants | | ||
| | [`docs/TraceSystem.md`](docs/TraceSystem.md) | The Street / Signal / Trace pressure system | | ||
| | [`docs/audit/MissionCertificationMatrix.md`](docs/audit/MissionCertificationMatrix.md) | Evidence for missions, arenas, contracts, gauntlet, and extraction semantics | | ||
| | [`docs/audit/GameStateAuthorityMutationLedger.md`](docs/audit/GameStateAuthorityMutationLedger.md) | Gameplay authority and mutation boundaries | | ||
| | [`docs/audit/PersistenceCertificationReport.md`](docs/audit/PersistenceCertificationReport.md) | Save, migration, corruption, and resume evidence | | ||
| | [`docs/architecture/StabilizationExtractionMap.md`](docs/architecture/StabilizationExtractionMap.md) | Current system decomposition and deferred extraction candidates | | ||
|
|
||
| --- | ||
|
|
||
| ## Operating rules | ||
|
|
||
| Contributions should preserve four invariants: | ||
|
|
||
| 1. `GameState` remains the gameplay authority. | ||
| 2. Presentation layers emit intents and render results; they do not invent outcomes. | ||
| 3. Mission, replay, progression, and persistence behavior must remain deterministic under controlled seeds. | ||
| 4. No completed claim is accepted without a test, build receipt, runtime evidence, or an explicit `NOT_COMPUTABLE` boundary. | ||
|
|
||
| Read [`AGENTS.md`](AGENTS.md) before changing combat flow, mission state, persistence, project structure, or generated Xcode files. | ||
|
|
||
| --- | ||
|
|
||
| <div align="center"> | ||
|
|
||
| ### The signal makes you powerful. The trace makes you mortal. | ||
|
|
||
| **HexWire** — turn-based cyberpunk strategy tactics for iOS. | ||
|
|
||
| </div> | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When this block is pasted into a shell, it only assigns a shell variable; it neither launches HexWire nor passes the value into a simulator process. Because
HexwireApp.swiftreads the app process environment, the documented “Launch directly” flow does nothing. Use the simulator-launch form, such asSIMCTL_CHILD_SR_AUTOSTART_MISSION_ID=Mission003 xcrun simctl launch <udid> com.hexwireaaron.game, instead.AGENTS.md reference: AGENTS.md:L34-L35
Useful? React with 👍 / 👎.