Initial commit: Arcade85 (5-in-1 TI-85 HD remakes) + AGENTS.md runbook
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
# Arcade85
|
||||
|
||||
A 5-in-1 iOS collection of faithful **HD remakes** of five classic TI-85 calculator
|
||||
games. Native **SwiftUI + SpriteKit**, one shared shell, each game a
|
||||
`Scene` (SpriteKit) + `Sim` (pure Swift engine) pair.
|
||||
|
||||
This file is the operational runbook for an agent building/deploying Arcade85 on the
|
||||
Mac Studio **without the human in the loop**. Read it top to bottom before touching
|
||||
signing, git, or the build. It follows the same pattern as `~/dev/KyleCode/AGENTS.md`
|
||||
(same Gitea, same `~/dev/.env` token, same signing identity).
|
||||
|
||||
---
|
||||
|
||||
## 1. Repo layout
|
||||
|
||||
```
|
||||
Arcade85/
|
||||
Arcade85.xcodeproj/ # hand-maintained (NOT xcodegen) — edit via Xcode/pbxproj
|
||||
Arcade85/
|
||||
Arcade85App.swift # @main
|
||||
Shell/ # app chrome: RootView, GameHostView, GameCatalog,
|
||||
# Theme, Haptics, HighScoreStore
|
||||
Games/
|
||||
SceneArt.swift # shared procedural texture/sprite helpers
|
||||
DopeWars/ DopeWarsScene.swift + DopeWarsSim.swift
|
||||
Lander/ LanderScene.swift + LanderSim.swift
|
||||
Phoenix/ PhoenixScene.swift + PhoenixSim.swift + PhoenixData.swift
|
||||
ZTetris/ TetrisScene.swift + TetrisSim.swift
|
||||
ZMercury/ MercuryScene.swift + MercurySim.swift + MercuryData.swift
|
||||
Galaxian/ (ported, dormant — see GameCatalog note)
|
||||
ComingSoonScene.swift
|
||||
README.md
|
||||
```
|
||||
|
||||
**Convention:** every game is a `*Scene.swift` (SpriteKit, all UI/input) paired with a
|
||||
`*Sim.swift` (pure Swift state machine — no UIKit/SpriteKit imports). The Sim is the
|
||||
engine and is where mechanics live; the Scene only renders and routes touches. Keep
|
||||
them separate. Dope Wars' `DopeWarsSim` is the reference for a well-factored Sim
|
||||
(seeded RNG, a separate `extRng` stream for non-classic extensions, `#if DEBUG` debug
|
||||
hooks, a `messages: [String]` queue the Scene drains one-per-tap).
|
||||
|
||||
The original TI-85 sources this was remade from live in sibling folders under
|
||||
`~/dev/TI/` (`lander/`, `zetris/`, `phx4.0ti85/`, `zmercury-ti85/`, `galaxian-ti85/`).
|
||||
They are **not** part of this repo.
|
||||
|
||||
## 2. Signing
|
||||
|
||||
- **Team:** `TG8X9PP8VT` (Kyle Albanese). **Identity:** "Apple Development: Kyle
|
||||
Albanese (5SRT78F8BG)". **Bundle ID:** `com.albanese.arcade85`.
|
||||
- **Automatic signing** (`CODE_SIGN_STYLE = Automatic`), `GENERATE_INFOPLIST_FILE = YES`
|
||||
(no Info.plist file exists — don't add one).
|
||||
- The current pbxproj does **not** pin `DEVELOPMENT_TEAM`; the identity in the login
|
||||
keychain is used. If a device build ever fails to sign, set
|
||||
`DEVELOPMENT_TEAM = TG8X9PP8VT` on the target (don't switch to manual profiles).
|
||||
|
||||
### Environment prerequisites (why this works)
|
||||
|
||||
Commands run as the user's **own launchd job in `gui/501` (Aqua session)**, so the
|
||||
login keychain is readable by `xcodebuild`/`codesign`. Verify before a device build
|
||||
(do NOT change anything if it fails — stop and tell the user):
|
||||
|
||||
```bash
|
||||
launchctl managername # must print: Aqua
|
||||
security find-identity -v -p codesigning /Users/fung/Library/Keychains/login.keychain-db
|
||||
# must list: "Apple Development: Kyle Albanese (5SRT78F8BG)"
|
||||
```
|
||||
|
||||
**Hard rules:** never revoke/recreate the Apple Development cert, don't touch keychain
|
||||
settings, keep automatic signing, never commit `*.p8` or `*.env` secrets.
|
||||
|
||||
## 3. Build
|
||||
|
||||
Run from `/Users/fung/dev/TI/Arcade85`.
|
||||
|
||||
### Simulator (no signing — default for quick checks)
|
||||
```bash
|
||||
xcodebuild -project Arcade85.xcodeproj -scheme Arcade85 \
|
||||
-destination 'generic/platform=iOS Simulator' -configuration Debug \
|
||||
-derivedDataPath build/dd build CODE_SIGNING_ALLOWED=NO
|
||||
```
|
||||
Success: `** BUILD SUCCEEDED **`. (Verified 2026-09-16.)
|
||||
|
||||
### Device (real iPhone, auto-signed)
|
||||
```bash
|
||||
xcodebuild -project Arcade85.xcodeproj -scheme Arcade85 \
|
||||
-destination 'generic/platform=iOS' -derivedDataPath build/dd \
|
||||
-allowProvisioningUpdates build
|
||||
```
|
||||
Install/launch a paired device (list with `xcrun devicectl list devices`):
|
||||
```bash
|
||||
APP=build/dd/Build/Products/Debug-iphoneos/Arcade85.app
|
||||
xcrun devicectl device install app --device <UDID> "$APP"
|
||||
xcrun devicectl device process launch --device <UDID> com.albanese.arcade85
|
||||
```
|
||||
|
||||
**There are no automated tests in this project.** A passing build is the check. For
|
||||
gameplay, run in the simulator and play, or use the Dope Wars debug env vars below.
|
||||
|
||||
### Dope Wars debug env vars (DEBUG builds only)
|
||||
`DopeWarsScene.didMove(to:)` reads `ProcessInfo` env vars for screenshot/demo poses:
|
||||
`ARCADE_AUTOPLAY=1` (auto-start a run), `ARCADE_DEMO=1` (deterministic day-12 demo),
|
||||
`ARCADE_DEMO_VIEW=buy|chase|tier3|over|ride|keypad|sharkchase|endless`. The
|
||||
`DopeWarsSim` also exposes `debug*` mutators (wallet, debt, price, tier, held, forced
|
||||
RNG rolls) gated behind `#if DEBUG`.
|
||||
|
||||
## 4. Git & Gitea
|
||||
|
||||
Remote: Gitea `https://git.kwalb.com/kyle/Arcade85` (branch `main`). No git
|
||||
credentials in the keychain — use the API token from `~/dev/.env` inline, and let the
|
||||
credential prompt fail to store (harmless). **The repo is created on first push:**
|
||||
|
||||
```bash
|
||||
TOKEN=$(sed -n 's/^GITEA_API=//p' ~/dev/.env)
|
||||
curl -s -X POST -H "Authorization: token $TOKEN" -H "Content-Type: application/json" \
|
||||
-d '{"name":"Arcade85","private":false,"default_branch":"main"}' \
|
||||
https://git.kwalb.com/api/v1/user/repos
|
||||
# then:
|
||||
git push "https://kyle:$TOKEN@git.kwalb.com/kyle/Arcade85.git" main
|
||||
```
|
||||
|
||||
API: `curl -H "Authorization: token $TOKEN" https://git.kwalb.com/api/v1/repos/kyle/Arcade85/…`
|
||||
|
||||
**Only commit/push when asked.** Stage only intended files. Never stage `*.p8` or
|
||||
`*.env`.
|
||||
|
||||
### `.env` — do not `source` it
|
||||
`~/dev/.env` holds `GITEA_URL`, `GITEA_API` (token), `GITEA_USERNAME`, `GITEA_EMAIL`
|
||||
plus other service keys. **Do not `source` it** — a later line is a bare
|
||||
`https://claude.ai/magic-link…` URL (not `key=value`) which breaks `source` in zsh.
|
||||
Read values with sed:
|
||||
```bash
|
||||
TOKEN=$(sed -n 's/^GITEA_API=//p' ~/dev/.env)
|
||||
```
|
||||
|
||||
## 5. `.gitignore` (already in place — don't remove)
|
||||
`build/`, `DerivedData/`, `*.xcuserstate`, `xcuserdata/`, `*.moved-aside`, `*.hmap`,
|
||||
`*.ipa`, `*.dSYM.zip`, `*.dSYM`, `.DS_Store`, `.build/`, `.swiftpm/`.
|
||||
|
||||
Add `*.p8` and `*.env` to this ignore list if/when they could appear here (none do
|
||||
today, but the rule is: never commit signing keys or secret files).
|
||||
|
||||
## 6. Adding a game
|
||||
|
||||
1. Create `Games/<Name>/<Name>Scene.swift` + `<Name>Sim.swift` (mirror Dope Wars).
|
||||
2. Add both files to the Xcode target in `Arcade85.xcodeproj/project.pbxproj`
|
||||
(hand-maintained — there is **no** `project.yml`/xcodegen step; edit the pbxproj or
|
||||
use Xcode's "Add Files to Arcade85").
|
||||
3. Register the slot in `Shell/GameCatalog.swift`.
|
||||
4. Build (simulator) to verify.
|
||||
Reference in New Issue
Block a user