juicyjuicy 0.11.0 → 0.11.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/dist/index.js CHANGED
@@ -19807,7 +19807,7 @@ function date4(params) {
19807
19807
  }
19808
19808
 
19809
19809
  // ../shared/src/cli.ts
19810
- var CLI_RELEASE = "0.11.0";
19810
+ var CLI_RELEASE = "0.11.1";
19811
19811
  function cliCommand(args) {
19812
19812
  return `npx -y juicyjuicy@${CLI_RELEASE} ${args}`;
19813
19813
  }
@@ -26456,7 +26456,7 @@ var program = new Command();
26456
26456
  // package.json
26457
26457
  var package_default = {
26458
26458
  name: "juicyjuicy",
26459
- version: "0.11.0",
26459
+ version: "0.11.1",
26460
26460
  description: "Publish AI-made browser games to juicyjuicy.games",
26461
26461
  type: "module",
26462
26462
  license: "MIT",
@@ -9,19 +9,19 @@ JuicyJuicy hosts **static browser games** (HTML/JS/CSS/assets, WebAssembly) and
9
9
 
10
10
  Run every CLI command with `--json`. Each output line is a JSON object; the **last** line is the result, either `{"ok": true, …}` or `{"ok": false, "error": {"code", "message", "details"?, "hint"?}}`. The exit code is `0` (ok), `1` (fix the game or `juicy.json`), `2` (log in) or `3` (network or server problem, so retry).
11
11
 
12
- Run the CLI exactly as written here, `npx -y juicyjuicy@0.11.0 …`: this skill is made for that release. If JuicyJuicy answers that the CLI is out of date, run the command its message gives. It updates the CLI and this skill together; read this skill again afterwards and use the release it names from then on.
12
+ Run the CLI exactly as written here, `npx -y juicyjuicy@0.11.1 …`: this skill is made for that release. If JuicyJuicy answers that the CLI is out of date, run the command its message gives. It updates the CLI and this skill together; read this skill again afterwards and use the release it names from then on.
13
13
 
14
14
  ## Procedure
15
15
 
16
16
  ### 1. Make sure the CLI is logged in
17
17
 
18
18
  ```bash
19
- npx -y juicyjuicy@0.11.0 whoami --json
19
+ npx -y juicyjuicy@0.11.1 whoami --json
20
20
  ```
21
21
 
22
22
  If it exits with `2`, log in. `login` opens the user's browser and **waits up to 10 minutes** for them to approve:
23
23
 
24
- - Run `npx -y juicyjuicy@0.11.0 login --json` in the background if your shell can, and read its first output line (`{"event": "device_code", "userCode", "verificationUrl"}`) right away, and show the user the code and link without waiting for them to ask: the page shows the same code, and that's how they know the login is theirs.
24
+ - Run `npx -y juicyjuicy@0.11.1 login --json` in the background if your shell can, and read its first output line (`{"event": "device_code", "userCode", "verificationUrl"}`) right away, and show the user the code and link without waiting for them to ask: the page shows the same code, and that's how they know the login is theirs.
25
25
  - Then tell the user, with the real code and link: *"A JuicyJuicy page opened in your browser. Check it shows the code **WXTZ-BCDF** and click **Approve**. If no page opened, go to <verificationUrl>."*
26
26
  - If your shell can't run commands in the background, say that first (without a code: it doesn't exist yet), then run it in the foreground with a timeout of at least 10 minutes. The code is also printed as `Your code: …`.
