@homie-rocks/studio 0.50.2 → 0.50.3

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 CHANGED
@@ -17,6 +17,20 @@ 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.50.3] - 2026-10-13
21
+
22
+ **Plugin 0.50.3** · A counter-dash continues from where the player sees it.
23
+
24
+ A player's own dash or jump pressed while prediction catches up after a knock or correction starts at once from where they see their character, never from a stale position that jumps them across the screen.
25
+
26
+ ### Fixed
27
+
28
+ - Fresh movement actions resume live prediction immediately and carry the visible position into the correction blend. In Copperwind's Cinder Circuit, before the fix, 161 of 168 counter-dashes jumped 51–173 px in one frame; after it, all 160 of 160 moved at most 28 px, across 0–300 ms connections with loss.
29
+
30
+ ### Upgrade notes
31
+
32
+ - Follow [RULES.md](plugins/homie/skills/game/RULES.md): declare a discrete movement button as `f.press()` (or `f.pulse()` for a byte-valued action), send it through `room.input`, and implement predicted movement in `move`. Existing games with these declarations receive the fix automatically. To retain pulses through a knock or stun until control returns, opt into `player: {control: 'canMove', pulses: 'hold'}`; the default is `'drop'`. The game's action handler still decides cooldowns. This fix changes drawing only; server authority, input timestamps and replay rules are unchanged.
33
+
20
34
  ## [0.50.2] - 2026-10-13
21
35
 
22
36
  **Plugin 0.50.2** · Keep your own runner out of solid ground.
@@ -1437,3 +1437,9 @@ controls it used. Queued held state from an earlier placement cannot later
1437
1437
  change the new body. Newly received discrete presses still belong to the player
1438
1438
  when the browser has not yet learned of that placement. `idleHold` no longer keeps a stopped body displaced
1439
1439
  indefinitely. These drawing settings never alter server truth.
1440
+
1441
+ A fresh discrete movement action (press or pulse) exits the own body's historical
1442
+ catch-up path. It resumes live prediction at once and carries the drawn pose into
1443
+ the normal correction blend, so a counter-dash or jump does not wait for the
1444
+ unseen impulse's history to finish. This changes drawing only; authority, input
1445
+ timestamps, cooldowns and replay rules are unchanged.
@@ -3279,6 +3279,48 @@
3279
3279
  }
3280
3280
  }
3281
3281
  }
3282
+ },
3283
+ "0.50.3": {
3284
+ "files": {
3285
+ "CLAUDE.md": "ddf2b2a0376202f6",
3286
+ "README.md": "684b3cca8001673c",
3287
+ "HANDOFF.md": "29337e2ace95b2e7",
3288
+ "games/README.md": "5ad32fe80c61f117",
3289
+ "music/README.md": "a3dc042dadd39df8",
3290
+ "videos/README.md": "16babc3437d5545b",
3291
+ "posts/README.md": "37841aae476bd540",
3292
+ "site/README.md": "1dbdf22c03a1e505",
3293
+ "site/src/worker.mjs": "6cc5c6131eaf6fd0"
3294
+ },
3295
+ "sections": {
3296
+ "AGENTS.md": {
3297
+ "(intro)": "394cbbe934e80722",
3298
+ "## Version-matched authoring guides": "f6261a0e5801b96b",
3299
+ "## Layout": "f3a280b8c96cd068",
3300
+ "## Apps: one screen, roles and parts": "c10aa0441ea89702",
3301
+ "## Commands (all through the pinned CLI in node_modules)": "5222e08ca55e326e",
3302
+ "## The site": "0cb8dd9a6f8a0096",
3303
+ "## Making games": "bb715272fd1a615b",
3304
+ "## The Game Codex and progress": "0738ef719cef3a4c",
3305
+ "## Art direction and models": "a48fff7bf0a5f2fc",
3306
+ "## Running live games (the back office)": "51ebf2ab756f6e4d",
3307
+ "## Servers and AI seats": "1ccfd549d2369a60",
3308
+ "## Selling things (the shop)": "9e020d69dd6a954e",
3309
+ "## Continuing a build from the Claude app": "0d68081e924ca419",
3310
+ "## Rules": "b2234d80f6cbe71d",
3311
+ "## Telling Homie": "80b46fdd9e578db8",
3312
+ "## Beta": "9d02638207a26e73"
3313
+ }
3314
+ },
3315
+ "named": {
3316
+ "Homie Arcade": {
3317
+ "sections": {
3318
+ "AGENTS.md": {
3319
+ "## Commands (all through the pinned CLI in node_modules)": "611b437f5b3303f0"
3320
+ }
3321
+ }
3322
+ }
3323
+ }
3282
3324
  }
