尚未收集儲存庫資訊。
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
For Cookierun resources
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗A Cookie Run combi stores a cookie, relay, pet, and treasure, but nothing else — the run's goal, whether it plays itself, the episode, boosts, and cookie power+ selections would otherwise live only in your head. The combi name is 10 characters, which is enough room to carry all of it. An optional loadout section goes further still, writing down the cookie, relay, pet, and treasure choices themselves, so a whole build travels as one code even without the game in front of you.
Every slot is something you can read at a glance: a letter from the name of what it holds, a digit where the thing is a number, and 0 for off or none.
slot: 1 2-3 4 5 6-7 8 9 10
M GG E B RR P P P
ex: J MX 3 5 RV F W 0
SE2: A X0 T 0 42 0 0 0
| Slot | Field | Encoding |
|---|---|---|
| 1 | Mode | M Manual, A Auto, S Semi-auto, J Semi-auto with a jump at the start |
| 2-3 | Goal | Two characters for the set of goals, below |
| 4 | Episode | A Any, 1-7 Episode 1-7, C Special Episode 1 (Island of Coins), T Special Episode 2 (Tower of Frozen Waves), R Special Episode 3 (Mysterious Rabbit Hole), X Special Exp Episode (XP-Elixir Workshop) |
| 5 | Boosts | One character for the whole set, below |
| 6-7 | Random boost | 00 none, otherwise two characters for one of the eleven below |
| 8-10 | Cookie power+ | One slot per group of powers, below |
The combi name is letters and digits only: the game field takes it as is, and a - inside it would read as the section separator below. There is no version character among the ten: the format version is the full code's, the first character of the loadout section below.
The starting action has no slot of its own. A jump at the start is one more thing a hand does, so it is J in the mode slot — a semi-auto run that jumps. A manual run never jumps: encoding one drops its action.
A run aims for Score on its own, or for one to three of Money, Exp and Box. An auto run never aims for Score — Score is played by hand.
| Chars | Goals | Chars | Goals |
|---|---|---|---|
S0 | Score | MX | Money + Exp |
M0 | Money | MB | Money + Box |
X0 | Exp (X for eXp) | XB | Exp + Box |
B0 | Box | AA | Money + Exp + Box |
A code that says Score beside A, S or J still decodes, with a warning.
Each of the sixteen sets of boosts has a fixed character. A single boost is its own letter and all four is A. HP Extension with Power Jelly — the pair most runs take — is 2, and with Double XP as well 3; the other pairs and triples take the characters left, in order:
| Char | Boosts | Char | Boosts | Char | Boosts |
|---|---|---|---|---|---|
0 | none | 2 | HP Extension + Power Jelly | 3 | HP Extension + Power Jelly + Double XP |
H | HP Extension | 1 | HP Extension + Fast Start | 8 | HP Extension + Power Jelly + Fast Start |
P | Power Jelly Boost | 4 | HP Extension + Double XP | 9 | HP Extension + Fast Start + Double XP |
F | Fast Start | 5 | Power Jelly + Fast Start | B | Power Jelly + Fast Start + Double XP |
X | Double XP | 6 | Power Jelly + Double XP | A | all four |
7 | Fast Start + Double XP |
Cookie Relay is not here: a run that uses one says so by naming a relay cookie in the loadout section.
Two characters from each boost's name, or its number where it has one.
| Chars | Boost | Chars | Boost |
|---|---|---|---|
00 | none | GC | Gold Coin Magic |
2C | Double Coins | CO | -30% Collision Damage |
BS | +15% Score (bonus score) | PO | +20% HP from Potions |
HD | 15% HP Drain | MA | Magnetic Aura |
RV | Revive once with 80 HP | PL | 2 Pit Lifts |
CC | 70% Crush Chance | ||
17 | +17% Base Speed |
Any number of the seven can be on, so they are split into three groups with a slot each. A slot works like the boost slot: 0 for none of its group, a power's own letter when it is the only one of its group, a running digit for some but not all of a group, and A for the whole group — as all four boosts are A.
| Slot | Powers | Combinations |
|---|---|---|
| 8 | C Cheerleader, S Special Force, F Fairy | 1 C+S, 2 C+F, 3 S+F, A all three |
| 9 | K Cheesecake, W Sea Fairy (W for water) | A both |
| 10 | L Serenade of Love, E EXP Party | A both |
Fairy plus Sea Fairy is FW0; Cheerleader, Fairy and EXP Party is 20E; all seven is AAA.
Some episodes take less than a full run:
| Episode | Takes |
|---|---|
Special Episode 1 (C) | cookie, pet, treasures |
Special Episode 2 (T) | cookie, pet, treasures, and a tower floor |
Special Exp Episode (X) | cookie and pet |
None of the three takes a relay, boosts, a random boost, or cookie power+, so slots 5-10 read 0. Special Episode 2 spends slots 5-7 on the floor instead — 001 to 100, or 000 for any floor — and slots 8-10 stay 000. The mode and goal apply as they do anywhere else.
Encoding drops what the episode has no room for. Decoding a code that carries it anyway drops it too, with a warning, rather than refusing the code.
A full code is loadout-combi: the loadout section, a -, then the ten-character combi name exactly as above. The loadout section always opens with the format version, so a full code with no loadout is the version alone before the -: 1-MS0A000000. A bare ten-character code — copied back out of the game, with no - and no version — still decodes, read as the version this page writes.
The separators are picked for word-wise selection (double-click, or Option+Shift+Arrow). Editors and browsers stop a word at - but not at _ or ., so the loadout selects as one word and the combi name — the part you paste into the game — as another.
The loadout writes down the cookie, relay, pet, and treasure a build uses. The game already stores those four in its own combi field, so a loadout is never required — add one when you want a build to travel as text on its own, without a screenshot or the game alongside it.
| Tag | Group | Encoding |
|---|---|---|
1 | Version | The format version of the whole code; the ten combi characters carry none of their own. Always present, even with no group after it |
C | Cookie | 2-character catalog id, or __ for any cookie |
R | Relay | 2-character catalog id, the same catalog as cookie, or __ for any relay |
P | Pet | 2-character catalog id, or __ for any pet |
T | Treasures | An order flag (U any order, O exact order), then up to three slots of 3-character ids joined by .; alternatives within a slot are joined by _, and each id may be followed by a level — a treasure whose levels are not one run is listed once per run |
C, R, P, and T are each written at most once and, when present, always in that order. A group that has nothing to say is simply missing — there is no placeholder character for "unset."
"Any" is not that placeholder, and the difference is the point: a missing group is a build that never mentions the slot, while __ is one that says anything fits there. _ is outside the [0-9A-Z] alphabet ids are drawn from, so it can never collide with a catalog id however far the catalog grows. Only C, R, and P accept it — a treasure slot already holds a list of acceptable alternatives, which is a different idea, and TU___ is rejected like any other malformed id (there _ is the alternative separator, so it reads as empty ids).
An R__ counts as a relay for everything a named relay counts for: the build is semi-auto, and slot 1 is written S. Which cookie relays in is not what makes the run need a hand.
1-MS0A800FW0 no loadout
1C2L-MS0A800FW0 a cookie only
1C__R__P__-SM0A000000 any cookie, any relay, any pet
1C2LR0BP1ZTU09F_0G2.0G1-JM031RV000 cookie, relay, pet, two treasure slots, any order
1TU09F02_09F59_0G23.0G19-MS0A000000 slot 1: 09F at +0-2 or +5-9, or 0G2 at +3; slot 2: 0G1 at +9
Encoding always writes the canonical form: ids are sorted within a slot, and whole slots are sorted against each other whenever the order flag is U — a single slot is always written U, since there is nothing to order with only one slot. That is what keeps one build to exactly one code. Reading a code is more forgiving: a hand-written or otherwise non-canonical loadout still decodes correctly, it just re-encodes into the canonical form rather than back into what you typed.
Every id — cookie, relay, pet, or treasure — is a catalog id from assets/index.json, __ aside. An id is the entry's own number on cookierunhub.com in base 36 — treasure 50 is 01E, and its page is /en/encyclopedia/treasures/50. A blessed treasure has no number of its own there, so it takes its unblessed form's number plus 23,328, half the 3-character space: the blessed form of 01E is I1E. Because the site owns the numbering, a code you write today keeps naming the same cookie, pet, or treasure for as long as the site keeps its pages, and an entry the site stops listing stays in the catalog, marked retired, so a code carrying it still reads.
Within one slot, an id repeats only to list another run of its levels, and reading a code merges every copy of an id in a slot into one treasure — so TU09F_09F is simply 09F at +0, and TU09F03_09F25 is 09F at +0-5. The same id may also repeat across two different slots: that is how overlapping alternatives are written.
A treasure is upgraded from +0 to +9, and each treasure in a slot says which levels it is accepted at. The level follows its id directly — ids are always three characters, so it needs no separator:
| Written | Levels |
|---|---|
09F | +0, not upgraded |
09F5 | +5 |
09F58 | +5 to +8 |
09F09 | +0 to +9, any level |
09F9 | +9 |
09F02_09F59 | +0 to +2, and +5 to +9 |
09F_09F9 | +0 and +9 |
No digits means +0, which is also how every code written before levels existed reads. A treasure whose levels are not one run repeats its id once per run, lowest first. Encoding writes the shortest form: runs are merged, a one-level run is one digit, and +0 is nothing. A range that runs backwards, like 95, is rejected.
Semi-auto is an auto run that needs manual work each time. An auto build is semi-auto when any of these is true: Fast Start is on (slot 5), a random boost is selected (slots 6-7), the run jumps at the start (J in slot 1), or the loadout carries a relay cookie (the R group, R__ included) on an episode that takes one. The other three boosts do nothing to it — Double XP included, since it changes what a run pays out rather than what it asks of you.
The relay is the one reason that lives outside the ten characters: a relay cookie is swapped in by hand, so a run carrying one never plays itself through. Slot 1 is written from the whole build, so the ten characters you paste into the game say S when a relay is in front of them — while a bare combi code, having no loadout to read, answers for its own three flags alone.
Slot 1 stores A, S or J for readability, but those four reasons are the authority. encodeFull normalizes slot 1 so a generated code never contradicts itself. decodeFull accepts a hand-typed code that does contradict, keeps combi.mode as written, and returns a warning; isSemiAutoBuild always answers from the fields above.
AM03H00000 full auto, money (HP Extension only)
AAA3H00000 full auto, money + exp + box
AM03200AAA full auto, money (HP Extension + Power Jelly, every cookie power+)
SM031RV000 semi-auto (HP Extension + Fast Start, Revive)
JX03H00000 semi-auto (jump only)
AB03400000 full auto, box (HP Extension + Double XP)
AM0T042000 full auto on the tower, floor 42
import { encode, decode, isSemiAuto } from "./src/routes/combi-name/codec";
encode({
goals: ["score"],
mode: "manual",
episode: "any",
floor: null,
boosts: ["hpExtension", "powerJellyBoost", "fastStart"],
randomBoost: null,
cookiePowers: ["fairy", "seaFairy"],
action: "none",
});
// "MS0A800FW0"
const { combi, warnings } = decode("JX035RVC0E");
isSemiAuto(combi); // true
decode throws on a code it cannot read — wrong length, an unknown character in a slot, or a tower floor that is not 000-100. Everything else is soft and comes back in warnings: slot 1 disagreeing with the flag slots, Score on an auto run, or anything the episode has no room for. encode throws on a set of goals no code can say: Score beside another goal, or none at all.
Every page carries a top bar in place of a sidebar: the brand ("Cookie Run"), a tool menu naming the current page (or "All tools" on the home pane) that opens a list of everything in the registry, and the theme control. The site root is a short home pane; the combi builder itself lives at /combi-name/.
The code is the whole interface. It leads the page, updating as you pick a configuration below it, and it is also where a code goes in: press Edit and type or paste one, and every control below follows it as you type. Pasting a code anywhere on the page loads it without opening the editor at all. A half-typed code says how far along it is rather than complaining, and a code that contradicts itself loads with a warning rather than being refused.
The code panel stays in reach while you work: pinned to the top of the page, on a wide screen and a phone alike. Its heading reads New code, or Editing saved code while a saved entry is open, so you always know which you are working on; updating an entry keeps it open. It shows Edit, Save (or Update while a saved entry is open), New while an entry is open and its build is a code not already saved, and a ⋯ menu holding Show full code, Copy code, Copy link, Reset, and Cancel while an entry is open. The page's one notification banner floats at the bottom of the window, over the page, so a message is in view however far down the page you are and nothing moves when it comes or goes. Under the panel, in order: a note for the code in the panel with five optional run stats under it, and a summary of the whole build. The stats say what a run of the build brought home: Score, Money and Exp (a positive whole number, or a range like 12000-15000), Boxes (0 to 5, or a range like 2-4) and Time (seconds). A stat that does not read stops the save, is outlined in red — every one that does not read, not just the first — and the banner says why. The code panel's Copy link carries the note and stats in the boxes too, so a build can be sent before it is saved.
Every message the page has goes in that banner and nowhere else, as one of three kinds, each with its own colour and mark: info in green (a copy that worked, a code saved, updated, loaded or deleted, typing progress), warn in yellow (a code read with changes, an import that skipped lines, nothing to import or export) or error in red (a code that does not read, a clipboard or a store the browser refused). Info clears itself after a few seconds, except typing progress, which stays while the editor is open; a warning or an error stays until you dismiss it with ✕ or something replaces it. A message about the code on screen — its warnings, a paste, a copy — goes once the build changes, and an error about a code you were typing goes when you close the editor. A message of several lines folds to its title and a count, like Read with changes (2) ▾; tap it to read them. A link that reads with changes and carries a note shows both: the note offer is one more line under the warning. While the Saved or Help drawer is open the banner moves into it, under its header, since a drawer covers the page behind it.
The panel shows only the ten characters the game takes — what Copy code copies — even when the code carries a loadout; Show full code in the menu swaps it to the whole code (and Copy code with it) until you switch back, and the choice is remembered in this browser: the loadout is the summary's to show, and it still rides in the link, in saved codes, and in the editor Edit opens, which holds the whole code. Each field of those ten characters is drawn as its own run. Hover one and it names its slot and what it currently says; click it and the page switches to the tab that holds the control and jumps to it, the same jump a line of the summary makes. A run for a character nothing on the page owns — the full code's version character, a reserved slot — or whose tab the episode has no room for is plain text instead, its tooltip still there but nothing behind it to click. That is why the slot tables, and the tip about clicking the code, live in the Help drawer behind the top bar's ? (Help) button rather than folded away at the bottom of the page — they confirm the format rather than being where you look things up.
Under the note sits the summary: a read-only digest of the build, one row per tab and in the tabs' own order — Run, Cookies, Treasures, Boosts, Random boost, Power+ — each with its pictures and words — cookies, treasures, boosts and Power+ as pictures, their names a click away; an evolved or blessed treasure wears an E or B and a ring in its colour, as in the treasure picker, since both forms share one picture — and each a way to the control behind it. Pictures sit in equal boxes, like a grid; click a row's pictures to show or hide that row's names (on the Run line, the same click shows why a run is semi-auto), and use the › at the right end of a line to switch to its tab and focus the control. Run always shows; every other row only when it has something to say, with a muted hint once nothing else has been picked. On a phone the summary opens folded to one line — the mode, the goal, the episode, the faces and the treasure pictures, and a boost count — and expands on tap.
Below the summary, a row of tabs replaces the old board: Main, Cookies, Treasures, and Boosts, each with a badge counting what it holds. A tab the episode has no room for — Treasures on the Special Exp Episode, Boosts on any of the three special episodes — is disabled and says why in its title, and the page shows Main in its place; picking an episode that has room for the stored tab brings it back.
Main holds mode and goal chip rows, with the auto/semi-auto verdict sentence under them, the episode, the tower's floor, and the starting action. Goals are a set: click a goal to add it and again to take it off, though the last one stays on. Score stands alone — picking it turns the others off, and picking another turns it off — so a manual run aims for Score or for 1-3 of Money, Exp, and Box, and an auto run for 1-3 of Money, Exp, and Box; switching to auto drops Score and falls to Money. There is no Semi-auto chip — pick Auto, and the build turns semi-auto by itself the moment Fast Start, a random boost, a jump action or a relay cookie is in play, which is what the format says anyway; the chip itself then reads Semi-auto, and the verdict and the summary's Run row say so too. The episode is an inline grid of its twelve cards, short enough to show whole without a filter box; its own none is Any. A field the episode has no room for keeps its heading and says so in place of its control, and switching back brings back what it held. Action opens with a none of its own, and clicking the chip you already picked goes back to it.
Cookies holds three role cards — Cookie, Relay, Pet — each showing the face and name of what it holds, or None or Any; the Relay card reads "No relay here" and disables itself where the episode takes none. Picking a card decides which inline grid underneath it writes that role, with a Clear button once the role holds something. Each grid is a filterable, uncapped list of faces — cookies for Cookie and Relay, pets for Pet — opening with two answers before the catalog: Any, the slot the build says anything fits, and the grid's own None, the slot the build never mentions.
Treasures holds the order chips, then the three treasure slots, unchanged from the old board: a slot's name over its alternatives, one to a line, each with a button that drops just that one; the name opens a picker dialog over the page, with a level strip per pick, where picks are a draft until Done and Escape throws the draft away whole. The picker offers every treasure the site lists.
Boosts holds the boost cards, random boost chips — None first, then the eleven — and the cookie power+ cards, which wear the portrait of the cookie or pet each power belongs to.
Your code lives in the address bar, so a build is a link you can send, and it is remembered between visits — a link wins over the remembered one, and Reset goes back to an empty code. Pasting a link into the address bar of a tab that is already open works too: the page notices the new code rather than overwriting it. Copy code in the panel's menu takes the code as the panel shows it, Copy link takes the whole address.
Saved codes and the slot-format help each open as a drawer from a button in the top bar, rather than sitting at the bottom of the page. Saved, with a count beside it, keeps builds you want to come back to, each with a note and run stats of its own, in this browser; a row shows its stats on one line under the code. Each row shows Load, which puts it on the code panel, closes the drawer, and fills the note and stats with its own, and a ⋯ menu holding the rest. In the note, Update writes back whatever the panel and the note then say — the code, the note, or both — while New saves it as an entry of its own and leaves the original alone; Cancel or Reset lets go of the entry. Copy link hands over one entry as a link that carries its note and stats (#CODE?note=…&money=12000-15000&time=245, the note as base64url so the link is one unbroken run of letters, digits, - and _, the stats as typed), and Share, shown where the browser has a share sheet, sends the same link through it; either way whoever opens it finds the note and stats waiting in their own boxes, one click from keeping it. Import and export, folded under the list, moves the whole list as plain text — each code on its own line, its stats under it one per line (money: 12000-15000), then its note, every note line starting with > — which reads fine pasted into a chat. Import takes that text, a file of it, bare codes or shared links, adds only the codes you have not saved yet, and says which lines it could not read.
The top bar carries the light/dark control that defaults to following your system. Everything runs in the browser — no network calls, no analytics.
The build produces one index.html per page, the JavaScript and CSS they share as chunks beside them, and the cookie, pet, and treasure icons under assets/. Everything is linked relatively, so dist/ carries no assumption about the base path it is served from — but it does have to be served: module scripts over a file:// URL are blocked by the browser. bun run preview is the local way to open it.
bun install
bun run dev # dev server on :3000; / is the home pane, /combi-name/ is the combi tool
bun run test # 456 tests, including an exhaustive round-trip over all 10,621,776 combis
bun run check # typecheck and Biome, in one pass
bun run build # writes dist/index.html, dist/combi-name/index.html, their chunks, and dist/assets/
bun run preview # serves the built dist/ on :4000; build first
bun run verify:assets # asks cookierunhub.com whether assets/index.json is still complete
The exhaustive test asserts that encoding produces exactly 5,310,888 distinct codes — 10,621,776 inputs collapse to that many because the auto/semi-auto character is derived rather than free, and a manual run drops its action. DOM tests run against the combi page and against every component under happy-dom, registered by tests/happydom.ts and preloaded via bunfig.toml.
| Path | Role |
|---|---|
src/routes/ | One directory per page — markup, stylesheet, page script, and that page's own logic. src/routes/index.* is the home pane. |
src/routes/combi-name/codec.ts | Slot tables, episode limits, encode, decode, normalize, isSemiAuto. No DOM, no dependencies. |
src/routes/combi-name/labels.ts | Display names for every enum value. |
src/routes/combi-name/describe.ts | Turns a combi into rows and an auto/semi-auto verdict. |
src/routes/combi-name/catalog.ts | Resolves cookie, pet, and treasure ids against assets/index.json. |
src/routes/combi-name/loadout.ts | The loadout section's grammar: encodeLoadout, decodeLoadout. |
src/routes/combi-name/full-code.ts | Joins a loadout and a combi into loadout-combi, or just the bare combi when there is no loadout. |
src/routes/combi-name/hints.ts | What each character of a code means, one entry per character, for the tooltips on the built code. |
src/routes/combi-name/state.ts | The code in the address bar and in localStorage: what a link carries and what a return visit restores. |
src/routes/combi-name/saved.ts | The saved list: save, update and remove entries, and the plain-text form export writes and import reads. |
src/components/ | Every custom element the pages declare, the top bar and the light/dark control among them. |
src/lib/ | What more than one route needs: the tool registry, and the link writer that keeps every href relative. |
scripts/ | The two asset programs and their helpers: fetch-assets.ts syncs from cookierunhub.com, verify-assets.ts asks the site whether the committed index is still complete. Every other package script is the command itself, in package.json. |
tests/ | Test configuration only; every test sits beside the code it covers. |
The ALL_* arrays and the label tables derive from the character tables, and a test asserts every value has a label, so adding a goal or episode cannot silently ship a page with a missing option.
The site is a Cloudflare Worker serving static assets. wrangler.jsonc points it at dist/ and has wrangler run bun run build itself, so the deploy workflows do not build beforehand.
.github/workflows/main.yml runs the tests, both checks, and the build. deploy-preview.yml uploads a preview version for every pull request; deploy-production.yml deploys on every push to main. Both need CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID in repository secrets.
Bun's version is pinned by the packageManager field in package.json, which oven-sh/setup-bun reads automatically. Keep it in sync with mise.toml when upgrading.