27
27
  - The user needs a JuicyJuicy account (it's invite-only for now). If the page says they can't sign in, they need an invite link from a friend who's a member.
@@ -45,7 +45,7 @@ Files and folders starting with `.` (`.env`, `.git/`, …) and `node_modules/` a
45
45
  `juicy.json` sits in the project folder and describes the game. Create or update it with `init`, filling in what you know from the game you built:
46
46
 
47
47
  ```bash
48
- npx -y juicyjuicy@0.11.0 init --yes --json \
48
+ npx -y juicyjuicy@0.11.1 init --yes --json \
49
49
  --title "Snake Deluxe" \
50
50
  --description "Eat the apples, don't bite your tail. Arrow keys or swipe." \
51
51
  --made-with "<your model name>, <the tool you run in>" \
@@ -85,7 +85,7 @@ To replace it, the user saves a screenshot as `thumbnail.png` in the project fol
85
85
 
86
86
  Do this **every time**, also for updates. It protects the user and their players; JuicyJuicy's server runs its own checks as well, so this is help, not a formality to get past.
87
87
 
88
- 1. **Check.** Run `npx -y juicyjuicy@0.11.0 check --json`. Errors (a failed result) must be fixed: explain each one (`details` has a `rule` and a `path`), and offer to fix it. If the user says no, **stop and don't publish**: the server would refuse it anyway. Warnings in the result (`findings`) go into step 2.
88
+ 1. **Check.** Run `npx -y juicyjuicy@0.11.1 check --json`. Errors (a failed result) must be fixed: explain each one (`details` has a `rule` and a `path`), and offer to fix it. If the user says no, **stop and don't publish**: the server would refuse it anyway. Warnings in the result (`findings`) go into step 2.
89
89
  Every file in the result's `files` will be public. If `unusualFiles` isn't empty (names that look like keys or private data, project files like `package.json`, notes and other files a web game doesn't load), **show the user that list and ask whether those files should be public** before publishing; offer to move them out of the build folder or set `buildDir` to a folder with just the game.
90
90
  2. **Security review.** Follow [reference/review.md](reference/review.md): keys and tokens, `innerHTML`/`eval` on network or multiplayer data, `http://` loads, trackers, login or payment forms, anything that leaves the page. Same rule: for what it marks as must-fix, fix it or don't publish.
91
91
  3. **Standards.** Check the game against these and tell the user, in a sentence or two, what falls short; offer to fix it. A "no" still publishes: not every game can have touch controls.
@@ -114,7 +114,7 @@ Keep it short when there's nothing to say: "Checked: no problems found" is enoug
114
114
  ### 6. Publish
115
115
 
116
116
  ```bash
117
- npx -y juicyjuicy@0.11.0 publish --json --message "<what changed, in a few words>"
117
+ npx -y juicyjuicy@0.11.1 publish --json --message "<what changed, in a few words>"
118
118
  ```
119
119
 
120
120
  This makes the new version live: when the user says "publish", that's what they want. Don't add `--draft` (see "Other commands") unless they asked in words for it not to go live yet. Not for a first publish, a big game or one you're unsure of either: the user would have to find the dashboard and make it live themselves.
@@ -141,7 +141,7 @@ The game's page under My games on JuicyJuicy has an **Upgrades** panel; its Add
141
141
 
142
142
  Other features on the panel (touch controls, gamepad, mouse lock, auto-pause) are "Coming soon" and have no recipe yet: if asked for one, say so, and build it your own way only if the user wants.
143
143
 
144
- 1. **Find the project.** Log in first (step 1). The project is the folder whose `juicy.json` has the game's `slug`: the current folder, or one the user points you to. **If it isn't on this computer** (or you're in a chat app or sandbox), download the live version: `npx -y juicyjuicy@0.11.0 pull <slug> --json` writes it into a new folder named after the slug (`dir` in the result) with its `juicy.json`, and you work there. Read the result's `next`: the download is the built game, so for a bundled one (minified code), ask whether the user has the source somewhere, or use `sourceUrl`, before changing the bundle itself. `pull` only works for the user's own games (`NOT_FOUND` otherwise).
144
+ 1. **Find the project.** Log in first (step 1). The project is the folder whose `juicy.json` has the game's `slug`: the current folder, or one the user points you to. **If it isn't on this computer** (or you're in a chat app or sandbox), download the live version: `npx -y juicyjuicy@0.11.1 pull <slug> --json` writes it into a new folder named after the slug (`dir` in the result) with its `juicy.json`, and you work there. Read the result's `next`: the download is the built game, so for a bundled one (minified code), ask whether the user has the source somewhere, or use `sourceUrl`, before changing the bundle itself. `pull` only works for the user's own games (`NOT_FOUND` otherwise).
145
145
  2. **Read the recipe** for the upgrade and make the change. Keep everything else about the game as it is.
146
146
  3. **Build and try it** (step 2), then **declare it** in `juicy.json` as the table says, adding to what's already listed.
147
147
  4. **Review and publish** as steps 5–7 say, with `--message "Add <upgrade>"`. In step 5's `check` result, `features.detected` lists what JuicyJuicy found in the files; a `feature-missing` warning means a declared upgrade isn't there yet: fix it before publishing.
@@ -149,14 +149,14 @@ Other features on the panel (touch controls, gamepad, mouse lock, auto-pause) ar
149
149
 
150
150
  ## Bring all my games up to date
151
151
 
152
- When the user asks to bring their JuicyJuicy games up to date or fix a **Needs update** badge, when `check` warns `requirement-missing`, or after updating the CLI: follow [reference/update-all-games.md](reference/update-all-games.md). It starts with `npx -y juicyjuicy@0.11.0 check-games --json`, which checks every game of the user's at once and settles what a script can; the rest are code changes, one game at a time.
152
+ When the user asks to bring their JuicyJuicy games up to date or fix a **Needs update** badge, when `check` warns `requirement-missing`, or after updating the CLI: follow [reference/update-all-games.md](reference/update-all-games.md). It starts with `npx -y juicyjuicy@0.11.1 check-games --json`, which checks every game of the user's at once and settles what a script can; the rest are code changes, one game at a time.
153
153
 
154
154
  ## Remix a game
155
155
 
156
156
  A game marked remixable on JuicyJuicy can be downloaded, changed and published as a new game that links back to it. Log in first (step 1), then:
157
157
 
158
158
  ```bash
159
- npx -y juicyjuicy@0.11.0 remix <slug> --json
159
+ npx -y juicyjuicy@0.11.1 remix <slug> --json
160
160
  ```
161
161
 
162
162
  - The first line is `{"event": "license", "name", "text"}`: the remix license. Tell the user in a sentence what it says. In short: the remix may be published **on JuicyJuicy only**, never anywhere else, and the files aren't to be passed on. The full text is:
@@ -192,9 +192,9 @@ Everything else is in [reference/troubleshooting.md](reference/troubleshooting.m
192
192
 
193
193
  ## Other commands
194
194
 
195
- - `npx -y juicyjuicy@0.11.0 list --json`: the user's games; `list <slug>` shows one game's versions. `--all` lists every game on JuicyJuicy instead (60 a page, `--page 2` and on; `nextPage` in the result), `--owner <username>` another creator's. Narrow and order any list with `--search <title text>`, `--tag`, `--engine`, `--remixes`, `--multiplayer` (games with rooms), `--highscores` (games with a leaderboard), `--sort newest|upvoted|downvoted|played` and `--period 24h|week|month|all`, e.g. to find a game to remix.
196
- - `npx -y juicyjuicy@0.11.0 publish --draft --json`: uploads a new version without making it live (players keep the current one). Only when the user asks for that in words (e.g. "upload it but don't put it live yet"), never on your own judgment. The result has `draft: true`; when they say so, make it live with `rollback <version>`, or they can on the dashboard.
197
- - `npx -y juicyjuicy@0.11.0 rollback <version> --slug <slug> --json`: makes an earlier version or a draft live, e.g. when the user says the last update broke the game. Run `list <slug>` first to pick the version with the user; one waiting for an admin's review can't be made live (`FORBIDDEN`).
198
- - `npx -y juicyjuicy@0.11.0 pull <slug> --json`: downloads the live version of one of the user's own games into a new folder with its `juicy.json`, to change it when the project isn't on this computer (see "Add a JuicyJuicy upgrade").
199
- - `npx -y juicyjuicy@0.11.0 check-games --json`: checks all the user's games against JuicyJuicy's features and required updates, declares the features it finds where a game never declared them, and lists what still needs a change (see "Bring all my games up to date").
200
- - `npx -y juicyjuicy@0.11.0 open <slug>`: opens the game page in the browser.
195
+ - `npx -y juicyjuicy@0.11.1 list --json`: the user's games; `list <slug>` shows one game's versions. `--all` lists every game on JuicyJuicy instead (60 a page, `--page 2` and on; `nextPage` in the result), `--owner <username>` another creator's. Narrow and order any list with `--search <title text>`, `--tag`, `--engine`, `--remixes`, `--multiplayer` (games with rooms), `--highscores` (games with a leaderboard), `--sort newest|upvoted|downvoted|played` and `--period 24h|week|month|all`, e.g. to find a game to remix.
196
+ - `npx -y juicyjuicy@0.11.1 publish --draft --json`: uploads a new version without making it live (players keep the current one). Only when the user asks for that in words (e.g. "upload it but don't put it live yet"), never on your own judgment. The result has `draft: true`; when they say so, make it live with `rollback <version>`, or they can on the dashboard.
197
+ - `npx -y juicyjuicy@0.11.1 rollback <version> --slug <slug> --json`: makes an earlier version or a draft live, e.g. when the user says the last update broke the game. Run `list <slug>` first to pick the version with the user; one waiting for an admin's review can't be made live (`FORBIDDEN`).
198
+ - `npx -y juicyjuicy@0.11.1 pull <slug> --json`: downloads the live version of one of the user's own games into a new folder with its `juicy.json`, to change it when the project isn't on this computer (see "Add a JuicyJuicy upgrade").
199
+ - `npx -y juicyjuicy@0.11.1 check-games --json`: checks all the user's games against JuicyJuicy's features and required updates, declares the features it finds where a game never declared them, and lists what still needs a change (see "Bring all my games up to date").
200
+ - `npx -y juicyjuicy@0.11.1 open <slug>`: opens the game page in the browser.
@@ -16,4 +16,4 @@ JuicyJuicy offers English, French, Italian, German, Spanish and Polish (`en`, `f
16
16
  Run the game, switch to each language and go through the menus and the first minute of play: no missing keys (an untranslated key shows up as the key's name), no clipped text, and the choice is still there after a reload.
17
17
 
18
18
  ## Declare it
19
- Set `languages` in `juicy.json` to every language the game now has, English first, e.g. `"languages": ["en", "fr", "pl"]` (or `npx -y juicyjuicy@0.11.0 init --yes --json --languages en,fr,pl`). Don't add it to `features`: JuicyJuicy reads `languages`, and shows the game in each language's filter.
19
+ Set `languages` in `juicy.json` to every language the game now has, English first, e.g. `"languages": ["en", "fr", "pl"]` (or `npx -y juicyjuicy@0.11.1 init --yes --json --languages en,fr,pl`). Don't add it to `features`: JuicyJuicy reads `languages`, and shows the game in each language's filter.
@@ -21,12 +21,12 @@ Don't build anything yet. **Ask the user how multiplayer should work in this gam
21
21
 
22
22
  1. **What kind of play:** together against the game (co-op), against each other (versus), taking turns, or a race or party round?
23
23
  2. **How many players:** 2 to 10.
24
- 3. **How players join:** an **Invite** button that shares a link, a code shown on screen to type in, and/or **public rooms** anyone playing the game can find in a list and join (see "Public rooms"). Can someone join a game that has started, or only in the lobby?
24
+ 3. **How players join:** through the default menu (see "The menu"): **Multiplayer** → **Search lobby** (a list of public lobbies, plus a code box) or **Host lobby** (a lobby the host switches between Public and Private, with an Invite link). Say you'll build that unless they want something else. Can someone join a game that has started, or only in the lobby?
25
25
  4. **When someone leaves:** does the game go on without them? When the host leaves, the next player takes over (see "When the host changes"); is that right for this game?
26
26
  5. **Phones:** should it play on phones (touch controls)?
27
27
  6. **Anything else:** teams, rounds, a winner screen, what each player sees of the others.
28
28
 
29
- Then write the design back in a few lines: the screens (menu, lobby, game, results), what the host runs, what each player sends and what the host sends back. **Build it only once the user agrees**, then follow "Using it" and "How to build it".
29
+ Then write the design back in a few lines: the screens (the default menu's, then game and results), what the host runs, what each player sends and what the host sends back. **Build it only once the user agrees**, then follow "The menu", "Using it" and "How to build it".
30
30
 
31
31
  ## The snippet
32
32
  Paste it as is, before the game's own code: an inline `<script>` in `index.html`, or the top of the main script. Don't change it. It works next to the cloud-saves snippet, in either order (an older copy of the cloud-saves snippet, without `window.juicy.save ||` near its top, must come first).
@@ -486,27 +486,69 @@ window.juicy.rooms || (function (juicy) {
486
486
  })(window.juicy);
487
487
  ```
488
488
 
489
+ ## The menu
490
+ Every game gets this multiplayer menu unless the user asks for another. Build it as the game's own screens, in its own look (fonts, colors, button style), and make every screen work at phone width and by keyboard.
491
+
492
+ 1. **Main menu:** a **Multiplayer** button next to the game's own buttons (Play, Settings…).
493
+ 2. **Multiplayer:** two buttons, **Search lobby** and **Host lobby**, and **Back**.
494
+ 3. **Search lobby:**
495
+ - A small framed box listing the public lobbies from `juicy.rooms.list()`: on each row the host's login (with `textContent`), the players (`2/4`), the label in the game's own words if the game uses labels, and a **Join** button. The box keeps its size and scrolls inside when the list is long.
496
+ - A **refresh icon button** (↻, with `aria-label="Refresh"`) at the box's top right. The list loads once when the screen opens and again only when the player presses it (each read counts against the player's limit; never more often than every 5 seconds).
497
+ - Under the box, a line "Private lobby? Enter its code", a **code box** (6 letters, upper case, `maxlength="6"`) and a **Join** button; Enter in the box joins too.
498
+ - An empty list says so in the box ("No open lobbies. Host one!") and keeps the code box working.
499
+ - **Back**.
500
+ 4. **Host lobby** opens a room with `create({ max, public: true })` and goes straight to the lobby screen. **Join** from Search or the code box goes there too.
501
+ 5. **The lobby:**
502
+ - The **lobby code** big and spaced out (`K7QX2M`), so it can be read out.
503
+ - For the host only, a **Public / Private** switch: Public is listed in Search lobby; Private is only for people with the code or invite link (`room.setPublic(false)`, `room.setPublic()`), with that line under it. It starts on Public; a game meant only for friends (or a user who asks) starts on Private instead. Everyone else sees which it is as text, without the switch.
504
+ - The players, the host marked (a crown or "(host)"), with empty "Waiting…" slots up to `room.max` (`2/4`).
505
+ - **Invite** (`room.invite()`: JuicyJuicy's share sheet), **Start** for the host only (the others see "Waiting for the host"), and **Leave**.
506
+ 6. **Opened from an invite link** (`juicy.rooms.invited()`): skip the menu and join that room's lobby.
507
+
508
+ Errors (a wrong code, a full room, signed out) show as a short line on the screen the player is on, which stays open. A closed room goes back to the Multiplayer screen with the reason.
509
+
489
510
  ## Using it
490
511
  ```js
491
- // Opened from an invite link: join that room straight away.
512
+ // Opened from an invite link: join that lobby straight away.
492
513
  const code = await juicy.rooms.invited();
493
- if (code) start(await juicy.rooms.join(code));
514
+ if (code) enter(() => juicy.rooms.join(code));
494
515
 
495
- // The menu's "Play with friends" opens a room; "Join" takes a code the player types.
496
- playButton.onclick = async () => start(await juicy.rooms.create({ max: 4 }));
497
- joinButton.onclick = async () => start(await juicy.rooms.join(codeInput.value));
516
+ multiplayerButton.onclick = () => showScreen("multiplayer"); // Search lobby, Host lobby, Back
517
+ hostButton.onclick = () => enter(() => juicy.rooms.create({ max: 4, public: true }));
518
+ searchButton.onclick = () => { showScreen("search"); refresh(); };
519
+ refreshButton.onclick = refresh; // the ↻ icon at the list's top right
520
+ joinCodeButton.onclick = () => enter(() => juicy.rooms.join(codeInput.value));
498
521
 
499
- // "Find a game" lists the public rooms; "Host a public game" opens one anyone can join.
500
- findButton.onclick = async () => showRooms(await juicy.rooms.list()); // [{ code, host, players, max, label }]
501
- hostButton.onclick = async () => start(await juicy.rooms.create({ max: 4, public: true, label: "duel" }));
522
+ async function refresh() {
523
+ const rooms = await juicy.rooms.list(); // [{ code, host, players, max, label }]
524
+ // One row per room: host login and players (textContent), and a Join button that runs
525
+ // enter(() => juicy.rooms.join(room.code)). None: "No open lobbies. Host one!"
526
+ showRooms(rooms);
527
+ }
528
+
529
+ async function enter(open) {
530
+ try {
531
+ start(await open());
532
+ } catch (error) {
533
+ showError(error.code); // a short line on this screen: wrong code, full, signed out…
534
+ }
535
+ }
502
536
 
503
537
  function start(room) {
504
- showLobby(room.code, room.players); // [{ id: "p1", name: "luk" }, …], with textContent
538
+ showScreen("lobby");
539
+ showLobby(room); // room.code, room.players ([{ id: "p1", name: "luk" }, …], with textContent), room.max
540
+ publicSwitch.hidden = !room.isHost();
541
+ publicSwitch.onchange = () => room.setPublic(publicSwitch.checked); // Public / Private
505
542
  inviteButton.onclick = () => room.invite(); // JuicyJuicy's share sheet, with Copy link
506
- room.on("join", (player) => addToLobby(player));
507
- room.on("leave", (player) => removeFromLobby(player));
508
- room.on("message", (data, from) => handle(data, from));
509
- room.on("close", (reason) => backToMenu(reason));
543
+ startButton.hidden = !room.isHost();
544
+ startButton.onclick = () => { room.send({ k: "start" }); room.lock(); beginGame(room); };
545
+ leaveButton.onclick = () => room.leave();
546
+ room.on("join", () => showLobby(room));
547
+ room.on("leave", () => showLobby(room));
548
+ room.on("host", () => showLobby(room)); // the new host gets the switch and Start
549
+ room.on("public", (isPublic) => showPublic(isPublic));
550
+ room.on("message", (data, from) => (data.k === "start" ? beginGame(room) : handle(data, from)));
551
+ room.on("close", (reason) => { showScreen("multiplayer"); showError(reason); });
510
552
  }
511
553
  ```
512
554
 
@@ -524,11 +566,10 @@ function start(room) {
524
566
  ## How to build it
525
567
  - **The host runs the game.** Players send their input (`{ k: "input", left: true }`, a move, a card played); the host applies it to the one true game state and sends the state, or what changed, to everyone. Players draw what the host sent and never decide outcomes themselves. For a real-time game, send state 10 to 20 times a second and smooth movement between updates; send input when it changes, not every frame.
526
568
  - **Small messages with a kind:** `{ k: "state", … }`, `{ k: "input", … }`. Each message is at most 16 KB as JSON, and each player may send at most 60 messages and 64 KB a second (one `send` to everyone counts once). Over that, messages are dropped (`RATE_LIMITED`), and far over it the player is disconnected (`TOO_FAST`).
527
- - **The lobby:** show the code and the players, an **Invite** button (`room.invite()`) and, for the host, **Start**. When the game starts, the host sends `{ k: "start", … }` and calls `room.lock()` if nobody may join mid-game.
528
- - **Public rooms** suit games where strangers can have a good time together: versus or party games with short rounds, drop-in co-op. Keep invite-only (the default) for games meant for friends, long sessions, or games that need everyone from the start. A game can offer both: **Play with friends** opens a private room, **Find a game** shows `list()` and **Host a public game** opens a public one.
529
- - Show the list as the game's own screen: each room's host login (with `textContent`), its players (`2/4`) and its label in the game's own words, with **Join**, and a **Refresh** button. Refresh when the player asks or at most every 5 seconds while the list is showing (each read counts against the player's limit). An empty list says so and offers to host one.
569
+ - **The lobby** is the screen in "The menu". When the game starts, the host sends `{ k: "start", … }` and calls `room.lock()` if nobody may join mid-game. If players may drop in, the host sends `{ k: "start" }` to each player who joins (`room.send(data, player.id)`) so they go straight into the game.
570
+ - **Public and private lobbies:** Host lobby opens a public room, which Search lobby lists; the host's switch makes it private (`room.setPublic(false)`: only the code and the invite link get in) and public again (`room.setPublic()`). The `"public"` event tells everyone, so the lobby can show which it is.
530
571
  - Lock the room (`room.lock()`) when the round starts unless players may drop in: that takes it off the list. Unlock it after the round to let the next players in.
531
- - A label is only the game's own id, from a fixed set in the code. **Never** put text a player typed into a label: no room names (there's no moderation; the security review treats it like free-text chat).
572
+ - **Labels** are optional, for a game with modes or maps in Search lobby (`create({ public: true, label: "duel" })`, `list({ label })`). A label is only the game's own id, from a fixed set in the code. **Never** put text a player typed into a label: no lobby names (there's no moderation; the security review treats it like free-text chat).
532
573
  - **When the host changes** (the host left or dropped): every player keeps the last state the host sent, so on `"host"` the new host (`room.isHost()`) carries on from it and starts sending state. A turn-based game resends whose turn it is.
533
574
  - **When a player leaves**, the host decides: remove their character, let the round finish, or end the game if too few are left.
534
575
  - **Dropped connections:** phones drop them when the game goes to the background. The snippet reconnects by itself (three tries) and keeps the player's id; during that time `send` does nothing. When the host comes back, it asks for nothing: players resend what they need on `"join"` or `"host"`.
@@ -6,7 +6,7 @@ With `--json`, a failed command's last line is `{"ok": false, "error": {"code",
6
6
 
7
7
  | Code | Meaning | Fix |
8
8
  |---|---|---|
9
- | `UNAUTHORIZED` | No saved login, or the token was revoked. | `npx -y juicyjuicy@0.11.0 login --json` (the user approves in the browser). In CI, set `JUICY_TOKEN`. |
9
+ | `UNAUTHORIZED` | No saved login, or the token was revoked. | `npx -y juicyjuicy@0.11.1 login --json` (the user approves in the browser). In CI, set `JUICY_TOKEN`. |
10
10
  | `EXPIRED_TOKEN` | The login code expired (10 minutes) or was used. | Run `login` again. |
11
11
  | `ACCESS_DENIED` | The user clicked Deny. | Ask them, then run `login` again. |
12
12
 
@@ -5,7 +5,7 @@ For "bring my JuicyJuicy games up to date", "fix the required updates", a **Need
5
5
  1. **Check every game at once.** Log in first (SKILL.md step 1), then run:
6
6
 
7
7
  ```bash
8
- npx -y juicyjuicy@0.11.0 check-games --json
8
+ npx -y juicyjuicy@0.11.1 check-games --json
9
9
  ```
10
10
 
11
11
  JuicyJuicy checks the live version of each of the user's games on its side. It records which features each one has and, for a game whose `juicy.json` never listed its `features`, declares what it finds in the files (like cloud saves). Nothing is uploaded and no new version is made. The result has one entry per game in `games` (`features` with `on`/`off`/`unknown`, `requirements` with `passed`), `toFix` (the games that still need a code change, each with its `prompts`), `notReached` and `next`.
@@ -13,7 +13,7 @@ For "bring my JuicyJuicy games up to date", "fix the required updates", a **Need
13
13
  2. **If `notReached` isn't empty**, run `check-games` again: it had no time for those games.
14
14
 
15
15
  3. **For each game in `toFix`**, one at a time:
16
- - Find its project, or download the live version with `npx -y juicyjuicy@0.11.0 pull <slug> --json` (SKILL.md, "Add a JuicyJuicy upgrade", step 1).
16
+ - Find its project, or download the live version with `npx -y juicyjuicy@0.11.1 pull <slug> --json` (SKILL.md, "Add a JuicyJuicy upgrade", step 1).
17
17
  - Do what each prompt says, with the recipe it names when it names one.
18
18
  - Make sure `juicy.json` has `features` (`[]` if the game has none of the upgrades).
19
19
  - Check and publish an update as SKILL.md steps 5–7 say, with `--message "Required update: <what>"`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "juicyjuicy",
3
- "version": "0.11.0",
3
+ "version": "0.11.1",
4
4
  "description": "Publish AI-made browser games to juicyjuicy.games",
5
5
  "type": "module",
6
6
  "license": "MIT",