3283
3325
  }
3284
3326
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@homie-rocks/studio",
3
- "version": "0.50.2",
3
+ "version": "0.50.3",
4
4
  "description": "A studio for games, music and video on its own Cloudflare: scaffold, multiplayer starters on the netplay contract, a port toolkit that makes existing single-player web games multiplayer, the site Worker with public rooms (Table/Lobby Durable Objects and D1, all on the free Workers plan, no payment method), a site with the hub's sections (Home, Games, Music, Videos, Rooms, Posts with feeds) in the studio's own look, an epic landing page for every game, big songs and videos in the studio's own R2 once it has storage (uploaded, checked by SHA-256, served at the same addresses), deploy, and the homie.rocks directory.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
package/rules/view.ts CHANGED
@@ -1181,6 +1181,11 @@ export function openRoom<R = unknown>(opts: OpenRoomOptions = {}): Room<R> {
1181
1181
  const shown = changed ? meNow()?.pos : null;
1182
1182
  for (const [name, fd] of kind?.input ?? []) if ((fd.t === 'press' || fd.t === 'pulse') && coerce(fd,s[name],dims)) { const value=coerce(fd,s[name],dims) as number | boolean; if(fd.t==='pulse'){pulseCount+=1;const target=Math.max(stepped+1,(pulseQueue.at(-1)?.t??stepped)+1);pulseQueue.push({name,value:Number(value),n:pulseCount,t:target});net.send('pulse',[epoch,name,value,target,pulseCount]);} else pressed.set(name,value); }
1183
1183
  sample = next;
1184
+ // A discrete action belongs to the present, even while an unseen impulse is
1185
+ // being drawn from history. Resume the live prediction and let the existing
1186
+ // input correction below carry the drawn origin across that change of path.
1187
+ if (shown && catchTick !== null && kind?.input.some(([name, fd]) =>
1188
+ (fd.t === 'press' || fd.t === 'pulse') && Boolean(coerce(fd, s[name], dims)))) catchTick = null;
1184
1189
  if (shown) {
1185
1190
  const now = clock(), nextShown = meNow()?.pos;
1186
1191
  if (nextShown && distance(shown, nextShown) > 0.00001) {
@@ -1,2 +1,2 @@
1
1
  // Generated by lib/build-identity.mjs; identifies the bundled runtime sources.
2
- export const STUDIO_BUILD = Object.freeze({"version":"0.50.2","sha256":"b5a5e460524fdf3585639ef1296b5e6cc9e0596e6f13da493d9a2e6938271ca4"});
2
+ export const STUDIO_BUILD = Object.freeze({"version":"0.50.3","sha256":"2099723ed724a66028f1cddaea2a5f9dc0c8616282096b6bc98fb7857a84a800"});
@@ -1,2 +1,2 @@
1
1
  /** The @homie-rocks/studio version this Worker code is (package.json's; a test keeps them equal). Cache-busts /_homie/site.js. */
2
- export const STUDIO_VERSION_TAG = '0.50.2';
2
+ export const STUDIO_VERSION_TAG = '0.50.3';