juicyjuicy 0.4.2 → 0.5.0
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 +34 -3
- package/dist/skill/SKILL.md +8 -1
- package/dist/skill/reference/manifest.md +2 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19983,6 +19983,15 @@ var relativePath = (what) => external_exports.string().transform(normalizePath).
|
|
|
19983
19983
|
`${what} must be a relative path inside the project`
|
|
19984
19984
|
);
|
|
19985
19985
|
var tagSchema = external_exports.string().min(2).max(24).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, "tags are lowercase words, e.g. puzzle or tower-defense");
|
|
19986
|
+
var languageNames = new Intl.DisplayNames(["en"], { type: "language", fallback: "none" });
|
|
19987
|
+
function languageName(code) {
|
|
19988
|
+
if (!/^[a-z]{2,3}$/.test(code)) return void 0;
|
|
19989
|
+
return languageNames.of(code);
|
|
19990
|
+
}
|
|
19991
|
+
var languageSchema = external_exports.string().trim().toLowerCase().refine(
|
|
19992
|
+
(code) => languageName(code) !== void 0,
|
|
19993
|
+
'use a two-letter language code, like "en" or "pl"'
|
|
19994
|
+
);
|
|
19986
19995
|
var SOURCE_URL_PATTERN = /^https:\/\/[a-z0-9.-]+(:\d{1,5})?(\/[\w.~%/@+=:-]*)?$/i;
|
|
19987
19996
|
var sourceUrlSchema = external_exports.string().max(300).regex(
|
|
19988
19997
|
SOURCE_URL_PATTERN,
|
|
@@ -20002,6 +20011,8 @@ var gameFieldSchemas = {
|
|
|
20002
20011
|
engine: external_exports.enum(ENGINES),
|
|
20003
20012
|
madeWith: external_exports.array(memberText().min(1).max(40)).max(5),
|
|
20004
20013
|
tags: external_exports.array(tagSchema).max(5),
|
|
20014
|
+
/** The languages a player can play it in, the default first. Each one counts once. */
|
|
20015
|
+
languages: external_exports.array(languageSchema).min(1, "list at least one language").max(5).transform((codes) => [...new Set(codes)]),
|
|
20005
20016
|
input: external_exports.array(external_exports.enum(INPUTS)),
|
|
20006
20017
|
orientation: external_exports.enum(ORIENTATIONS),
|
|
20007
20018
|
aspectRatio: external_exports.string().regex(/^(fill|\d{1,2}:\d{1,2})$/, 'use "W:H" like "16:9", or "fill"'),
|
|
@@ -20021,6 +20032,7 @@ var manifestSchema = external_exports.strictObject({
|
|
|
20021
20032
|
engine: gameFieldSchemas.engine.default("other"),
|
|
20022
20033
|
madeWith: gameFieldSchemas.madeWith.default([]),
|
|
20023
20034
|
tags: gameFieldSchemas.tags.default([]),
|
|
20035
|
+
languages: gameFieldSchemas.languages.default(["en"]),
|
|
20024
20036
|
input: gameFieldSchemas.input.default([]),
|
|
20025
20037
|
orientation: gameFieldSchemas.orientation.default("any"),
|
|
20026
20038
|
aspectRatio: gameFieldSchemas.aspectRatio.default("16:9"),
|
|
@@ -20084,6 +20096,7 @@ var updateGameRequestSchema = external_exports.object({
|
|
|
20084
20096
|
engine: gameFieldSchemas.engine.optional(),
|
|
20085
20097
|
madeWith: gameFieldSchemas.madeWith.optional(),
|
|
20086
20098
|
tags: gameFieldSchemas.tags.optional(),
|
|
20099
|
+
languages: gameFieldSchemas.languages.optional(),
|
|
20087
20100
|
input: gameFieldSchemas.input.optional(),
|
|
20088
20101
|
orientation: gameFieldSchemas.orientation.optional(),
|
|
20089
20102
|
aspectRatio: gameFieldSchemas.aspectRatio.optional(),
|
|
@@ -20785,8 +20798,16 @@ var REMIX_LICENSE_NAME = "JuicyJuicy remix license";
|
|
|
20785
20798
|
var REMIX_LICENSE = "Members may download this game's files and publish a changed version of it on JuicyJuicy, credited to the original. It doesn't allow publishing the game or a remix of it anywhere else, or passing the files on. Turning Remixable off stops new remix downloads; remixes already published stay up.";
|
|
20786
20799
|
|
|
20787
20800
|
// ../shared/src/listing.ts
|
|
20788
|
-
var GAME_SORTS = [
|
|
20801
|
+
var GAME_SORTS = [
|
|
20802
|
+
"newest",
|
|
20803
|
+
"oldest",
|
|
20804
|
+
"trending",
|
|
20805
|
+
"upvoted",
|
|
20806
|
+
"downvoted",
|
|
20807
|
+
"played"
|
|
20808
|
+
];
|
|
20789
20809
|
var GAME_PERIODS = ["24h", "week", "month", "all"];
|
|
20810
|
+
var GAME_LISTS = ["featured", "favorites", "unplayed"];
|
|
20790
20811
|
var DEFAULT_GAME_LIST_QUERY = {
|
|
20791
20812
|
sort: "newest",
|
|
20792
20813
|
period: "all",
|
|
@@ -20801,8 +20822,10 @@ var paramSchemas = {
|
|
|
20801
20822
|
period: external_exports.preprocess(lowercase2, external_exports.enum(GAME_PERIODS)),
|
|
20802
20823
|
engine: external_exports.preprocess(lowercase2, external_exports.enum(ENGINES)),
|
|
20803
20824
|
tag: external_exports.preprocess(lowercase2, gameFieldSchemas.tags.element),
|
|
20825
|
+
lang: languageSchema,
|
|
20804
20826
|
q: external_exports.string().max(MAX_GAME_SEARCH_LENGTH),
|
|
20805
20827
|
remixes: external_exports.enum(["0", "1"]),
|
|
20828
|
+
list: external_exports.preprocess(lowercase2, external_exports.enum(GAME_LISTS)),
|
|
20806
20829
|
page: external_exports.string().regex(/^\d{1,4}$/, "use a whole number").transform(Number).pipe(external_exports.number().min(1).max(MAX_GAME_LIST_PAGE))
|
|
20807
20830
|
};
|
|
20808
20831
|
function remixFilter(param) {
|
|
@@ -20814,8 +20837,10 @@ var gameListRequestSchema = external_exports.object({
|
|
|
20814
20837
|
period: paramSchemas.period.default(DEFAULT_GAME_LIST_QUERY.period),
|
|
20815
20838
|
engine: paramSchemas.engine.optional(),
|
|
20816
20839
|
tag: paramSchemas.tag.optional(),
|
|
20840
|
+
lang: paramSchemas.lang.optional(),
|
|
20817
20841
|
q: paramSchemas.q.optional(),
|
|
20818
20842
|
remixes: paramSchemas.remixes.optional(),
|
|
20843
|
+
list: paramSchemas.list.optional(),
|
|
20819
20844
|
page: paramSchemas.page.default(DEFAULT_GAME_LIST_QUERY.page)
|
|
20820
20845
|
}).transform(({ remixes, ...rest }) => ({ ...rest, remixes: remixFilter(remixes) }));
|
|
20821
20846
|
|
|
@@ -24346,7 +24371,7 @@ var program = new Command();
|
|
|
24346
24371
|
// package.json
|
|
24347
24372
|
var package_default = {
|
|
24348
24373
|
name: "juicyjuicy",
|
|
24349
|
-
version: "0.
|
|
24374
|
+
version: "0.5.0",
|
|
24350
24375
|
description: "Publish AI-made browser games to juicyjuicy.games",
|
|
24351
24376
|
type: "module",
|
|
24352
24377
|
license: "MIT",
|
|
@@ -26331,6 +26356,7 @@ var KEY_ORDER = [
|
|
|
26331
26356
|
"engine",
|
|
26332
26357
|
"madeWith",
|
|
26333
26358
|
"tags",
|
|
26359
|
+
"languages",
|
|
26334
26360
|
"input",
|
|
26335
26361
|
"orientation",
|
|
26336
26362
|
"aspectRatio",
|
|
@@ -26353,6 +26379,7 @@ async function buildManifest(dir, flags, ask) {
|
|
|
26353
26379
|
orientation: pick2("orientation", "any"),
|
|
26354
26380
|
aspectRatio: pick2("aspectRatio", "16:9"),
|
|
26355
26381
|
tags: pick2("tags", []),
|
|
26382
|
+
languages: pick2("languages", ["en"]),
|
|
26356
26383
|
input: pick2("input", []),
|
|
26357
26384
|
remixable: pick2("remixable", false)
|
|
26358
26385
|
};
|
|
@@ -27740,7 +27767,11 @@ function createProgram() {
|
|
|
27740
27767
|
"--made-with <list>",
|
|
27741
27768
|
'models and tools, e.g. "Claude Opus 5.5, Claude Code"',
|
|
27742
27769
|
splitList
|
|
27743
|
-
).option("--tags <list>", "up to 5 tags, e.g. arcade,space", splitList).
|
|
27770
|
+
).option("--tags <list>", "up to 5 tags, e.g. arcade,space", splitList).option(
|
|
27771
|
+
"--languages <list>",
|
|
27772
|
+
"language codes players can pick, the default first, e.g. en,pl",
|
|
27773
|
+
splitList
|
|
27774
|
+
).addOption(new Option("--input <list>", `controls: ${INPUTS.join(", ")}`).argParser(splitList)).addOption(new Option("--orientation <orientation>").choices(ORIENTATIONS)).option("--aspect-ratio <ratio>", 'like 16:9, or "fill"').option("--thumbnail <file>", "png/jpg/webp in the game folder").option("--remixable", `let other members remix it on JuicyJuicy only (${REMIX_LICENSE_NAME})`).option("--source-url <url>", "public source code, e.g. a GitHub repo").addHelpText(
|
|
27744
27775
|
"after",
|
|
27745
27776
|
`
|
|
27746
27777
|
${REMIX_LICENSE_NAME} (--remixable): ${REMIX_LICENSE}`
|
package/dist/skill/SKILL.md
CHANGED
|
@@ -53,15 +53,22 @@ npx -y juicyjuicy@0 init --yes --json \
|
|
|
53
53
|
- `init` keeps what an existing `juicy.json` already says (flags override), and detects `buildDir`, `entry` and `engine`. Check what it wrote.
|
|
54
54
|
- `--made-with`: your real model and the tool you run in, e.g. `"Claude Opus 5.5, Claude Code"` or `"Gemini 3 Pro, Antigravity"`.
|
|
55
55
|
- The slug (the `/g/<slug>` URL name) defaults to one made from the title. Once published it belongs to this user; reuse it to publish updates.
|
|
56
|
+
- `--languages`: the languages a player can switch between, English first, e.g. `en,pl`. Leave it out for a game that's only in English (the default is `en`).
|
|
56
57
|
- Offer to write `HOW_I_MADE_IT.md` (a short story of how the game was made, up to 20 KB of markdown). `init` picks it up when it exists.
|
|
57
58
|
|
|
58
59
|
All fields: [reference/manifest.md](reference/manifest.md).
|
|
59
60
|
|
|
61
|
+
**English first.** Every game on JuicyJuicy plays in English by default, so players anywhere can pick it up:
|
|
62
|
+
|
|
63
|
+
- If the game's text (menus, buttons, instructions, dialogue, text drawn in images) is in another language, build an English version before publishing: keep the player-facing text in one table per language, start in English, and add a visible switch (like `EN | PL`) to the language the game was made in. Tell the user in a sentence that you did. Pass both with `--languages en,pl`.
|
|
64
|
+
- `title` and `description` are always in English. A title that is a name (`Kasztanek`) stays as it is; one made of words in another language gets translated (`Wielka Ucieczka` → `The Great Escape`). Tell the user the English title you chose.
|
|
65
|
+
- Text in the thumbnail (step 4) is in English too.
|
|
66
|
+
|
|
60
67
|
### 4. Add a thumbnail
|
|
61
68
|
|
|
62
69
|
A `thumbnail.png` (or `.jpg`/`.webp`, up to 2 MB and 4096×4096 pixels, ideally the game's shape, like 1280×720 for 16:9) in the project folder becomes the game's tile.
|
|
63
70
|
|
|
64
|
-
- **If you can run the game in a browser and take a screenshot**, make a deliberate one: get past any title or "click to start" screen to real gameplay, then save it as `thumbnail.png` and pass `--thumbnail thumbnail.png` to `init`.
|
|
71
|
+
- **If you can run the game in a browser and take a screenshot**, make a deliberate one, with the game in English: get past any title or "click to start" screen to real gameplay, then save it as `thumbnail.png` and pass `--thumbnail thumbnail.png` to `init`.
|
|
65
72
|
- **Otherwise the CLI takes one itself.** When `juicy.json` names no thumbnail, `check` and `publish` open the built game in Chrome, Edge, Chromium or Brave on this machine (headless, at the game's `aspectRatio`, sandboxed and offline: only the game's own files load) and use a screenshot taken a few seconds after it loads. A game that loads its engine, fonts or images from another site is captured without them. Don't block publishing on a thumbnail.
|
|
66
73
|
- **Not for a remix**, unless the user agrees: the screenshot runs the other creator's code. Ask first; only if they say yes, pass `--auto-thumbnail` to `check` and `publish`. Without it you get a warning starting `no thumbnail: this is a remix`.
|
|
67
74
|
|
|
@@ -13,6 +13,7 @@ The manifest in the project folder. `juicyjuicy init` writes it; edit it by hand
|
|
|
13
13
|
"engine": "phaser",
|
|
14
14
|
"madeWith": ["Claude Opus 5.5", "Claude Code"],
|
|
15
15
|
"tags": ["arcade", "space"],
|
|
16
|
+
"languages": ["en", "pl"],
|
|
16
17
|
"input": ["keyboard", "touch"],
|
|
17
18
|
"orientation": "landscape",
|
|
18
19
|
"aspectRatio": "16:9",
|
|
@@ -33,6 +34,7 @@ The manifest in the project folder. `juicyjuicy init` writes it; edit it by hand
|
|
|
33
34
|
| `engine` | | `vanilla`, `phaser`, `threejs`, `pixi`, `godot`, `unity` or `other`. | `--engine` |
|
|
34
35
|
| `madeWith` | | Up to 5 models/tools, e.g. `["Claude Opus 5.5", "Claude Code"]`. | `--made-with "a, b"` |
|
|
35
36
|
| `tags` | | Up to 5 lowercase words or `word-word`, e.g. `puzzle`, `tower-defense`. | `--tags a,b` |
|
|
37
|
+
| `languages` | | Up to 5 language codes a player can switch between, English first, e.g. `["en", "pl"]`. Default `["en"]`. Shown as a language filter on JuicyJuicy. | `--languages a,b` |
|
|
36
38
|
| `input` | | Any of `keyboard`, `mouse`, `touch`, `gamepad`. | `--input a,b` |
|
|
37
39
|
| `orientation` | | `landscape`, `portrait` or `any` (default). | `--orientation` |
|
|
38
40
|
| `aspectRatio` | | `"W:H"` like `"16:9"` or `"4:3"`, or `"fill"` to fill the player. Default `16:9`. | `--aspect-ratio` |
|