Untrack local docs (*.md) and machine-specific .mcp.json
Keep them on disk (still read/used locally) but out of the remote going forward. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3d1de617a5
commit
c5632548dc
6 changed files with 0 additions and 363 deletions
|
|
@ -1,8 +0,0 @@
|
||||||
{
|
|
||||||
"mcpServers": {
|
|
||||||
"unity": {
|
|
||||||
"type": "http",
|
|
||||||
"url": "http://172.27.208.1:8068/mcp"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
18
CLAUDE.md
18
CLAUDE.md
|
|
@ -1,18 +0,0 @@
|
||||||
# Project: JANKENBOTS
|
|
||||||
|
|
||||||
A ~25-player "friendslop" party game: teams cobble a janky physics robot from themed scrap, then **each teammate pilots one part of it** in an absurd cartoon arena brawl; dead players become free-roaming ragdoll **gremlins**. Graduated from `ideas/jankenstein` on 2026-07-10 and renamed **JANKENBOTS** (was the working title JANKENSTEIN). Engine: **Unity**. Currently building a **basic networked prototype** to test the core coordination feel with real friends.
|
|
||||||
|
|
||||||
## Working agreement
|
|
||||||
|
|
||||||
- This is a git repo with `origin` on Forgejo at `https://git.rdx4.com/megaproxy/jankenbots.git` (private). HTTPS auth uses the token in `~/.git-credentials` — pushes are non-interactive.
|
|
||||||
- Commit after each logical change with a one-line imperative message; `git push` after each commit (or at minimum before ending the session).
|
|
||||||
- Read `memory.md` at session start. Update it before ending the session.
|
|
||||||
- Never commit secrets — see `.gitignore` and the rules in `~/claude/CLAUDE.md`.
|
|
||||||
|
|
||||||
## Project-specific notes
|
|
||||||
|
|
||||||
- **Engine: Unity.** Decided after a netcode/prior-art study (see `DESIGN.md` → *Tech direction*). The physics-party genre is overwhelmingly Unity; the defining risk is networked physics at ~25-player scale.
|
|
||||||
- **Everything lives at `F:\jankenbots\jankenbots`** (= `/mnt/f/jankenbots/jankenbots` from WSL; `~/claude/projects/jankenbots` is a symlink to it). The path is doubly-nested because Unity Hub created the project as `jankenbots` inside `F:\jankenbots` — harmless; the canonical repo/project root is the inner folder. One unified folder: the git repo, the design docs, **and** the Unity project (`Assets/`, `Packages/`, `ProjectSettings/`) all together, because the Unity Editor must run on Windows. Git runs from WSL over `/mnt/f` (`core.filemode false` set). Unity-aware `.gitignore`/`.gitattributes` are in place. **Git LFS is active** (since 2026-07-12): binary art/audio/models (png/jpg/fbx/obj/wav/etc.) are stored via LFS on the Forgejo remote; Unity YAML text assets (prefab/mat/scene/asset) stay normal git text. `git lfs` auths to Forgejo via the stored Basic credential — no extra setup; just `git push` as usual.
|
|
||||||
- **`DESIGN.md`** is the complete design record carried over from the idea's `plan.md` (control feel v0.1, weapon archetypes, lobby math, tech direction). `memory.md` is the distilled decisions + live TODOs; `DESIGN.md` is the deep detail.
|
|
||||||
- **Current focus:** a throwaway **networked prototype** — Unity **Netcode for GameObjects (NGO) + Relay**, host-authoritative, friends join by code. Milestone 1 = one shared bot, each player drives one tread. See `docs/prototype-plan.md`. This prototype's netcode is **not** the final architecture (server-auth vs Photon Quantum is still deferred).
|
|
||||||
- **Claude-in-editor (Unity MCP):** config is seeded — `.mcp.json` registers a `unity` HTTP server at `http://172.27.208.1:8080/mcp`; full runbook in `docs/mcp-setup.md`. Server = CoplayDev/unity-mcp run in **HTTP mode host-side**, reached across the WSL boundary by the Windows host IP (same shape as the UE nwiro/ChiR24 servers). Requires the Unity Editor open + the package installed + the bridge (0.0.0.0 bind or `netsh portproxy` on :8080). Verify with `mcp__unity__*` tools. Editor must be running for the tools to work; re-check the gateway IP if it stops connecting.
|
|
||||||
157
DESIGN.md
157
DESIGN.md
|
|
@ -1,157 +0,0 @@
|
||||||
# JANKENSTEIN
|
|
||||||
|
|
||||||
Working name (jank + monster-building). Alts on the table: **BODGEBOTS**, **SCRAPYARD SCRUM**, **CLANKERS**, **RUSTBUCKETS**, **JALOPY WARS**. Brainstorm / planning artifact. Date format: `YYYY-MM-DD`.
|
|
||||||
|
|
||||||
**One-liner:** A ~25-player "friendslop" party game where teams cobble together a janky physics robot out of themed scrap, then *each teammate pilots one part of it* in an absurd arena brawl — and the players who die pop out as ragdoll gremlins who won't stay down.
|
|
||||||
|
|
||||||
## Problem / motivation
|
|
||||||
|
|
||||||
The "friendslop" genre (PEAK, Lethal Company, Content Warning, Gang Beasts, Mecca Chameleon) is a proven format: chaotic online co-op designed as a *delivery system for social chaos over voice chat*, not as a precise skill game. The genre DNA:
|
|
||||||
|
|
||||||
- 3–25 players, **voice chat is the actual game**; the mechanics exist to make people say things to each other.
|
|
||||||
- A shared goal with a **spectacular, funny, visible failure state**.
|
|
||||||
- **Physics jank as a feature** — the game should betray you in ways that make friends laugh.
|
|
||||||
- **Low skill floor, emergent ceiling** — comedy from coordination breaking down, not execution difficulty.
|
|
||||||
- Cheap, readable, clippable/streamable. Lo-fi is a feature.
|
|
||||||
- The trap to avoid: building a *good game* instead of a *good hangout*.
|
|
||||||
|
|
||||||
**The wedge:** build-and-battle games exist (Besiege, Trailmakers, Main Assembly, Robocraft, Instruments of Destruction) but they are all *sim-serious, precise, and single-player-ish*. **Nobody has made the fast, big-lobby, ragdoll-jank, party-comedy build-brawl where building is deliberately clumsy and cooperative, and the losers stay engaged by becoming gremlins and voting.** That's the open space.
|
|
||||||
|
|
||||||
## Design pillars (locked)
|
|
||||||
|
|
||||||
These came out of the initial brainstorm and are the fixed points to design around:
|
|
||||||
|
|
||||||
1. **Big lobby, not a squad.** Target ~25 players (Mecca Chameleon scale), not capped at 6. The mob is the joke.
|
|
||||||
2. **Physics-based + shared-creative-task hybrid.** The "creation" is a physical robot built with unreliable hands; the creativity is in *how* you build it.
|
|
||||||
3. **Absurd / cartoon tone.** Bright, goofy, slapstick — *not* horror. Human Fall Flat / Gang Beasts energy.
|
|
||||||
4. **One-and-done sessions.** A "night" is a self-contained lobby of short (~5-min) rounds; reset after. Easy drop-in/out.
|
|
||||||
5. **Co-op WITHIN a team, competition ACROSS teams** ("mix of pure co-op + frenemies"). Intra-team friction is incompetence; inter-team friction is the fight.
|
|
||||||
6. **The signature mechanic: you don't build a robot, you build your team's control scheme.** Each functional part needs a pilot in the fight, so your body plan *is* your division of labor.
|
|
||||||
7. **Judging = fight + vote.** The physics fight judges *function* (objective, no arguing); a crowd-favorite vote judges *style* (glorious garbage still scores). This solves the "who decides what's good" problem in a creative game.
|
|
||||||
8. **Nobody stays fully out.** Death = you pop out as a free-roaming ragdoll **gremlin** (sabotage, cheer, get punted, or re-crew a dead seat).
|
|
||||||
|
|
||||||
## Sketch
|
|
||||||
|
|
||||||
### Core loop (self-contained ~5-min round; a session = a playlist of rounds w/ cumulative score)
|
|
||||||
|
|
||||||
1. **Scavenge** — teams grab parts from a shared, *contested* junkyard (steal rivals' wheels for early cross-team friction). Junk theme rotates each round (farm gear → office supplies → space salvage → medieval…), which is how "abstract / varied setting" survives.
|
|
||||||
2. **Build** — bolt parts onto a chassis. Assembly is fairly *clean/snappy*; the comedy is mostly the **structurally-unstable result** (top-heavy bots tip, bad joints flop) with a dash of clumsy-ragdoll-hands. Over-engineering is self-punishing: a top-heavy monster falls over before it reaches the enemy.
|
|
||||||
3. **Fight** — bots brawl. **Each teammate pilots one part** (you're the left tread, you're the flipper, you're the eyes). Miscoordination = the bot spins in circles. Mode varies (see below); the bot is the constant, the win condition is the variable.
|
|
||||||
4. **Gremlin time** — when your part is destroyed or a teammate dies, that player pops out as a little ragdoll **gremlin**: run around the arena, sabotage enemy bots, cheer, get punted, or scramble to **re-crew** an abandoned station.
|
|
||||||
5. **Vote & tally** — score = objective fight result **+** crowd-favorite style vote. Eliminated players/spectators vote (can't vote own). Next round: new mode + junk theme.
|
|
||||||
|
|
||||||
### The signature mechanic in detail
|
|
||||||
|
|
||||||
Every functional part = a "control station" that needs a pair of hands in the fight. Therefore:
|
|
||||||
- **Team size caps bot complexity** — you can't run more stations than you have teammates.
|
|
||||||
- The build-phase tension: a lean 2-pilot bot is coordinated but weak; a 5-weapon monster is terrifying but a coordination nightmare (and probably top-heavy).
|
|
||||||
- **Leaver-safety (design value: never punish a team for a departed/dead player):** unpiloted parts go **neutral/idle** (free-spinning, harmless) — NOT dead weight. Any gremlin or living teammate can **hot-swap** into an empty seat. Worst case, an empty seat gets a **dumb temp-intern NPC** that pilots badly (comedy, not punishment). This preserves the "each person is a part" soul while removing fragility.
|
|
||||||
|
|
||||||
### Control feel — v0.1 (2026-07-10)
|
|
||||||
|
|
||||||
The make-or-break question ("what does piloting one part actually feel like?") now has a working model. **Core forks provisionally locked:** literal physics-forces + upright assist · manual locomotion · medium depth (one primary verb + one resource + passive lean).
|
|
||||||
|
|
||||||
**The reframe that unlocks it:** one part is *not* too thin — each pilot has a **whole controller** for a single part. The design equation is **deep individual control × tight physical coupling to teammates' parts on one shared body = the party game.** Depth keeps the individual engaged; coupling is where the coordination-comedy lives.
|
|
||||||
|
|
||||||
**The tread pilot (designed end-to-end as the highest-leverage part — if driving isn't fun, nothing else matters):**
|
|
||||||
- **Snap-to-cruise throttle** — the key trick. Raw analog is a trap (two humans can't match stick pressure → endless veer → misery). Full-forward snaps to a defined cruise speed identical for both pilots, so "go straight" is trivially easy (both slam forward = dead straight) and *all* coordination texture lives in the in-between (partial throttle, reversing one side, turning). Easy to move, hard to be graceful — the right party-game curve. Input is quantized but force still acts literally on the shared body, so terrain/hits/weight-shifts still knock you off-line (jank preserved).
|
|
||||||
- **Lock-pivot** — the skill verb. A button plants your tread as a pivot anchor; left-locks + right-drives carves a tight turn. Requires a called play ("lock left, I'll swing us!"). Coordinated pivots = skill ceiling; both-lock-or-neither = helpless-360 comedy floor.
|
|
||||||
- **Passive lean** — stick sideways shifts weight; you're *constantly* keeping the top-heavy bot from face-planting, so no pilot is ever idle (the universal "heartbeat" rule across all part types).
|
|
||||||
- **Boost** — a burst that overheats; *deliberately omitted from the first prototype* — add only if driving feels flat (minimal-first discipline).
|
|
||||||
- Moment-to-moment: *gunning/easing one side of a heavy machine, calling turns, stabbing lock to pivot, perpetually nudging weight.* A full role for one part.
|
|
||||||
|
|
||||||
**Feel delivery (juice):** weighty not twitchy (momentum buys reaction time + physical comedy); per-tread engine notes that *grind* when mismatched (audio desync cue); rumble when your tread overpowers the other (haptic tug-of-war); dust/skid + strain-glow so the veer is *readable*, not mysterious. **The control scheme's real output is sentences said to friends** — "ease off left!", "lock and pivot!" — which is the friendslop DNA.
|
|
||||||
|
|
||||||
**Biggest risk (named honestly):** two humans sharing one drivetrain could land as misery, not comedy. Mitigations baked in (cruise-snap, lock-pivot mastery, weighty reaction time, short rounds, enemy keeps coordination relevant). If it still fails: **(Plan B)** asymmetric split — one pilot = throttle/power, the other = steering/rudder (two *complementary* verbs, not redundant halves; more legible, slightly less "you are the left tread"); **(nuclear fallback)** semi-auto locomotion + manual weapons only.
|
|
||||||
|
|
||||||
**Drive split — RESOLVED (2026-07-10): symmetric.** Each locomotion part = one pilot applying its literal force ("you are the left tread"). Decisive reason: it's the **only model that generalizes to arbitrary scrap contraptions** (asymmetric throttle/steer silently assumes a *car* — there's no canonical "steering wheel" on a 2-treads-+-thruster-+-hammer monster) — and it keeps the part↔pilot mapping that *is* pillar #6; asymmetric would violate the core mechanic. For a comedy game the symmetric fumble also beats the clean asymmetric line. **But steal asymmetric's one gift** (complementary roles interlock better than same-axis competition): the **lean/ballast axis is the complementary layer** — left pilot leans left, right pilot leans right; keeping the top-heavy bot upright is a genuinely cooperative two-person job *on top of* the competitive drive. Rule is **symmetric-per-part by default; asymmetric only *inside* a single two-handed part** (e.g. a turret where one aims / one fires). Global-asymmetric stays the calibrated fallback if the prototype groans (kill signal: groans not laughs + testers begging for direct control).
|
|
||||||
|
|
||||||
**Weapon pilots & three-body coordination (2026-07-10).** Adding a weapon pilot goes from "two people negotiate one axis" to **three people applying forces to one body** — the weapon *perturbs the drivers' world* every time it acts. The design job is turning simultaneous chaos into **call-and-response**, via three interlocking moves (worked on the hammer): (1) the **wind-up is a telegraphed "brace" signal** — the bot visibly leans as it charges, so the physics itself warns the drivers; bigger hit = bigger warning *and* bigger destabilization (self-balancing); (2) **braced bonus** — if the drivers lock-pivot into a stable platform, the weapon hits harder/truer, so drive+strike become a **combo** the drivers *want* to set up ("plant → pound"); (3) the weapon **doubles as a third engine** (recoil = shove/fling/mobility) **and a movable counterweight** when idle (nobody idle). Feel: *a loaded gun bolted to a drunk animal two others are steering.* **Soft interdependence, not hard gating** — chip hits solo (new-team floor), much more when set up (coordinated ceiling).
|
|
||||||
|
|
||||||
**Weapons generalize to a five-archetype framework** (it won't only be hammers). Each weapon's coordination signature is set by its *temporal profile* + its *driver-dependence* (traverse range: fixed-forward → drivers aim it; turret → weapon pilot independent):
|
|
||||||
- **Punch** (punctuated: hammer, flipper, cannon, spring-ram) — telegraphed wind-up → braced plant-and-pound → recoil-mobility. Call-and-response "STEADY… NOW." (The hammer archetype above.)
|
|
||||||
- **Grinder** (continuous-managed: spinner, saw, drill, flamethrower) — spin up a resource (RPM/heat), hold, line up contact; the drivers fly *around* a persistent quirk (gyro precession, grinding drag). Grammar = "adapt to my state," not "wait for my moment."
|
|
||||||
- **Grip** (relational: grabber/claw, magnet, harpoon/tether) — latches to the *enemy* bot → merges two teams' three-body problems into a six-body tug-of-war. Huge comedy, big complexity/netcode jump → **tag a later tier**, not launch-day.
|
|
||||||
- **Guard** (reactive: shield, deflector, armour-angle) — angle toward the threat; thin as a solo role, pairs with another station.
|
|
||||||
- **Passive** (no pilot: ram prow, spikes, wedge) — a *shape* that works when the drivers use momentum; "the drivers *are* the weapon." (Resolves the thin-ram-pilot worry — not every weapon is a full station.)
|
|
||||||
|
|
||||||
**Two framework-level insights:**
|
|
||||||
- **The weapon *mix* is a chaos dial the team sets at build time.** All-Punch bot = one clean rhythm (easy, coordinated, weaker); one-of-each kitchen sink = glorious polyrhythm (terrifying if mastered, disaster if not). This makes pillar #6 ("over-engineering self-punishes") *mechanical* — the build phase is a **bet on how much coordination load your team can carry**; both styles valid.
|
|
||||||
- **Refined layering principle:** don't stack two *high-input-frequency* continuous roles. Driving is high-frequency-continuous; a Grinder is *low*-input-continuous (set RPM, then hold+position), so drive+spinner layers fine. Never put two always-fiddling roles on one bot.
|
|
||||||
|
|
||||||
**Cheapest de-risk, and it comes FIRST:** control feel is fully decoupled from netcode → provable with **2 controllers, one machine, offline, drive-around-cones/chase-a-ball.** A weekend Unity prototype that gates the whole design **before** any netcode spend. New spike order: **① local 2-controller drive test (control feel) → ② the 25-player physics/netcode spike.**
|
|
||||||
|
|
||||||
### Team size & lobby math — RESOLVED (2026-07-10)
|
|
||||||
|
|
||||||
**Range: team 3–5 · lobby ≥2 teams.** Sweet-spot target = **5 teams of 5 → 5 bots** (a readable-but-chaotic arena), but the flexible range is the shipping model.
|
|
||||||
- **Why 3 is the floor:** it's the smallest team that produces the signature **driver + driver + weapon three-body coordination**. A team of 2 is just two treads — no weapon pilot, the soul missing. **Why 5 is the ceiling:** coordination load + build budget top out there.
|
|
||||||
- **Teams are pre-made friend groups; matchmaking buckets them into lobbies and prefers equal sizes** (it does *not* assemble teams from solos). Min-3 implication: solos/duos get pooled into ad-hoc teams or NPC-backfilled — decide later whether solo queue is supported at all.
|
|
||||||
- **Balancing unequal sizes — flat build budget (the real mechanic, not "the vote evens it out"):** every team gets the **same build budget** (part-points / weight / power) regardless of size; stations = players, so the budget just divides differently. A **3-team builds concentrated** (few beefy parts → small, nimble, easy to coordinate); a **5-team builds distributed** (more, lighter parts → big, tippy, more simultaneous actions but softer hits + coordination tax). **Equal total power, different character** — size is a *playstyle axis, not a strength axis.* Reinforced for free by existing systems: physics punishes bigness (top-heavy = self-limiting, bigger target) and the super-linear coordination tax. Backstops: matchmaking avoids the mismatch first (so this is the rare fallback); optional **temp-NPC top-up** equalizes station count for a short-handed team (bad piloting = partial, comedic equalizer).
|
|
||||||
- **No roamer — everyone is in the bot.** The 5th player is either a (budget-weakened) **5th station** or a **second pair of hands on a two-person heavy weapon** (asymmetric-within-a-part: one aims, one fires). **Off-bot free-roaming is *exclusively* the gremlin (dead-player) mechanic** — you leave the bot only by dying. Keeps pillar #6 pure (every living player = a part).
|
|
||||||
- **Match structure ≠ team size:** build-teams can regroup into 2 sides for team modes (sportsball) or stay N-way FFA (Rumble).
|
|
||||||
- **The style vote needs ≥3 teams** — at 2 teams "can't vote your own" degenerates to a coin-flip, so 2-team lobbies fall back to **fight-result + eliminated/spectator vote**. Surface a soft "best with 4+ teams."
|
|
||||||
- **Netcode target this pins down:** ~5 bots × ~4–5 aggregate bodies + chassis ≈ **25–30 primary networked rigid bodies**, + gremlins + debris/ragdolls (the load spike ② must hold).
|
|
||||||
|
|
||||||
### Game modes (the bot is constant; the win condition varies)
|
|
||||||
|
|
||||||
- **Rumble** — all bots in one arena, last-bot-standing. Max chaos/spectacle.
|
|
||||||
- **Sumo / King-of-the-Hill** — shove rivals out of a ring, or hold a zone. Physics-forgiving; pushing = funnier flips than weapons.
|
|
||||||
- **Payload / Gauntlet** — haul or escort a thing through a hazard course; you fight the course AND each other.
|
|
||||||
- **Sportsball** — shove a giant ball into a goal. Pure party.
|
|
||||||
|
|
||||||
Bot persistence is **mode-dependent**: some modes reuse your evolving bot (short "repair & modify" phase between rounds — bot accrues scars and gets weirder); some force a fresh themed rebuild for variety/fairness.
|
|
||||||
|
|
||||||
## Open questions
|
|
||||||
|
|
||||||
- [~] **Control feel.** v0.1 model designed for the tread pilot (snap-to-cruise + lock-pivot + passive lean; see *Control feel — v0.1* in the Sketch). Drive-split fork **resolved: symmetric** (part = pilot = literal force; asymmetric held as fallback). Weapon pilots designed: **three-body call-and-response** (telegraphed wind-up + braced-bonus combo + weapon-as-engine/counterweight) generalizing to a **five-archetype framework** (Punch / Grinder / Grip / Guard / Passive), with the weapon-mix as a build-time chaos dial. **Remaining:** build the **local 2-controller drive-around-cones prototype** to prove/kill the feel before netcode.
|
|
||||||
- [ ] **Build-coupling tightness.** How strict is "one part = one pilot"? Current lean: neutral-idle + hot-swap + temp-NPC (see above) so a leaver never dooms the team. Revisit whether some parts (locomotion?) are semi-auto vs. all-manual. (Hybrid option: core locomotion semi-automatic, only weapons/specials need dedicated hands.)
|
|
||||||
- [x] **Team size / lobby math — RESOLVED (2026-07-10).** Team 3–5 · lobby ≥2 teams · **flat build budget** balances unequal sizes (concentrated↔distributed, equal power / different character) · matchmaking buckets pre-made groups & prefers equal sizes, NPC-fills the rest · **no roamer — off-bot = gremlins only** · style vote needs ≥3 teams. Full detail in the *Team size & lobby math* Sketch section.
|
|
||||||
- [ ] **Keep a hidden per-player agenda?** Optional spice for the vote ("secretly I wanted the bot to look like a duck" / "hide a chicken inside"). Adds frenemy tugging within a team, or is it noise on top of an already-full design? Undecided.
|
|
||||||
- [ ] **Voting mechanics at scale.** How do ~25 people vote for crowd-favorite without it being a mess or a popularity-contest stomp?
|
|
||||||
- [ ] **Part taxonomy.** Locomotion (wheels/treads/legs/thrusters), weapons (spinner/hammer/flipper/saw/ram), utility (grabber/shield/magnet), chassis. How many, how they map to stations.
|
|
||||||
- [ ] **Scavenge-contest rules.** How contested is the shared junkyard? Can you actively steal built parts off a rival mid-build?
|
|
||||||
- [ ] **Progression.** One-and-done implies cosmetic-only unlocks at most. Confirm no persistent power progression.
|
|
||||||
- [x] **Engine / tech — DECIDED (2026-07-10): Unity.** The engine is settled; the netcode *architecture within Unity* (below) is the new live sub-decision.
|
|
||||||
- **Why Unity.** The physics-party genre is overwhelmingly Unity: Fall Guys (Unity — custom-modified UNet + a from-scratch networked ragdoll, on dedicated servers; *not* Unreal, the common myth), Gang Beasts, Human Fall Flat, PEAK, Lethal Company, Content Warning, Party Animals, Stumble Guys, Trailmakers, Besiege, Robocraft. Small-team economics, C# iteration loop, and physics-swap flexibility all fit. The two Unreal physics-heavy titles in the genre (Rocket League, Main Assembly) both *ripped out* Unreal's physics and dropped in **Bullet**; the one UE5 game near our player count (Meccha Chameleon, 24p) barely does dynamic physics. Unreal's replication is superb but tuned for the server-authoritative *shooter* worldview — a worse default fit for janky co-op physics.
|
|
||||||
- **The MCP-tooling tiebreak was correctly overridden.** Unreal MCP already works in our setup (`pair-o-dox` via nwiro; `lostways` via ChiR24 Unreal_mcp) while Unity's is credible-but-unproven in our WSL2↔Windows setup — but that's editor-convenience, not the real risk. The netcode/genre evidence wins. (Follow-up: stand up a Unity MCP server — CoplayDev/unity-mcp or IvanMurzak/Unity-MCP — using the same host-side HTTP + non-loopback-bind + host-IP bridge pattern the UE servers use.)
|
|
||||||
- **Sobering caveat — we are aiming at the empty quadrant.** *No shipped game does 25 players + heavy multi-rigidbody contraptions + brawl.* The genre's iron law: **player count scales inversely with physics fidelity.** Heavy ragdoll/contraption brawlers cap ~8 (Gang Beasts, Party Animals, Human Fall Flat, Trailmakers, Main Assembly); Fall Guys reached 60 only with dedicated servers + a custom *lightweight* ragdoll + deliberately forgiving timing; Stumble Guys reached 32 only via deterministic Quantum + *simplified* physics; Meccha reached 24 only by having ~no physics. Our ambition sits where nobody has shipped — treat that as the defining risk, not a footnote.
|
|
||||||
- [ ] **Netcode architecture (Unity) — the live sub-decision now.** Two viable paths; both hit a **CPU wall** (many rigid bodies), not a bandwidth wall.
|
|
||||||
- **A) Dedicated server-authoritative + state sync** (the mainstream answer). Closest real blueprint: **Robocraft 2** (Unity, combat contraptions — server simulates the robot, client predicts its *own*). Server sims physics; remote bodies go kinematic and interpolate toward received transforms+velocities (priority accumulator + jitter buffer + delta compression); predict **only** each player's own robot/part. Server per-tick physics cost sets the player ceiling → server-CPU-bound (Robocraft needed bare-metal + Kubernetes).
|
|
||||||
- **B) Photon Quantum (deterministic ECS lockstep).** Precedent: **Stumble Guys** (32 players, ragdoll/swing physics, mobile). Bandwidth scales with *inputs, not bodies* — fits our "each teammate pilots one part" mechanic beautifully — and it sidesteps PhysX non-determinism entirely. Costs: every client simulates the *whole arena* (CPU-bound), gameplay is rewritten in fixed-point deterministic ECS (Unity becomes view-only), and heavy articulated joints in fixed-point are the thing most likely to misbehave.
|
|
||||||
- Lean: **undecided.** A is the proven-shape default; B has the closest player-count precedent and the best fit for the input-driven "you are a part" fantasy. Decide *after* the spike below.
|
|
||||||
- [ ] **The de-risking spike — do this before any real build.** Whichever path: two ~30-joint robots colliding, several players present, at arena scale, over simulated ≥100 ms latency, on min-spec hardware. This is the make-or-break test for the whole concept; everything else is secondary until it passes.
|
|
||||||
- [ ] **Design ⇄ netcode tension (feeds back into the pillars).** If the spike is ugly, the levers are all design-side: part-count budgets per bot (Besiege-style *shared* block budget across the team), fewer bots physically interacting at once (lean on mode design), lower simultaneous physics fidelity, and lean *harder* into "jank reads as funny, not broken" forgiving design (Fall Guys' actual secret). Revisit **pillar 1 (big lobby, ~25)** against the physics budget deliberately — the 25 may need to become "25 present, fewer in hard contact at once."
|
|
||||||
- [ ] **Art style specifics.** Lo-fi cartoon; exact look TBD.
|
|
||||||
|
|
||||||
## References
|
|
||||||
|
|
||||||
- Genre prior art (friendslop): PEAK, Lethal Company, Content Warning, Gang Beasts, Human Fall Flat, Fall Guys, Mecca Chameleon (~25-player scale reference).
|
|
||||||
- Build-and-battle prior art (the serious cousins to differentiate from): Besiege, Trailmakers, Main Assembly, Robocraft, Instruments of Destruction, BattleBots/Robot Wars (the fantasy).
|
|
||||||
- Wiki: http://192.168.1.249:6876/ideas/jankenstein
|
|
||||||
- Netcode prior art (2026-07-10 research):
|
|
||||||
- Rocket League netcode — Jared Cone, GDC 2018 "It IS Rocket Science!" ([GDC Vault](https://www.gdcvault.com/play/1024972/It-IS-Rocket-Science-The), [slides](https://media.gdcvault.com/gdc2018/presentations/Cone_Jared_It_Is_Rocket.pdf)). UE3 with PhysX swapped for **Bullet**; clients predict+resim, server authoritative.
|
|
||||||
- Fall Guys (Unity, 60p) — [The Multiplayer Group case study](https://www.themultiplayergroup.com/case-studies/fall-guys), [Azure case study](https://developer.microsoft.com/en-us/games/articles/2021/11/record-breaking-fall-guys-scales-faster-with-azure/). Modified UNet, dedicated servers, custom-from-scratch networked ragdoll.
|
|
||||||
- Robocraft 2 (Unity, combat contraptions) — closest blueprint for path A. [OVHcloud/Freejam case study](https://corporate.ovhcloud.com/en-gb/newsroom/news/ovhcloud-uk-freejam/) (server-side physics → "hefty CPU increase" → bare-metal + k8s).
|
|
||||||
- Stumble Guys (Unity + Photon Quantum, 32p) — path B precedent. [Photon Quantum](https://www.photonengine.com/quantum), [pricing](https://www.photonengine.com/quantum/pricing) (free ≤100 CCU).
|
|
||||||
- Besiege / Trailmakers (Unity, host-authoritative P2P, block/part budgets) — [Besiege Multiverse](http://multiverse.spiderlinggames.co.uk/).
|
|
||||||
- Glenn Fiedler / Gaffer On Games — [State Synchronization](https://gafferongames.com/post/state_synchronization/), [Deterministic Lockstep](https://gafferongames.com/post/deterministic_lockstep/).
|
|
||||||
- Unity MCP servers (Claude Code clients): [CoplayDev/unity-mcp](https://github.com/CoplayDev/unity-mcp) (MIT, ~12.3k⭐), [IvanMurzak/Unity-MCP](https://github.com/IvanMurzak/Unity-MCP) (Apache-2.0).
|
|
||||||
|
|
||||||
## Session log
|
|
||||||
|
|
||||||
### 2026-07-10 (control feel)
|
|
||||||
- Cracked the top open question: added **Control feel — v0.1** to the Sketch. Reframe = one part isn't thin (whole controller per part); design equation is deep individual control × tight physical coupling. Designed the **tread pilot** end-to-end (snap-to-cruise throttle, lock-pivot skill verb, passive lean so nobody's idle, boost deferred), the feel/juice layer (weight, audio desync grind, haptic tug-of-war, readable veer), and named the biggest risk (two-humans-one-drivetrain) with Plan B (asymmetric throttle/steering split) and a nuclear fallback (semi-auto locomotion).
|
|
||||||
- Key sequencing insight: control feel is **decoupled from netcode** → cheap local 2-controller "drive around cones" prototype gates the whole design and comes **before** the 25-player netcode spike. Updated the open question to `[~]` (in progress) with the remaining forks: symmetric-vs-asymmetric drive, weapon-pilot three-body coordination, and building the local prototype.
|
|
||||||
- Resolved three more forks in one session: **(1) drive split → symmetric** (part = pilot = literal force; only model that generalizes to arbitrary scrap contraptions + keeps pillar #6; asymmetric held as fallback; steal its interlocking via the lean axis). **(2) Weapon pilots → three-body call-and-response** (telegraphed wind-up as a brace signal, braced-bonus makes drive+strike a combo, weapon doubles as engine/counterweight), generalized to a **five-archetype framework** (Punch / Grinder / Grip / Guard / Passive) with the weapon-mix as a build-time chaos dial and a refined "no two high-input continuous roles" layering rule. **(3) Team size / lobby math → team 3–5, lobby ≥2 teams**, balanced by a **flat build budget** (concentrated↔distributed = equal power, different character; physics + coordination tax reinforce), matchmaking buckets pre-made groups & prefers equal sizes with NPC-fill for the rest. **Cut the "roamer"** — everyone's in the bot; off-bot free-roaming is exclusively the gremlin (dead) mechanic. Style vote needs ≥3 teams (2-team lobbies use fight-result + spectator vote). Only remaining control-feel item: build the local 2-controller prototype.
|
|
||||||
|
|
||||||
### 2026-07-10
|
|
||||||
- Researched asset marketplaces (Unity Asset Store is Unity's Fab equivalent; Fab itself also serves Unity) and Unity MCP servers for Claude Code.
|
|
||||||
- Added a Claude-tooling note under the **Engine / tech** open question: both engines have strong Claude-drivable MCP servers, so it's not an engine differentiator — but Unreal MCP is *already working in our own setup* (`pair-o-dox` via nwiro, `lostways` via ChiR24 Unreal_mcp), a convenience edge over Unity's (credible but unproven in our WSL2↔Windows setup). Netcode remains the real decider.
|
|
||||||
- Ran a 3-agent netcode/prior-art study (Unity stack, Unreal stack, shipped-game case studies) and **DECIDED the engine: Unity.** Rationale: the physics-party genre is overwhelmingly Unity (Fall Guys is Unity w/ custom netcode, not Unreal; plus Gang Beasts, Human Fall Flat, PEAK, Lethal Company, Party Animals, Stumble Guys, Trailmakers, Besiege, Robocraft); UE's replication is shooter-shaped and its two physics-heavy genre titles both swapped in Bullet. The MCP-tooling edge for Unreal was correctly overridden.
|
|
||||||
- Key sobering finding: **no shipped game occupies our quadrant** (25p + heavy multi-rigidbody + brawl); genre iron law is count-scales-inversely-with-fidelity. Converted the leftover risk into concrete open sub-questions: (1) netcode architecture — dedicated server-authoritative state sync (Robocraft blueprint) vs Photon Quantum lockstep (Stumble Guys precedent), undecided; (2) a de-risking spike (two 30-joint bots colliding at arena scale, ≥100ms latency, min-spec) to run before any real build; (3) design⇄netcode tension pressuring pillar 1's ~25-player target. Added netcode-prior-art references.
|
|
||||||
|
|
||||||
### 2026-07-09
|
|
||||||
- Created idea scaffold from template.
|
|
||||||
- Ran an initial brainstorm that pivoted from a generic "physics + shared creative task" party game into a **build-a-janky-robot brawl**. Established the 8 design pillars, the core loop, and the signature "you build your control scheme, each teammate pilots a part" mechanic.
|
|
||||||
- Resolved the creative-judging problem (fight judges function + vote judges style) and the leaver-fragility worry (neutral-idle parts + gremlin hot-swap + temp-NPC).
|
|
||||||
- Next session should crack **control feel** — the highest-leverage open question.
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
# Unity MCP setup — Claude (WSL) driving the Unity Editor (Windows)
|
|
||||||
|
|
||||||
**Goal:** let Claude Code (running in WSL) control the Unity Editor (running on the Windows host) via MCP — the same pattern our UE projects already use (nwiro / ChiR24): the MCP server runs **host-side over HTTP**, and Claude in WSL connects across the WSL↔Windows boundary by its host IP.
|
|
||||||
|
|
||||||
**Server:** [CoplayDev/unity-mcp](https://github.com/CoplayDev/unity-mcp) ("MCP for Unity", MIT, ~12k★). Chosen because it's the most popular/maintained and — critically — supports an **HTTP transport** (`url: http://host:8080/mcp`), which bridges the WSL boundary cleanly instead of a same-machine stdio assumption.
|
|
||||||
|
|
||||||
> The in-editor **"Configure All Detected Clients"** button will *not* find WSL's `claude` (it looks on Windows), so we configure Claude manually via the committed `.mcp.json` (already in this repo) pointed at the Windows host IP.
|
|
||||||
|
|
||||||
## Current values (this machine)
|
|
||||||
|
|
||||||
**✅ WORKING CONFIG (verified 2026-07-10, mcp-for-unity-server v3.4.4):**
|
|
||||||
- **Windows host IP as seen from WSL:** `172.27.208.1` (the WSL default gateway; confirm with `ip route show default`). Can change across WSL restarts — if MCP stops connecting, re-check it and update `.mcp.json`.
|
|
||||||
- **MCP server:** binds `127.0.0.1:8067` (set the port in the *MCP for Unity* window; HTTP transport). **Do NOT use 8080** — see gotcha below.
|
|
||||||
- **WSL bridge:** Windows `netsh portproxy` `0.0.0.0:8068 → 127.0.0.1:8067` (+ firewall allow on 8068). A **distinct** listen port (8068) is required — a proxy on `0.0.0.0:8067` would collide with the server's `127.0.0.1:8067` bind.
|
|
||||||
- **`.mcp.json`** (committed) → `{"unity": {"type":"http","url":"http://172.27.208.1:8068/mcp"}}`
|
|
||||||
- **`.claude/settings.local.json`** (local) pre-enables the `unity` server.
|
|
||||||
- **Verify from WSL:** `curl -s -X POST http://172.27.208.1:8068/mcp -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}'` → should return an `initialize` result naming `mcp-for-unity-server`.
|
|
||||||
|
|
||||||
**⚠️ Gotcha — the port 8080 trap (why this took a few tries):** binding `8080` failed with Windows `[Errno 13] ... forbidden by its access permissions` (WSAEACCES). That's because **WSL2 runs on Hyper-V/WinNAT, which reserves large TCP port ranges**, and 8080 fell inside one. The server silently started then shut down; the "open 8080" was only the dead portproxy accepting + resetting. Fix = pick a port **outside** the reserved ranges (check `netsh interface ipv4 show excludedportrange protocol=tcp`) — we used `8067`. Bridge with a *different* proxy port (`8068`) to avoid the loopback/all-interfaces bind collision.
|
|
||||||
|
|
||||||
**Bridge commands (admin PowerShell), for reference / re-setup:**
|
|
||||||
```powershell
|
|
||||||
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8068 connectaddress=127.0.0.1 connectport=8067
|
|
||||||
New-NetFirewallRule -DisplayName "Unity MCP 8068" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8068
|
|
||||||
netsh interface portproxy show all
|
|
||||||
```
|
|
||||||
|
|
||||||
## One-time setup (do on Windows, in the Unity Editor)
|
|
||||||
|
|
||||||
1. **Create/open the Unity project** at `F:\jankenstein` (Unity LTS). This repo already lives there — Unity will add `Assets/`, `Packages/`, `ProjectSettings/` alongside the existing files.
|
|
||||||
2. **Install the package:** `Window → Package Manager → + → Add package from git URL…`
|
|
||||||
```
|
|
||||||
https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main
|
|
||||||
```
|
|
||||||
3. **Open** `Window → MCP for Unity`. Switch the transport to **HTTP** and **Start** the server (listens on `:8080`). Note the exact port shown.
|
|
||||||
4. **Make it reachable from WSL.** The HTTP server binds loopback by default, so pick one:
|
|
||||||
- **(a)** If the panel exposes a non-loopback / `0.0.0.0` / "listen on all interfaces" option, enable it. Then WSL reaches it directly at `http://172.27.208.1:8080/mcp`.
|
|
||||||
- **(b)** Otherwise add a Windows port-proxy + firewall rule (admin PowerShell) — same trick pair-o-dox uses for nwiro:
|
|
||||||
```powershell
|
|
||||||
netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=127.0.0.1 connectport=8080
|
|
||||||
New-NetFirewallRule -DisplayName "Unity MCP 8080" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080
|
|
||||||
```
|
|
||||||
Remove later with `netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8080`.
|
|
||||||
|
|
||||||
## Connect from WSL (Claude Code)
|
|
||||||
|
|
||||||
1. Make sure the Unity Editor is **running with the project open** and the MCP server is **Started** (step 3 above) — the tools only work while the editor is live.
|
|
||||||
2. Run Claude from this folder (`/mnt/f/jankenstein`, or the symlink `~/claude/projects/jankenstein`). The committed `.mcp.json` + `.claude/settings.local.json` register/enable the `unity` server.
|
|
||||||
3. **Restart the Claude session** after any transport or `.mcp.json` change so it re-reads the config.
|
|
||||||
4. **Verify:** Claude should see `mcp__unity__*` tools. Quick smoke test: ask it to read the open scene / list GameObjects. If it fails:
|
|
||||||
- `curl -s http://172.27.208.1:8080/mcp` from WSL — no response ⇒ the bridge (step 4) isn't up or the IP changed.
|
|
||||||
- Confirm the editor is open and the server Started.
|
|
||||||
- Re-check the gateway IP (`ip route show default`).
|
|
||||||
|
|
||||||
## Gotchas
|
|
||||||
|
|
||||||
- **Editor must be open** with the project loaded — MCP drives the live editor, it doesn't launch it.
|
|
||||||
- **IP drift:** the WSL gateway IP (`172.27.208.1`) can change on WSL restart; update `.mcp.json` if so.
|
|
||||||
- **HTTP↔stdio toggling** in the Unity panel requires a Claude restart to pick up.
|
|
||||||
- This is **editor tooling**, unrelated to the game's own netcode (NGO + Relay) — different layer entirely.
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
# Prototype build-plan — networked shared bot
|
|
||||||
|
|
||||||
**Goal:** the smallest thing that lets me + 2–5 friends get into a shared arena over the internet and feel out whether **coordinating one janky bot together is fun**. Throwaway code — feel over fidelity. If it's fun, we keep going; if it groans, we iterate the control model (or flip to the asymmetric drive fallback) before spending anything on real netcode.
|
|
||||||
|
|
||||||
## Stack (decided)
|
|
||||||
|
|
||||||
- **Unity** (engine, decided) — project lives on the Windows host.
|
|
||||||
- **Netcode for GameObjects (NGO)** — high-level networking.
|
|
||||||
- **Unity Relay + Lobby** — friends **join by code**, Relay handles NAT so nobody port-forwards. Needs a free Unity account / Unity Gaming Services project.
|
|
||||||
- **Host-authoritative physics** — the host owns the bot's `Rigidbody` simulation; clients send tread **inputs** (RPCs / `NetworkVariable`s), host simulates, NGO replicates transforms. Remote clients see interpolated transforms (non-host bots/parts kinematic). This is the *simple* version of "Plan A" server-auth — **not** a commitment to the final architecture.
|
|
||||||
|
|
||||||
> Deliberately **not** doing client-side prediction, rollback, or Quantum here. Low-latency friends + host-authoritative + interpolation is plenty to judge the *feel*.
|
|
||||||
|
|
||||||
## Milestone 1 — "two treads, some friends, a flat floor"
|
|
||||||
|
|
||||||
The thesis test. Build order, each step independently testable:
|
|
||||||
|
|
||||||
1. **Empty networked scene.** NGO + Relay wired: Host button (creates a Relay allocation → shows a join code) + Join button (enter code). Two builds connect over the internet. Prove connectivity first, nothing else.
|
|
||||||
2. **A capsule you can drive, replicated.** One networked player-controlled cube on the floor; movement host-authoritative (input → RPC → host moves it → replicates). Confirms the input→host→replicate loop and that it feels ok over real ping.
|
|
||||||
3. **The shared bot: chassis + 2 treads.** One bot in the scene. Each tread is a force-applying part on the shared chassis `Rigidbody`. **Seat assignment:** first two players claim left/right tread (unclaimed treads = neutral/free, per leaver-safety).
|
|
||||||
4. **Tread control = the v0.1 model.**
|
|
||||||
- **Snap-to-cruise throttle** (stick/trigger): full-forward → fixed cruise force; partial = proportional. Both treads at cruise ⇒ straight.
|
|
||||||
- **Lock-pivot** (button): plant this tread as a pivot anchor.
|
|
||||||
- **Passive lean** (stick sideways): apply a ballast torque to fight tipping.
|
|
||||||
- Apply as **literal forces** to the shared body so differential drive + jank emerge.
|
|
||||||
5. **Something to do:** a big physics **ball** to shove around, or a few cones / a rough goal. No scoring needed — just a shared objective to make coordination *matter*.
|
|
||||||
6. **Feel juice (cheap):** weighty tuning (mass/drag so it's not twitchy), a follow camera framing the whole bot, and — if quick — the audio "grind on mismatch" cue. Skip haptics/vfx for v1.
|
|
||||||
|
|
||||||
**Success = the answer to one question:** with friends on voice chat, is wrestling this bot around *funny and satisfying*, or *infuriating*? Watch for the **kill signal**: groans not laughs + people asking for direct solo control → iterate the model (try the asymmetric throttle/steer split) before going further.
|
|
||||||
|
|
||||||
## Explicitly out of scope for M1
|
|
||||||
|
|
||||||
Building/scavenge phase · weapons · gremlins · voting · themes/art · 25 players · dedicated servers · prediction/rollback · the real netcode architecture. All later.
|
|
||||||
|
|
||||||
## Milestone 2 (only if M1 is fun) — "add a hammer"
|
|
||||||
|
|
||||||
One weapon pilot on the shared bot → test the **three-body call-and-response** (telegraphed wind-up, braced-bonus plant-and-pound, weapon-as-counterweight). This is where the coordination comedy should really sing. See `DESIGN.md` → *Weapon pilots & three-body coordination*.
|
|
||||||
|
|
||||||
## Open setup tasks
|
|
||||||
|
|
||||||
- [ ] Create the Unity project on Windows; pick Unity LTS; add the NGO + Relay + Lobby packages via Package Manager.
|
|
||||||
- [ ] Set up a Unity Gaming Services project (free tier) for Relay/Lobby; note the project link (not secrets) in `memory.md` references.
|
|
||||||
- [ ] Decide the Unity project's version control (git on `F:\` pushed to Forgejo, vs symlinked into this repo).
|
|
||||||
- [ ] Stand up the Unity MCP server so Claude can help build in-editor.
|
|
||||||
76
memory.md
76
memory.md
|
|
@ -1,76 +0,0 @@
|
||||||
# memory — JANKENBOTS
|
|
||||||
|
|
||||||
Durable memory for this project. Read at session start, update before session end. Date format: `YYYY-MM-DD`. Deep design detail lives in `DESIGN.md` (the full record carried over from the idea's `plan.md`); this file is the distilled decisions + live work.
|
|
||||||
|
|
||||||
> **Location:** this project lives at **`/mnt/f/jankenbots/jankenbots`** (Windows `F:\jankenbots\jankenbots`) so the Unity Editor (Windows-only) and the git repo/docs share one folder. `~/claude/projects/jankenbots` is a **symlink** to it. Work from either path. **Name:** the game is **JANKENBOTS** (working title was JANKENSTEIN; the archived idea folder keeps the old name at `~/claude/archive/ideas/jankenstein/`).
|
|
||||||
|
|
||||||
## Decisions & rationale
|
|
||||||
|
|
||||||
- **Concept (locked).** ~25-player friendslop build-brawl: teams build a janky physics robot from themed scrap; **each teammate pilots one functional part** (pillar #6 — "you build your control scheme, not a robot"); death → free-roaming ragdoll **gremlin**. 8 design pillars in `DESIGN.md`.
|
|
||||||
- **Engine: Unity** (2026-07-10). Decided after a 3-angle netcode/prior-art study. The physics-party genre is overwhelmingly Unity (Fall Guys, Gang Beasts, Human Fall Flat, PEAK, Lethal Company, Party Animals, Stumble Guys, Trailmakers, Besiege, Robocraft); the two UE physics-heavy titles both swapped UE physics for Bullet. An earlier Unreal-MCP-tooling edge was correctly overridden. **The defining risk is networked physics at ~25-player scale — no shipped game occupies that quadrant.**
|
|
||||||
- **Control feel v0.1 — driving = symmetric** (2026-07-10). Each locomotion part = one pilot applying *literal force* ("you are the left tread") — the only model that generalises to arbitrary scrap contraptions and the one that keeps pillar #6. Tread pilot verbs: **snap-to-cruise throttle** (both slam forward = easy straight; coordination lives in the in-between), **lock-pivot** (called-play turns), **passive lean** (nobody idle). Asymmetric (throttle/steer split) held as the fallback if the prototype groans.
|
|
||||||
- **Weapons = three-body call-and-response** (2026-07-10). A weapon pilot perturbs the drivers' world → turn simultaneous chaos into rhythm: wind-up **telegraphs a brace**, a **braced bonus** makes drive+strike a combo, weapon doubles as engine/counterweight. Generalises to **5 archetypes** — Punch / Grinder / Grip (later tier) / Guard / Passive. The **weapon mix is a build-time chaos dial** (over-building self-punishes = pillar #6 made mechanical).
|
|
||||||
- **Team size & lobby math** (2026-07-10). Team **3–5** (3 = smallest full driver+driver+weapon triangle; 5 = coordination/budget ceiling); lobby **≥2 teams**; sweet spot 5 teams of 5. Unequal sizes balanced by a **flat build budget** (small team = concentrated & nimble; big team = distributed & tippy → equal power, different character), reinforced by physics (bigness = top-heavy, self-limiting) + coordination tax; matchmaking buckets pre-made friend groups & prefers equal sizes, NPC-fills the rest. **No living "roamer" — everyone is in the bot; off-bot = gremlins (dead) only.** Style vote needs ≥3 teams (2-team lobbies use fight-result + spectator vote).
|
|
||||||
- **Prototype netcode = Unity NGO + Relay, host-authoritative** (2026-07-10). Chosen for the *throwaway* first prototype (free, first-party, friends join by code, no port-forwarding). **This does NOT commit the final architecture** — server-authoritative state sync vs Photon Quantum deterministic lockstep is still deferred until the game is proven fun.
|
|
||||||
|
|
||||||
## Open questions / TODOs
|
|
||||||
|
|
||||||
- [ ] **▶ M1 BUILD COMPLETE — only the 2-human playtest remains** (see `docs/prototype-plan.md`). Done so far (2026-07-10, all compiling clean + pushed): **packages** (NGO 2.13.0 + `com.unity.services.multiplayer` 2.2.4 — the *unified* SDK that supersedes the deprecated standalone relay/lobby packages; pulls transport 6.5.0 + core/auth), **4 scripts** in `Assets/Scripts/{Net,Bot}/`, **scene** `Assets/Scenes/M1_Arena.unity` (NetworkManager+UnityTransport+NetworkBootstrap, ground/cam/light, set as build scene), **replicated Player capsule prefab** (`Assets/Prefabs/Player.prefab`, registered as `NetworkConfig.PlayerPrefab`).
|
|
||||||
- **✅✅✅ SHOVE BALL + FOLLOW CAMERA BUILT & SMOKE-VERIFIED (2026-07-12) — M1 build is DONE.** Wired both into `M1_Arena` via MCP, solo-host smoke test passed (ball spawns + rests on ground + shoves under force; camera moves to bot+offset and frames it). Committed `b21f2d9`. **Shove ball** = in-scene `NetworkObject` sphere `ShoveBall` (1.5m, Rigidbody 10kg, linearDamping/angularDamping 0.5, Interpolate, Continuous) at world `(0,0.75,6)` (6m in front of the bot's +Z spawn facing, resting on the Plane at y=0); `SphereCollider` + `Assets/Physics/ShoveBall.physicsMaterial` (dyn/stat friction 0.4/0.5, bounce 0.3, Average combines); `NetworkRigidbody`+`NetworkTransform` → host-authoritative, exactly mirroring the Bot. **NO custom script** (passive prop; host PhysX + NetworkRigidbody replicate it for free — correct M1-minimal call). **Follow camera** = `Assets/Scripts/Camera/FollowCamera.cs` (plain client-local MonoBehaviour, NOT networked) on `Main Camera`, `target`=Bot chassis, `worldOffset (0,8,-12)`. Deliberately **position-follow-only** (fixed world offset + separately-slerped look-at, ignores the bot's roll/yaw) so the janky bot's spin/tip doesn't nauseate; escalation lever if it feels detached = follow bot YAW only. Auto-finds "Bot" by name if `target` empty. **Control-scheme note confirmed this session:** TreadPart v0.1 is **forward + steer only, NO reverse** (throttle W/↑ is forward-only per its own comment; turning = asymmetric throttle or lock-pivot; lean=anti-tip). **Unity 6 (6000.5.3f1) API gotchas hit:** `PhysicMaterial`→`PhysicsMaterial`, `PhysicMaterialCombine`→`PhysicsMaterialCombine`, Rigidbody `.drag`/`.angularDrag`→`.linearDamping`/`.angularDamping` (old names still readable but set the new ones). `NetworkBootstrap` is in the **global namespace** (no `Jankenbots.Prototype`), `HostGame()` is async `Task<string>`. **▶ ONLY M1 STEP LEFT = the real 2-human friends playtest over Relay** (this session's test was solo host + a scripted impulse as a ball-shove proxy). Then M2 = hammer.
|
|
||||||
- **✅ GIT LFS ACTIVE FOR BINARY ASSETS (2026-07-12).** `git lfs install` done repo-wide; `.gitattributes` routes images/audio/video/models/fonts/native-libs (+ binary `.asset` exceptions: `LightingData.asset`, `*.cubemap`) through LFS, while Unity YAML **text** assets (`.unity/.prefab/.mat/.asset/.anim/.controller`) stay normal mergeable git text (do NOT LFS those). **Forgejo LFS works** — server has LFS enabled + locking support; `git lfs` auths via the **Basic** credential from `~/.git-credentials` (the REST `Authorization: token` scheme does NOT work for the LFS batch endpoint, but plain `git push`/lfs picks up Basic auth from the stored cred automatically — no extra setup). First real art landed: 4 Asset Store packs (**Floreswa** characters, **Junk Car Parts**, **Junkyard models**, **LB3D** lowpoly) = 159 LFS binaries (png/obj/fbx/jpg), pushed clean (commit `7ebc175`). **Workflow when importing more assets:** Package Manager ▸ My Assets ▸ **Download THEN Import** (Download alone doesn't put files in `Assets/`); then `git add Assets/` (add the whole dir so folder-sibling `.meta`s come along — `git add Assets/Pack` MISSES `Assets/Pack.meta`), verify with `git lfs ls-files`, push. **Perftest junk** (`Assets/Resources/PerformanceTestRun*.json` from the Performance Testing package) is gitignored — not source.
|
|
||||||
- **✅ BUILD + FORGEJO-RELEASE PROCESS ESTABLISHED (2026-07-12).** Distribute playtest builds to friends as **Forgejo release assets** (Forgejo 11.0.15 at `git.rdx4.com`, repo has `has_actions:true` + runners, but we do NOT use CI — the local-MCP-build path is far faster, no Unity-license-in-CI hassle). **Process:** (1) build via MCP `manage_build action=build target=windows64|linux64 output_path=F:/jankenbots/builds/<plat>/JANKENBOTS.exe|.x86_64` → returns a `job_id`; poll `manage_build action=status job_id=…` until `result:succeeded` (a ~empty M1 scene builds in ~65s, ~105MB uncompressed; the exe appears on disk BEFORE status flips to succeeded — wait for the status, don't trust file presence). Build scene = `M1_Arena` (the only enabled build scene); default platform is StandaloneWindows64. (2) `zip` is NOT installed in WSL → archive with `python3 -c "import shutil; shutil.make_archive('NAME','zip',root_dir='.',base_dir='FOLDER')"` (win zip ≈40MB). Builds live in `F:/jankenbots/builds` (= `/mnt/f/jankenbots/builds`, OUTSIDE the repo — don't commit them). (3) **Forgejo release via API** with the token from `~/.git-credentials` (`sed -E 's#https?://[^:]+:([^@]+)@.*#\1#'`, 40-char token, user megaproxy): `POST /api/v1/repos/megaproxy/jankenbots/releases` (JSON `{tag_name,target_commitish=<sha>,name,body,prerelease:true}`) → capture `id`; then upload each asset `POST /releases/{id}/assets?name=FILE.zip -F attachment=@path`. **Release `m1-playtest-2026-07-12` (id 19)** now carries **ALL THREE** zips — Windows + macOS + Linux — https://git.rdx4.com/megaproxy/jankenbots/releases/tag/m1-playtest-2026-07-12 . Add more assets to the SAME release id rather than making a new one. **All standalone targets now installed & build clean (Win64/OSX/Linux64).** **Linux gotcha (RESOLVED):** needed **Linux Build Support (Mono)** installed in Unity Hub (Installs ▸ 6000.5.3f1 ▸ ⚙ Add modules → check the box AND click Install/Continue — checking alone doesn't download it) THEN a **full Editor restart**. Nasty trap: after a mid-session module drop, `BuildPipeline.IsBuildTargetSupported` falsely returns **True** (it re-scanned the modules folder) while the build pipeline still throws `UnityException: Build target 'StandaloneLinux64' not supported` and writes NO output — only a genuine restart loads the module into the running process. Verify a fresh Editor via a NEW `session_id` in `mcpforunity://instances`. **macOS gotcha:** unsigned `.app` → recipient bypasses Gatekeeper (right-click ▸ Open, or `xattr -dr com.apple.quarantine JANKENBOTS.app`); zipping from WSL over `/mnt/f` (mounts 777) preserves the Mach-O/x86_64 exec bit (linux binary also needs `chmod +x` on the recipient side, noted in release body). Restarting the Editor DROPS MCP — reconnect via `/mcp` and re-`set_active_instance` (hash stable across restarts: `jankenbots@47f7b88ac88d97d3`). **Background publish pattern that worked (2026-07-12):** fire `manage_build`, then a detached Bash watcher script that polls the output dir for a stable size, zips via `shutil.make_archive`, and uploads to the release via the Forgejo API — lets the build run without blocking (Unity build blocks the Editor main thread, so MCP scene edits must wait until it finishes anyway; use that window for filesystem-only agent work).
|
|
||||||
- **✅ CAPSULE REPLICATION VERIFIED (2026-07-11) — M1 netcode thesis proven.** Two clients over Relay (host = original editor via MCP, client = ParrelSync clone), both capsules spawned + drove independently + replicated **bidirectionally, smooth**. The `input→ServerRpc→host-physics→NetworkTransform` loop works over real Relay. **ParrelSync 1.5.2** installed for local 2-client testing (clone at `../jankenbots_clone_0`, symlinks Assets+ProjectSettings; open it via `ClonesManager.OpenProject` or the ParrelSync menu; its MCP loses the port fight so only the original is MCP-controllable).
|
|
||||||
- **✅✅ TWO-TREAD BOT DRIVES — M1 CORE THESIS VALIDATED (2026-07-11).** Two clients over Relay, each piloting one tread of the shared bot; coordinating both to drive straight **"feels good"** (user's words). First attempt the bot was too hot + top-heavy and launched off on a nudge → tuned to stable: cruiseForce 450, linearDamping 1.5, angularDamping 6, maxAngularVelocity 3, **centerOfMass (0,-0.6,0)** (serialized override, implicitCom=false → persists). These are baked into the scene Bot. **Gotchas found:** (1) the step-2 `PlayerPrefab` capsule still auto-spawns per client and PlayerDriver ALSO reads WASD → despawn capsules (or clear PlayerPrefab) for a clean bot test — in the real game players are seats, not free capsules; (2) each re-host mints a NEW Relay join code (old ones die) — stale codes were the cause of a failed join; (3) recompiling scripts mid-session forces the ParrelSync clone to recompile → don't Join during compile. Remaining M1: shove ball + follow camera (step 5-6), then the REAL verdict = a live 2-human friends playtest (the auto-drive was a solo proxy).
|
|
||||||
- **✅ SHARED BOT BUILT (2026-07-11), solo-smoke-verified; awaiting 2-pilot drive test.** In-scene `Bot` NetworkObject in M1_Arena: chassis Cube (Rigidbody 60kg + NetworkObject + NetworkTransform + NetworkRigidbody + SeatManager) with two child treads `Tread_L`/`Tread_R` (TreadPart, side Left/Right) at world ±1.2 X. In-scene bot auto-spawns on host; seat claim + gating verified solo. **DESIGN FIX (important):** the two drafts were mis-wired — TreadPart gated on NetworkObject `IsOwner` (needs per-tread ownership → impossible, NGO forbids nested NetworkObjects in a spawned prefab) while SeatManager's `OwnsSeat/PilotOf` API sat unused. Rewrote TreadPart to **seat-based gating**: both treads share the chassis NetworkObject; a client drives the tread whose seat it holds (`PilotOf(side)==LocalClientId`), host re-validates `OwnsSeat` on the RequireOwnership=false RPC. Also swapped TreadPart to `Keyboard.current` (New-only input). Controls: **W/↑ throttle · Shift pivot · A/D lean**. Moved SeatManager OnGUI below the bootstrap panel (was overlapping).
|
|
||||||
- **✅ UGS GATE CLEARED + HOST PATH VERIFIED (2026-07-10).** Cloud project **jankenbots** (`cloudProjectId a0d222ae-c79b-4120-bc0d-947bfd7600cb`, org `megaproxy`) is linked (has been in ProjectSettings since project creation) AND **Relay is now activated in the dashboard** (the missing step — done via cloud.unity.com ▸ Development ▸ Products ▸ Relay; there is NO enable toggle, opening the product page activates it). Verified by an in-editor Play-mode smoke test: `UnityServices.State=Initialized`, anonymous auth signed in, `HostGame()` created a real Relay allocation + join code, host's Player capsule auto-spawned (`IsSpawned`, owner=0). **The host half of M1-step-2 works end-to-end.** Still unverified: a *remote client joining* + peer-to-peer replication (needs a 2nd instance — standalone build via `manage_build` or a ParrelSync clone).
|
|
||||||
- **Next build steps:** (5) shared bot = chassis Rigidbody + 2 `TreadPart` treads + `SeatManager` (⚠ `TreadPart` still reads legacy `Input.GetAxis` — swap to `Keyboard.current` like PlayerDriver was, project is Input-System-**New-only**); (6) shove ball + follow cam; (7) 2-friends feel test over Relay (needs a standalone build via `manage_build` or a ParrelSync clone for the 2nd client).
|
|
||||||
- **Verified Relay API gotcha (baked into NetworkBootstrap):** with the unified SDK, `new RelayServerData(allocation, "dtls")` does NOT exist — use `AllocationUtils.ToRelayServerData(allocation, "dtls")` (`AllocationUtils` is in `Unity.Services.Relay.Models`). Corrected via live editor reflection.
|
|
||||||
- [x] **Project location decided + unified** — `F:\jankenbots\jankenbots` (git + Unity + docs together), symlinked `~/claude/projects/jankenbots`. Unity `.gitignore`/`.gitattributes` in place.
|
|
||||||
- [x] **Unity project created** — fresh URP + Input System template (`Assets/`, `SampleScene`, `InputSystem_Actions`). Still to add: NGO + Relay + Lobby packages (part of M1 above).
|
|
||||||
- [x] **Unity MCP working** — CoplayDev server on `127.0.0.1:8067`, portproxy `8068→8067`, `.mcp.json` → `172.27.208.1:8068/mcp`; handshake verified (v3.4.4). **Tools only load when Claude is started from this project folder** with Unity open + server running.
|
|
||||||
- [ ] **Netcode architecture (deferred, the real risk)** — dedicated server-authoritative state sync (Robocraft 2 blueprint) vs Photon Quantum lockstep (Stumble Guys precedent). Decide *after* the fun is proven + the 25-player physics spike. Netcode target ≈ 25–30 primary rigid bodies + gremlins/debris.
|
|
||||||
- [ ] **The 25-player physics/netcode spike** — two ~30-joint bots colliding at arena scale, ≥100 ms latency, min-spec. The make-or-break gate before scaling up.
|
|
||||||
- [ ] Remaining **design** questions (detail in `DESIGN.md`): build-coupling tightness, hidden per-player agenda, at-scale voting, part taxonomy, scavenge-contest rules, art style, progression (cosmetic-only), final name (working title JANKENSTEIN; alts BODGEBOTS / SCRAPYARD SCRUM / CLANKERS / RUSTBUCKETS / JALOPY WARS).
|
|
||||||
|
|
||||||
## Session log
|
|
||||||
|
|
||||||
### 2026-07-12 (session 5 — arena pass: bigger arena + container walls + rigged player avatar)
|
|
||||||
- **Built out the arena + the first player character.** (1) **Arena → 150×150m** (Ground scale 15, dirt re-tiled to 24× to hold ~6m/tile). (2) **Walls** = `ArenaWalls` (4 invisible BoxCollider physics walls, 4m tall, sealed corners, half-extent 75) + `Junkyard_Walls` (96 cargo containers, 24/side @ 6.25m pitch, from `Assets/Junkyard models/Models/Cargo/Cargo*.obj`, purely decorative — physics is the invisible walls). (3) **Rigged player avatar** — new pack `Hodaart Low Poly Character Collection 3` (humanoid-rigged, Mixamo skeleton, ships Idle/Walk/Run clips + URP mats). `Assets/Prefabs/PlayerCharacter.prefab` = Character 01 + CharacterController + NetworkObject + `OwnerAuthNetworkTransform` + `PlayerAvatar`, Animator w/ humanoid avatar + `PlayerLocomotion.controller` (Idle/Walk/Run 1D blend tree on `Speed`). Registered as `NetworkConfig.PlayerPrefab` (auto-spawn ON again). **Verified in play:** spawns, visible, poses in Idle (rig animates), owner-auth. All committed (`beb17ea`), Hodaart in LFS.
|
|
||||||
- **DESIGN CONTEXT (from user):** full-game loop = players are these rigged characters; they **run around a timed junkyard gathering scrap to build the bot**, then **drive from player stands** we'll build around the arena. So the avatar (run-around) and the tread controls are SEPARATE systems. ⚠️ **Known tension:** `PlayerAvatar` and `TreadPart` both read WASD — fine now (test avatar without claiming a seat), but the player-stand flow must gate one vs the other. Also: PlayerPrefab is `PlayerCharacter` again, so for a clean **bot-only** test you'd re-clear PlayerPrefab (avatar + tread double-drive on WASD otherwise).
|
|
||||||
- **KEY MCP GOTCHAS (cost real time this session — heed them):**
|
|
||||||
- **`execute_code` (CodeDom) references only the LAST SUCCESSFULLY COMPILED `Assembly-CSharp`.** New script types are INVISIBLE to execute_code until the scripts compile **clean** AND the domain reloads. If a script has ANY compile error, Unity keeps the old assembly and execute_code silently can't see your new types (error: "type ... does not exist in namespace"). Workflow: write script → `refresh_unity(force, wait_for_ready)` → **`read_console` for errors** → confirm via reflection probe (`System.Type.GetType("NS.Type, Assembly-CSharp")`) before referencing the type in execute_code. Existing game types (e.g. `Jankenbots.Prototype.SeatManager`) DO resolve in execute_code, so it's not a general limitation — it's the fresh-compile timing.
|
|
||||||
- **`[DisallowMultipleComponent]` is in `UnityEngine`, not `Unity.Netcode`.** (That typo failed the whole Assembly-CSharp compile → new types vanished → see above.)
|
|
||||||
- **Prefab editing: use `PrefabUtility.LoadPrefabContents(path)` → mutate → `SaveAsPrefabAsset(root, path)` → `UnloadPrefabContents`.** The `InstantiatePrefab`+unpack+`SaveAsPrefabAsset(instance)` path DROPPED the components I'd added to the instance root — LoadPrefabContents is the reliable editor for an existing prefab asset.
|
|
||||||
- **Owner-authoritative NetworkTransform** = subclass `NetworkTransform` and `protected override bool OnIsServerAuthoritative() => false;` (right for player avatars; the bot/ball stay server-auth default).
|
|
||||||
- **`HostGame()` races the async sign-in on Start** — calling it too early throws "player is already signing in". Poll `AuthenticationService.Instance.IsSignedIn` (or just retry) before hosting in a fresh play session.
|
|
||||||
- **Player movement smoothing (2026-07-12):** initial `PlayerAvatar` felt "jerky/jarring" because it applied velocity INSTANTLY (full 5m/s on press, dead-stop on release) → also popped anim Idle→Run. Fixed: `Vector3.MoveTowards`-ramp horizontal velocity (`acceleration` 45, `deceleration` 60 m/s², inspector-tunable) so starts/stops ease and Idle→Walk→Run blends. Diagnosed first (applyRootMotion already False, NT.Interpolate True/correct, TickRate 30) — the instant-velocity was the cause, not netcode. Committed `4404870`. **Still open:** no player-follow camera (camera locked to Bot), which makes on-foot movement awkward to judge — offered to add a 3rd-person player-follow cam (retarget FollowCamera to the local avatar during the on-foot phase), user hasn't decided.
|
|
||||||
- **Republished all 3 platform builds (2026-07-12) with the arena+walls+avatar content** to release `m1-playtest-2026-07-12` (id 19): rebuilt Win/OSX/Linux (0 errors each), deleted the 3 old assets via API (`DELETE /releases/19/assets/{id}`, need Basic-token; got asset ids from the release JSON), uploaded fresh zips, updated notes (you now spawn as a runnable character; bot+ball in the walled arena; WASD-overlap caveat noted). Builds live OUTSIDE the repo in `F:/jankenbots/builds` (not committed). Publish script: `scratchpad/republish_builds.sh` (gotcha: to pass a multiline body to `python3 -c` use `BODY="$B" python3 -c "...os.environ['BODY']..."`, NOT an argv trailing arg).
|
|
||||||
- **▶ RESUME:** everything committed (`4404870`) + all 3 fresh builds on the release. Next: **player-follow camera** (offered, pending user OK), **player stands** + drive-from-stand flow (gates avatar-vs-tread WASD overlap), swap grey bot chassis/treads + shove ball for scrap models, and the real 2-human playtest. Screenshots confirmed the look (container ring + dirt + character cohesive).
|
|
||||||
|
|
||||||
### 2026-07-12 (session 4 — M1 build finished: shove ball + follow camera)
|
|
||||||
- **▶ RESUME HERE next session:** the entire M1 build is done (bot drives, shove ball, follow camera — all in `M1_Arena`, all smoke-verified). **The ONE thing left in M1 is the real 2-human friends playtest over Relay** — flip off any `debugAutoDriveFull`, don't rely on scripted proxies, get two actual people each on one tread pushing the ball around. That playtest is the true fun verdict. After it → **M2 = add a hammer** (first weapon). See the "SHOVE BALL + FOLLOW CAMERA" ✅✅✅ block above for every value/gotcha.
|
|
||||||
- Fanned out two Sonnet subagents (camera-script author + ball-networking designer) while MCP was down, then wired both into the scene via MCP once the editor came back. Ball needs no script; camera is `FollowCamera.cs`. Confirmed the control scheme is **forward + steer, no reverse**. 2 commits pushed (`87f929b` camera script, `b21f2d9` scene+ball+material). Unity-6 physics API renames noted in the block above.
|
|
||||||
|
|
||||||
### 2026-07-11 (session 3 — M1 bot drives, thesis validated)
|
|
||||||
- **▶ RESUME HERE next session:** M1 core is proven (two-tread bot drives over Relay, feels good). **Remaining M1:** (1) build the **shove ball** (big physics sphere) + a **follow camera** framing the bot — makes coordination purposeful; (2) run the **real 2-human friends playtest** (this session used a host-side `debugAutoDriveFull` auto-drive as a solo proxy — flip it off / don't rely on it with real players); then **M2 = add a hammer**. To bot-test cleanly: despawn the player capsules or clear `NetworkConfig.PlayerPrefab` (they double-drive on WASD), and remember each re-host = a NEW Relay code.
|
|
||||||
- Built the whole M1 bot this session via MCP + ParrelSync 2-client testing; tuned physics live after it launched off; validated it drives straight with two pilots. All committed + pushed (see the M1-progress TODO block above for the full state, gotchas, and verified API/tuning values). ParrelSync clone editor can be closed between sessions; reopen via ClonesManager when needed.
|
|
||||||
|
|
||||||
### 2026-07-10 (session 2 — M1 build start)
|
|
||||||
- **Started Milestone 1 via a research/draft workflow + serial in-editor build.** Ran a 9-agent workflow (verified NGO/Relay API research → adversarial verify → draft 4 scripts → integration plan); the verify agent installed the packages to reflect against the *live* editor, catching two hallucinated Relay APIs before any code hit the project. Then serially, all main-loop MCP work (packages/scene/prefabs are stateful/single-editor → NOT parallelized): dropped scripts (compile clean, 0 errors), built `M1_Arena` scene + NetworkManager, made the replicated Player capsule prefab, fixed PlayerDriver input for New-only Input System. 4 commits pushed. **Stopped at the UGS-link gate** (see TODO) — nothing is runtime-testable until that's linked.
|
|
||||||
- **Runtime host smoke-test (solo, no 2nd client):** enter Play via `manage_editor play`, then `execute_code` to call `nb.HostGame()` and poll `read_console` — saw QosJob region pings + `Hosting with join code XXXXXX`. Note: the `editor/state` resource's background tick FREEZES (goes stale) during playmode transitions, but direct `execute_code`/`read_console` commands still work — probe with those, don't trust the stale state snapshot.
|
|
||||||
- **MCP resource URI correction:** editor state is `mcpforunity://editor/state` (not `/editor_state`); project info `mcpforunity://project/info`. `find_gameobjects` wildcard `*` returns nothing — search by name/component/path. `execute_code` uses CodeDom (C# 6) by default → fully-qualify `UnityEngine.Object`, no C#12 syntax.
|
|
||||||
|
|
||||||
### 2026-07-10 (session 1 — promotion + setup)
|
|
||||||
- **Promoted from `ideas/jankenstein` to a real project.** Scaffolded the WSL-side project home (this repo): filled `CLAUDE.md`, seeded this `memory.md` from the idea's `plan.md`, carried the full design record over as `DESIGN.md`, added `docs/prototype-plan.md`. Idea folder archived to `archive/ideas/jankenstein`.
|
|
||||||
- Decided to build a **basic networked prototype first** (user wants to test the coordination feel with real friends — local split-screen won't capture the social/voice-chat core). Stack: **Unity NGO + Relay**, host-authoritative, throwaway netcode. Milestone 1 = one shared bot, each player one tread.
|
|
||||||
- **Consolidated the project + seeded Unity MCP config** (`.mcp.json` → `unity` HTTP server at `172.27.208.1:8080/mcp`, `.claude/settings.local.json`, `docs/mcp-setup.md` runbook), Unity `.gitignore`/`.gitattributes` (no LFS yet).
|
|
||||||
- **Renamed JANKENSTEIN → JANKENBOTS and unified folders.** User created the Unity project at `F:\jankenbots\jankenbots` (named it jankenbots). Moved the seeded repo (git history + docs + `.mcp.json`) **into** the Unity project root so it's one folder; renamed the Forgejo repo `jankenstein → jankenbots` + updated the remote; re-pointed the symlink to `~/claude/projects/jankenbots`. Unity project is a fresh URP/Input-System template (has `Assets/`, `SampleScene`, `InputSystem_Actions`). **MCP status: ✅ WORKING (verified 2026-07-10, mcp-for-unity-server v3.4.4).** Server binds `127.0.0.1:8067` (HTTP mode), bridged to WSL via `netsh portproxy 0.0.0.0:8068→127.0.0.1:8067`; Claude reaches `http://172.27.208.1:8068/mcp` (`.mcp.json`). **Key gotcha:** 8080 is unusable — it's in a Hyper-V/WinNAT reserved range (WSL2), bind fails with WSAEACCES/Errno 13; use a non-reserved port + a *distinct* proxy port. Full detail in `docs/mcp-setup.md`. **Session wrapped here** — everything committed & pushed; resume by opening a fresh Claude session from this folder (Unity open, MCP server running) and starting Milestone 1.
|
|
||||||
|
|
||||||
## External references
|
|
||||||
|
|
||||||
- Full design record: `DESIGN.md` (this repo) — control feel v0.1, weapon archetypes, lobby math, tech direction, netcode prior art.
|
|
||||||
- Prototype build-plan: `docs/prototype-plan.md`.
|
|
||||||
- Wiki (orientation): http://192.168.1.249:6876/projects/jankenbots
|
|
||||||
- Idea-phase history: `~/claude/archive/ideas/jankenstein/` (original brainstorm `plan.md` + session logs).
|
|
||||||
- Netcode prior art (Rocket League GDC talk, Fall Guys/Robocraft/Stumble Guys case studies, Gaffer On Games) — cited in `DESIGN.md` → References.
|
|
||||||
- **Unity MCP setup runbook:** `docs/mcp-setup.md`. Server = CoplayDev/unity-mcp in **HTTP mode host-side**; Claude (WSL) connects at `http://172.27.208.1:8080/mcp` (`.mcp.json` committed). Bridge pattern mirrors the UE servers (host-side HTTP + host-IP). Not yet stood up — needs the editor + package installed.
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue