@homie-rocks/studio 0.30.2 → 0.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +108 -1
- package/README.md +349 -23
- package/assets/animate.ts +16 -6
- package/assets/assets.ts +14 -3
- package/assets/render-page.ts +10 -2
- package/assets/safety.mjs +7 -1
- package/bin/homie-studio.mjs +204 -124
- package/lib/art-cli.mjs +61 -18
- package/lib/art-tools.mjs +53 -10
- package/lib/asset-check.mjs +249 -46
- package/lib/asset-import.mjs +11 -5
- package/lib/asset-manifest.mjs +128 -51
- package/lib/build.mjs +239 -72
- package/lib/characters.mjs +119 -20
- package/lib/check.mjs +110 -7
- package/lib/chrome.mjs +11 -0
- package/lib/clips.mjs +54 -0
- package/lib/cloudflare.mjs +203 -10
- package/lib/codex.mjs +6 -0
- package/lib/collision.mjs +245 -0
- package/lib/decisions.mjs +2 -2
- package/lib/deploy-state.mjs +166 -0
- package/lib/dev.mjs +430 -0
- package/lib/directory.mjs +172 -9
- package/lib/doctor.mjs +12 -11
- package/lib/handoff.mjs +2 -6
- package/lib/library.mjs +1 -1
- package/lib/mcp-tools.mjs +42 -37
- package/lib/mcp.mjs +1 -1
- package/lib/net.mjs +81 -2
- package/lib/node-version.mjs +40 -0
- package/lib/office.mjs +6 -6
- package/lib/optimise.mjs +39 -4
- package/lib/parts-build.mjs +169 -0
- package/lib/parts-cli.mjs +104 -0
- package/lib/parts-store.mjs +342 -0
- package/lib/parts-tools.mjs +92 -0
- package/lib/parts.mjs +720 -0
- package/lib/perf.mjs +131 -31
- package/lib/port-check.mjs +40 -6
- package/lib/preview.mjs +77 -0
- package/lib/routes.mjs +240 -0
- package/lib/scaffold.mjs +83 -22
- package/lib/shoot.mjs +307 -0
- package/lib/site.mjs +1 -2
- package/lib/stage.mjs +118 -0
- package/lib/studio.mjs +0 -66
- package/lib/style-board.mjs +49 -6
- package/lib/template-history.json +101 -0
- package/lib/trailer.mjs +47 -0
- package/lib/typecheck.mjs +107 -0
- package/mcp/ui/lineup.js +3 -3
- package/mcp/ui/rights.js +1 -3
- package/netplay/NETPLAY.md +552 -16
- package/netplay/netplay.ts +950 -43
- package/package.json +10 -1
- package/parts/PARTS.md +169 -0
- package/port/index.ts +8 -2
- package/port/personas.ts +275 -0
- package/port/powerups.ts +357 -0
- package/port/probe.ts +38 -2
- package/port/room.ts +329 -40
- package/site/SITE.md +102 -20
- package/starters/ember-vale/index.html +1 -1
- package/starters/ember-vale/src/main.ts +7 -1
- package/starters/gem-rush/index.html +1 -1
- package/starters/gem-rush/src/main.ts +41 -12
- package/starters/gem-rush-3d/assets/RIGHTS.md +0 -24
- package/starters/gem-rush-3d/assets/manifest.json +0 -24
- package/starters/gem-rush-3d/index.html +1 -1
- package/starters/gem-rush-3d/src/main.ts +50 -11
- package/starters/hero-rush-3d/assets/RIGHTS.md +0 -19
- package/starters/hero-rush-3d/assets/manifest.json +0 -19
- package/starters/hero-rush-3d/index.html +1 -1
- package/starters/hero-rush-3d/src/main.ts +50 -11
- package/worker/arrival.mjs +4 -1
- package/worker/discover.mjs +11 -25
- package/worker/index.mjs +142 -62
- package/worker/license.mjs +45 -41
- package/worker/office-page.mjs +0 -4
- package/worker/office-schema.mjs +6 -0
- package/worker/office.mjs +19 -23
- package/worker/pages.mjs +156 -29
- package/worker/parts.mjs +275 -0
- package/worker/room.mjs +157 -14
- package/worker/schema.mjs +6 -8
- package/worker/seats.mjs +71 -0
- package/worker/site.mjs +51 -53
- package/worker/version.mjs +1 -1
- package/lib/remix-assets.mjs +0 -84
package/CHANGELOG.md
CHANGED
|
@@ -17,9 +17,116 @@ To bring a studio up to date, tell Claude: "Upgrade my studio to the newest Homi
|
|
|
17
17
|
`npx -y @homie-rocks/studio@latest upgrade`, which shows what's new since the version your studio pins (from this
|
|
18
18
|
file) and what the upgrade would change, and changes nothing until you agree.
|
|
19
19
|
|
|
20
|
+
## [0.31.1] - 2026-10-06
|
|
21
|
+
|
|
22
|
+
**Plugin 0.32.1** · [#53](https://github.com/homie-rocks/homie/pull/53)
|
|
23
|
+
|
|
24
|
+
Fixes from two creators' notes on 0.31.0: Homie's holds run in Grok, `publish --before` publishes nothing, a page that loses its room is never stuck, a missing setting is never a silent zero, and a part's preview fits a phone.
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- `@homie-rocks/camera/heading.js` (camera 0.2.1): `headingFrom({ zero: '+x', toward: '+z' })` converts your game's own heading into the camera's and back, and `headingOfVector(dx, dz)` does it from a forward vector. The package now says plainly which way its heading points (yaw 0 faces +Z, a positive yaw turns toward +X, in radians), with a picture in the README and in the types. In development the follow camera warns once when the subject keeps travelling one way while its heading says another, and names the adapter; mark reversing frames with `reversing: true`, or turn it off with `followState({ headingCheck: false })`.
|
|
29
|
+
- `net.prefs.number`, `net.prefs.boolean` and `net.prefs.string` read a setting with your fallback for a missing key, a null, a wrong type or a read before the prefs arrived, and say so once in the console. `net.prefs.set` refuses a `NaN` or anything else that would be kept as `null`.
|
|
30
|
+
- `createRoom({ fallback })`, seat or solo: `'solo'` plays a private round with bots until the room has a body for the player, `'spectate'` watches, and `room.standing` says where the player stands. NETPLAY.md section 28 is the recipe, and the late-join checklist has the slow-boot, mid-round join.
|
|
31
|
+
- A shared part can say the shape of its preview: `"aspect": "4:3"` and, for phones, `"phoneAspect": "3:4"` in `preview` (whole numbers 1 to 32, no flatter than 3:1, no taller than 1:2; 16:9 if you say nothing). Every part preview has an "Open the preview" link that shows it in a tab of its own.
|
|
32
|
+
- On a custom domain, a deploy and its plan warn before anything goes live when another site's catch-all or wildcard route covers your studio's address: leave that route alone, and add the one line shown (or `deploy --own-route`). When the routes cannot be read, it says so rather than saying all is well.
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- **Homie's holds run in Grok once you trust the plugin.** 0.30.2 said Grok runs no plugin's hooks. That was wrong: Grok takes a plugin's hooks from its main manifest, ours named none there, and Grok was loading the Claude Code file instead and finding nothing. A secret is also now really taken out of what the AI reads in Grok (it was only being flagged beside the output). `setup status --client grok` says whether the holds ran and how to turn them on.
|
|
37
|
+
- **`publish --before` publishes nothing.** It asks the directory whether you are listed and how many publishes are left today. In 0.31.0 the command line ignored the flag and published.
|
|
38
|
+
- Commands that change something outside your computer (deploy, publish, storage, the office and others) stop at a flag they do not know, before anything is sent. `deploy --dry-run` was one such flag: it used to deploy.
|
|
39
|
+
- A page that loses its room no longer shows "Reconnecting…" for ever: after 20 seconds (`reconnectMaxMs`) it plays on its own with bots, says so, and rejoins when the room answers. The line over the game says what is true: "Reconnecting…" only to a page that was connected, and a full room is said in words with a way to another room.
|
|
40
|
+
- A player who is seated while every body is taken gets one as soon as a body frees up or the next round starts, instead of watching for the rest of the visit.
|
|
41
|
+
- A browser that freezes for a few seconds while a heavy game boots no longer drops its connection when it wakes.
|
|
42
|
+
- A part's preview is no longer cut off on a phone: a narrow frame is at least 320 px tall instead of about 197.
|
|
43
|
+
- The 3D starters say which of their angles a camera can take as it stands and which needs converting.
|
|
44
|
+
|
|
45
|
+
### Upgrade notes
|
|
46
|
+
|
|
47
|
+
- Grok: install or reinstall the plugin with trust, `grok plugin install homie-rocks/homie#plugins/homie --trust`. From then on a deploy, a Cloudflare change and a paid call are held for your "proceed", as in Codex.
|
|
48
|
+
- A studio that pins 0.31.0 still publishes on `publish --before` from its own command line until it upgrades.
|
|
49
|
+
- If your game reads settings with `net.prefs.get`, move numbers to `net.prefs.number(key, fallback)`: a `null` kept by an older build is now read as nothing kept.
|
|
50
|
+
- `@homie-rocks/camera` is 0.2.1.
|
|
51
|
+
|
|
52
|
+
## [0.31.0] - 2026-10-06
|
|
53
|
+
|
|
54
|
+
**Plugin 0.32.0** · [#50](https://github.com/homie-rocks/homie/pull/50) · [release-2026-10-06-studio-0.31.0](https://github.com/homie-rocks/homie/releases/tag/release-2026-10-06-studio-0.31.0)
|
|
55
|
+
|
|
56
|
+
Fixes from two creators' logs of building real studios: games now build on each other by sharing parts (remix is retired), a slow 3D game keeps its host, local play stays local, and synthesized bass plays at its written pitch.
|
|
57
|
+
|
|
58
|
+
### Added
|
|
59
|
+
|
|
60
|
+
- **Parts: how games build on each other.** A part is a piece of a game that its studio chooses to share: a creature, a level generator, a camera, a bot brain, an audio pack. Never the whole game. In chat, `parts_find` looks for pieces other studios shared, `part_add` brings one into your studio (every file checked, the original credited, yours to tune from then on), `part_new` lifts a piece out of one of your games (the game still builds and plays the same), and `part_share` shares it under a licence you pick. A part is private until you share it, and live after your next deploy. Your studio lists what it shares at `/.well-known/homie-parts.json`; homie.rocks lists the shared parts of listed studios at `/parts/`. The packages a part builds on are installed by npm. The design is `parts/PARTS.md`.
|
|
61
|
+
- Planning or making a game now starts by looking for packages and for parts before anything is written from scratch, and a game's Codex has a Built from section saying what came from where. A deploy's plan shows the licences and credits of the parts a game uses, and says when they cannot be combined.
|
|
62
|
+
- `homie-studio preview <id>`: one built game's files at an address on this computer, with no Wrangler and no rooms, for a capture or a script.
|
|
63
|
+
- `homie-studio shoot <id>`: a two-browser seat check, then frames taken on a stepped clock, so a 3D game can be captured without a GPU.
|
|
64
|
+
- `homie-studio trailer <id>`: films a game frame by frame on a virtual clock, rebuilds its sound from the game's own files, picks the shots from what the game played, and delivers 16:9, 1:1 and 9:16. Sound that does not go through the sound player (live-synthesized voices, speech) is not in the mix, and the result says so.
|
|
65
|
+
- `homie-studio build --types` checks your games' TypeScript before building. New studios come with TypeScript; an older one runs `npm install --save-dev typescript`.
|
|
66
|
+
- A game can `await import()`: it becomes a file that loads when asked for, so a 3D game can load its later scenes late.
|
|
67
|
+
- game.json `netplay`: `stallMs` (how long a host may go quiet, 1.5 to 10 s), `version` (after a deploy, old tabs and new tabs no longer share a room; an old tab is told to reload at its round's break), and `params` (your own names passed from `/play?…` to the game as `net.params`; `debug` and `q` always pass).
|
|
68
|
+
- `net.link` and a "Reconnecting…" line over the game say when a game is cut off from its room. `net.offline` and `net.connected` are documented against it, and `net.reconnects` counts.
|
|
69
|
+
- `net.prefs` keeps a game's settings and personal bests (16 KB a game). `localStorage` throws inside the game's frame on purpose, and the docs now say why.
|
|
70
|
+
- `createRoom({ admit })` chooses which body a newcomer takes, for fresh joins and for a room revived from its checkpoint alike; `createRoom({ ties: 'shared' })` gives equal scores the same place; `features` lets a host turn a new mechanic on only when every player's build has it. NETPLAY.md has a rollout recipe for changing a game's rules while rooms are open, and a late-join checklist that includes "everyone leaves, then a new visitor enters before the room expires".
|
|
71
|
+
- `guardGestures()` for a touch game: a long press never selects text or raises copy and paste. The play page and its frame refuse selection too. Try it on a real phone; a harness cannot.
|
|
72
|
+
- `net.shell` tells a game where the play page's own buttons sit, so a HUD stays clear of them.
|
|
73
|
+
- A game declares what it scores with: game.json `playtest.primary` (a key or the mouse on a computer; a control or a region on a phone), and `"scoring": "together"` for a cooperative game.
|
|
74
|
+
- studio.json `"site": { "order": [...] }` sets the order of your games everywhere they are listed. A Home of your own takes the generated hero with `<!-- homie:home-hero -->`.
|
|
75
|
+
- A 3D game sets its own model budgets: game.json `"assets": { "budgets": { "triangles", "bytes" } }`, read by the game, by `assets check` and by `assets add`.
|
|
76
|
+
- `assets use <game> <asset> unused` marks a file the game no longer draws. The lineup draws the inventory, the cast and the environment separately.
|
|
77
|
+
- `collision_bake` (in chat; `homie-studio collision bake <game> <model.glb>`) turns a model into something figures can stand on, tied to the model by a checksum; `collision_check` fails when the model changed since, or a bot cannot walk a route you authored. It uses `@homie-rocks/heightfield`, which your AI installs in the studio the first time.
|
|
78
|
+
- `assets add --lo 0.2` also writes `<asset>_lo.glb`, the cheap copy for the far band of a prop drawn at two levels of detail.
|
|
79
|
+
- `homie-studio shoot <id> --preview` takes pictures of the built game with no site running, and names the build they are of.
|
|
80
|
+
- The models skill brings in a finished job from a connected fal account under the same budget and receipts (`models.mjs import`), and tells a missing local key apart from a connector's sign-in.
|
|
81
|
+
- New modules in the packages (each stands alone; install from npm): a third-person follow camera that never ends up in a wall or the player's head (`@homie-rocks/camera`); quality tiers, dynamic resolution that undoes a drop that did not help, and near/far instanced props (`@homie-rocks/render`); a ready-made post stack per tier (`@homie-rocks/postfx`); combo, hit-stop and bursts (`@homie-rocks/fx`); a per-sound limiter (`@homie-rocks/audio`); buildings with floors, doors and stairs, routes checked the way bots walk them, markers on every level, and grounded capture positions (`@homie-rocks/heightfield`); five bot personas and host-owned power-ups whose timers survive a host change (`@homie-rocks/studio/personas`, `/powerups`).
|
|
82
|
+
|
|
83
|
+
### Changed
|
|
84
|
+
|
|
85
|
+
- **Remix is retired.** A game is no longer handed over whole. `game remix`, the `game_remix` tool, the "Make a game like this" band, the office's Remixable switch and the Studio pane's Remix button are gone, and a studio no longer serves a game's source (its old address answers 410 and points to `/parts/`). A game that was a remix keeps its credit, "Based on <game> by <studio>".
|
|
86
|
+
- A game's bundle is named by its content, so a fresh page never loads the previous bundle from the edge after a deploy. The build says for each game whether it changed and its build hash; a deploy says which games it changes; the live site says the same hash in `/.well-known/homie-studio.json`.
|
|
87
|
+
- A build is put in place only when all of it is there. It no longer deletes `site/dist`, so anything running from it keeps its files.
|
|
88
|
+
- `dev` keeps rooms local even when the studio has a custom domain: production routes are left out of the local configuration, and `dev` stops with a clear reason if a game would be handed a socket anywhere but this computer. A wrapper script is no longer needed for that.
|
|
89
|
+
- `deploy` keeps your custom-domain and exact-host routes, refuses to deploy a wildcard or catch-all route, and says which route to add when another Worker's wildcard answers your domain first. Only one deploy of a studio runs at a time.
|
|
90
|
+
- A playtest records what state the game was in at every press and picture (round phase, alive, time left, the link), and says BLOCKED or N/A instead of failing a row that landed on a results screen, a dead body, the loading cover or a dropped connection. "First picture" is the first picture of the game itself; the loading card is timed separately. UI coverage is measured with the thumb held on the stick, so numbers differ from earlier runs.
|
|
91
|
+
- One scripted round is reported as one round: a bot win is a measured gap with a recommendation to repeat it, never "people cannot win". The report states that UI coverage is DOM-only and that canvas HUDs were not checked, and calls out a reconnect beside a completed round.
|
|
92
|
+
- The playtest's review step asks one approval question naming exactly which files it sends and where, has a local fallback that sends nothing, and the report says which review ran, or that none did.
|
|
93
|
+
- `assets check` calls its scene numbers an inventory estimate and lists what it cannot see without running the game. "First play" is now "shipped payload": the same number and budget, honestly named (`firstPlayMB` still works). `perf` reports what was really fetched before play and, when your game exposes them, the renderer's draw calls and triangles.
|
|
94
|
+
- `check`, `perf`, `shoot`, `port check` and the playtest say the same sentence when this computer cannot look a site up. `perf` reports the arrival mode and when the game itself said it was ready, and the playtest reports a HUD element sitting under one of the play page's own controls.
|
|
95
|
+
- Listing a studio shows the licences and credits of the parts its games use before it is listed.
|
|
96
|
+
- `publish` says how many publishes are left today, and listing a studio again after a deploy is a re-read that does not count against the day.
|
|
97
|
+
- A room's log lines carry a time, the game and the room, and tell a player leaving apart from a failed operation. Room and error lines under `dev` carry a time (`--timestamps` for every line).
|
|
98
|
+
- The build names the hero files a landing wants and their shapes: `hero/wide.jpg` (16:9), `hero/tall.jpg` (9:16), and `wide.mp4` / `tall.mp4`.
|
|
99
|
+
|
|
100
|
+
### Fixed
|
|
101
|
+
|
|
102
|
+
- **Synthesized bass played octaves too high.** A number is now always hertz and a MIDI note is given as `midi`. A2 was written as 110 Hz and played as MIDI note 110 (4.7 kHz); the kick, the tom and several effects had the same fault. They sound different now: as written.
|
|
103
|
+
- A loop keeps its seam through the limiter, and a loop that does not repeat is listed in the warnings instead of beside an empty list. The "steady tone" warning gives the tone's level and how much of the time it is there, and no longer fires on a melody's brief high partial. The sound player no longer hangs on an effect listed as a single file.
|
|
104
|
+
- A trailer's cuts are counted in frames and stay on the beat, and every delivery is yuv420p, limited range, tagged BT.709.
|
|
105
|
+
- A game that does not build fails `homie-studio build` and leaves the built site as it was.
|
|
106
|
+
- A slow 3D game no longer swaps hosts on every hitch: the helper sends a heartbeat while a host's frames are stuck. A game that boots for seconds can wait longer for its room (`connectOpenMaxMs`) or start the wait itself (`net.start()`).
|
|
107
|
+
- A visitor who revives an emptied room takes a body over properly (`onTakeover`, `adopt`). A player who joins while the host is briefly disconnected gets a body. A returning player's score is no longer reset.
|
|
108
|
+
- Every command says at once when Node.js is older than 22, instead of ending without a word.
|
|
109
|
+
- `dev` and `dev --stop` clean up after a server that was stopped another way, and a game added while `dev` runs is picked up.
|
|
110
|
+
- A stuck screenshot decoder stops as BLOCKED after 20 seconds instead of hanging, and the playtest exits when its report is written.
|
|
111
|
+
- A press into a wall is no longer reported as unresponsive controls: the playtest tries the other way and reports both.
|
|
112
|
+
- The big-screen check no longer fails a local preview for a missing join QR; it still requires one on a deployed address.
|
|
113
|
+
- A hostname this computer cannot look up is reported as this computer's network, with local testing offered, not as a broken site or game.
|
|
114
|
+
- Standalone textures and skies are measured and counted in picture memory, and pictures shipped with no record are listed. Normal and roughness maps the game does not draw can be declared (`"inGame": { "maps": "base" }`) and leave the estimate.
|
|
115
|
+
- A second clip library for one skeleton is refused unless declared supplemental; a supplemental one joins coverage and previews. Removing a starter character keeps its pack's credit while its retargeted clips remain. `anim plan` and `anim preview` show the ground speed each character's walk and run cover on its own rig.
|
|
116
|
+
- A `net.playable()` that arrives after the automatic arrival warns: pass `arrival: 'game'`.
|
|
117
|
+
|
|
118
|
+
### Upgrade notes
|
|
119
|
+
|
|
120
|
+
- Remix settings do nothing now: `"remix"`, `"share"`, `landing.make` and the licence words `remix-with-credit`, `remix-freely` and `no-remix`. The build says so once; delete them when convenient. Leave `"remixOf"` in a game that was a remix: it is the credit. Nothing is removed from your database.
|
|
121
|
+
- A game's `"license"` is now the SPDX licence it names for itself (`"MIT"`), shown in its credits.
|
|
122
|
+
- Sound made with the sound skill plays at its written pitch after this release. If you raised a bass part an octave to work around the old fault, lower it again.
|
|
123
|
+
- A game with no port probe gets its playtest `move` row BLOCKED where it used to pass silently.
|
|
124
|
+
- The first deploy after upgrading asks the homie.rocks directory to read a listed studio again, once.
|
|
125
|
+
- The packages that gained modules are new versions: `@homie-rocks/camera`, `render`, `postfx`, `fx`, `audio` and `heightfield` 0.2.0.
|
|
126
|
+
|
|
20
127
|
## [0.30.2] - 2026-10-04
|
|
21
128
|
|
|
22
|
-
**Plugin 0.31.2** · [#48](https://github.com/homie-rocks/homie/pull/48)
|
|
129
|
+
**Plugin 0.31.2** · [#48](https://github.com/homie-rocks/homie/pull/48) · [release-2026-10-04-studio-0.30.2](https://github.com/homie-rocks/homie/releases/tag/release-2026-10-04-studio-0.30.2)
|
|
23
130
|
|
|
24
131
|
Fixes from first runs in Codex and Grok: a missing connector no longer stops a new studio, you are told when Homie's holds are off (in Grok they are), Grok has an install command, and a one-sentence studio gives you a Play link before it polishes.
|
|
25
132
|
|