Ctrl K
ComunidadGuías…

CHANGELOG.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Changelog

## Unreleased

- Deploy and watch a hosted app safely. `tools/deploy_host.sh` deploys only a commit with green gate checks that contains the running commit, unless `--rollback-to` is given, and never one with an older data schema than the live data. The image carries its schema as a label. It tests its cold backup with `gzip -t`, rolls back to the old image when the new one fails its health or smoke check, and keeps the 5 newest backups and their images. The alert watch hands over one "app down" alert when the host, the container or the alerts file cannot be read, and waits while a deploy holds its lock. The nightly watch runs the private-save tests at the deployed commit and checks the app with the smoke check, which works under accounts. Its systemd units live in `deploy/systemd`, run from the watch's own clone, post a failed run to ntfy and install with `tools/install_watch.sh`. The watchdog also warns when the data folder has under 10 GB free.
- Rerun the failed jobs of a failed push run on `main` once, so one flaky job does not leave a commit without green checks. `tools/flake_rate.py` reports how many runs passed only on that rerun.
- Name development builds from `main` as such. `main` is now 0.7.0.dev0, and `tools/release_version.py` accepts an `X.Y.Z.devN` version. It moves only the package version, so the installers and Compose files keep installing the published release.
- Require green checks before a change lands on `main` or a `feature/` branch. CI and the Python install workflow each end in one gate job, `ci gate` and `install gate`, that passes only when every other job passed. The branch ruleset requires both, so `feature/` branches now take changes through a pull request. Pushes to `feature/` branches run both workflows, so each commit there has its own evidence, and a documentation-only pull request runs the install checks too. The release gate requires both gates.
- Stop two linked games trading the same species back and forth. Each copy scored a small gain, and the receiver's PC released it at the next visit. Before an automatic trade, each receiver now rates the incoming Pokémon with its own PC rules, and a trade one of them would release is skipped. A Pokémon that completes a Pokédex entry is always sent. After a trade or a refusal, the same two games leave that species pair alone for 6 hours.
- Send a Gold, Silver or Crystal Pokémon to heal once its strong attacks run out, even when a weak one has PP left. A level 84 Typhlosion carried Kanto with Flamethrower and Strength, and when both were spent, 30 PP of Cut kept it from the Pokémon Center. It met Misty and Brock with Cut and Swift alone, fainted, and the weak rest of the party could not finish the battle. The heal walk now counts only attacks that hit at least half as hard as the Pokémon's strongest.

- Skip a Gold, Silver or Crystal event return or gift the PC would release. Gold caught the returning Sudowoodo and released it 11 seconds later, and took the Eevee gift only to release it. A due return or gift the PC would rate as a spare now waits for the next walking milestone, and the journal says so once. The loop guard counts a caught return or completed gift as progress only once it has stayed in the PC for a check.

- Stop League reward gifts from looping through the PC. Since PC values, a reward copy counts as a spare, so a gift that went into a box was released at the next PC visit, which made room for the next gift. A Silver run spent hours receiving and releasing Lv 5 starters. A gift the PC would release, or a copy short of the best while the boxes are nearly full, is now settled as skipped, with no gift and no save. Shiny Gen II gifts are always sent. The check rates the gift as the League reward it is. Until it was counted delivered, it rated as a traded copy, the best of its species, so most gifts were still sent. A shiny Red, Blue or Yellow gift is now always sent too. The staged gift's mark goes straight to the rating, so the PC tab never sees it.

- Let the loop guard catch Red, Blue and Yellow gift loops. A Gen I gift names the species in capitals and a release does not, so the two never paired. A reload that replays the same maps, trainers and levels no longer counts as progress, so the same save cannot be reloaded forever. The guard reads only new journal entries and is safe to ask from the web page and the game at once.

- Stop a waiting Gold, Silver or Crystal run from showing as stalled while the loop guard is tripped.

- Stop the overnight watch from marking main-page alerts as seen. Without an alert command, `tools/alert_watch.py` now only prints them, so the timer still hands each one over.

- Ask for help when a run loops. The same Pokémon received and released 6 times, or the same save reloaded 6 times, since the last real progress (a badge, catch, evolution, League win, trainer, level or new map) now shows "The run is caught in a loop" on the main page, and the run stops gifts and reloads until it makes progress.

- Back off the whole game after a trade times out on the way to the Cable Club, as a full PC already does. A stuck run used to be picked for trade after trade, once per Pokémon it offered.

- Repair a Red, Blue or Yellow party nickname that holds a text command byte, when a save loads and when a trade ends. A traded name with a damaged ending drew differently from its bytes, so the party menu never matched and the run could not heal, use Surf or switch.

- Write the problems the main page shows to `watchdog-problems.json` in the data directory, so a host can watch them. `tools/alert_watch.sh` runs a command once per new problem.

- Stop Red, Blue and Yellow runs from reloading forever when reloads do not help. After 12 reloads in a row without progress, the watchdog gives up the stuck collection project for a while, journals "Gave up on" that goal and lets the next goal run, as Gold, Silver and Crystal already do. A story goal has no project to give up, so the run stops reloading, says so once in the log and shows as stalled.

- Give every stored Pokémon a PC value and release the cheapest first, in all six games. A Pokémon's popup on the PC page shows its value, what it is made of and whether it is a spare, kept for a plan or never released. The next five to go carry a mark on their cards. A legendary or one-time event Pokémon, such as a second Mew or Ho-Oh, counts 200, as much as a trained Lv 100 spare, and still goes before any shiny. Ordinary gifts count 80. Keep-locked Pokémon, the best or only copy of a species, the party and eggs are never released automatically. **Release at next PC visit** puts a Pokémon first in the queue, and an only copy asks for its name first. The **Release order** select can favor shiny or DV copies. Visits take the cheapest box by box, so a visit can run longer but costs less per freed slot. The journal names the value of each released Pokémon, and a PC with nothing left to release says so once on the PC page and in the journal. The API is `POST /api/pc/release` and `POST /api/pc/favor`.

- Stop Gold, Silver and Crystal runs from walking to a PC forever for room that does not exist. With a full party and every box full of Pokémon a release may not take, such as League rewards from other trainers, a gift sent the run to a PC to deposit a partner. The PC had no room, so the run turned it off and walked back, through every reload, for days. Gifts and the Game Corner prize partner now wait until a slot is free. The watchdog also escalates now: after 12 reloads that did not help, it blocks the stuck collection goal for a while, journals "Gave up on" that goal, and lets the next goal run.

- Say why an adventure could not start when none of its autosaves restores. The error now names each reason a save was refused, how many saves it covered and the first one, instead of only how many were tried. A worker that fails before it is ready now sends that reason to the Library, which used to show only "Worker exited before becoming ready" ([#321](https://github.com/afk-sapien/PokeSim/issues/321)).

- Let a manager set the next activity from the game page. The **Next activity** picker lists the goals the planner can start now, from its own list. The planner runs the chosen goal once, after upkeep such as healing, and then goes back to its own order. **Cancel** drops it. A goal that cannot run now is refused with the reason. A load, a restart or a stuck run clears the pick, and a stuck run writes "Gave up on" the goal to the journal. The API is `GET /api/goals` and the `pin_goal` and `unpin_goal` controls.

- Add a Nicknames switch to each adventure's settings, in all six games. Off, the bot answers NO at every nickname prompt, so caught, gift and reward Pokémon keep their species names. Player and rival naming is unchanged. The switch applies at once, including while the adventure runs, through the new `PATCH /api/v1/adventures/{aid}/play` route. A saved nickname pool that leaves no names now also means no nicknames, where before the Library refused to save it. A Library that never saved a pool still uses the built-in names.

- Add a Play style choice to each adventure's settings, in all six games: Balanced, Story first or Collector. Balanced is the default and plays as before. Story first ranks filler side projects below the planned story and Pokédex goals. Collector ranks better DV copy and repeat catch hunts with new Pokédex entries, so they compete on value per frame instead of waiting behind training and races. Story and upkeep goals never move. The choice applies at once, including while the adventure runs, through the `PATCH /api/v1/adventures/{aid}/play` route. An unknown style is refused.

- Stop Red, Blue and Yellow DV hunts from catching Pokémon only to release them. A hunt took every species on its map, so a postgame Yellow hunting Tauros caught about 1500 owned Nidoran, Exeggcute and Cubone a day in the Safari Zone and released nearly all of them at the next Pokémon Center. A hunt now reads the wild Pokémon's DVs and catches it only when they beat every copy already held, for the target and for other species alike. Missing and shiny Pokémon are still always caught.

- Heal before a boss battle when the party is not ready, in all six games. Before a gym leader, an Elite Four member, the Champion, the Gen I rival in the League or Red, a Pokémon under half its HP, or under half the PP of the attacks it fights with, sends the party to a Pokémon Center first. Each attack's PP counts by how hard it hits, so a spent Flamethrower is not hidden by a full Strength. One approach takes at most three such trips. With no Center in reach, or the trips used, the party goes in as it stands and the journal says "Went in unready".

- Keep the image that can restore each host backup, and keep fixes on `main` from sitting outside production. `tools/deploy_host.sh` named each backup after the commit it deployed and kept that image, but the data was written by the image before it, so a backup could outlive the only image that could open it. Each backup now has a json file naming its writer image, and that image is kept. The script also lists the `main` commits a candidate lacks and refuses when one is over a day old, unless `--behind-main` is passed.

- Hold every deploy to a live soak. `tools/live_soak.py` plays a candidate and the deployed commit for two game hours each on copies of the live adventures and of post-game saves with a full PC and a League gift backlog, and fails the candidate when it releases, reloads, repeats itself or grows its journal faster than the deployed commit, makes less progress, or keeps catching for a goal without a better copy. `tools/deploy_host.sh` now refuses a commit, a rollback included, without a passing soak report. Red, Blue and Yellow League gifts are now spaced in game time, so a fast run gets the same gift rate per game hour as a slow one. The loop guard keeps its reload counts in the adventure, so a worker restart no longer forgets a save it keeps reloading, and it now pairs gifts and releases of Nidoran♀, Nidoran♂ and Mr. Mime. Stage ladder gate reports record their attempt.

- Stop DV hunts from catching a Pokémon and releasing it at the next Pokémon Center, in all six games. A hunt kept a copy whose DVs beat the best one held, but the PC valued copies by level and training, so the new Lv 5 copy was often the first to go. Copies are now judged by one rule in both places. A copy scores as its best final form would fight at Lv 100 with full stat experience, and Attack counts fully when its best physical attack beats its best special one by a quarter, not at all when the special one wins by a quarter, and half otherwise. Attacks are rated by power, accuracy and the same-type bonus, from the family's level-up moves plus the one-time TMs and the HMs the bot teaches that the form can learn, Explosion and Self-Destruct left out. Its rarity is the share of all DV combinations that score as well. A hunt catches a copy only when it is at least twice as rare as the rarest copy held, and still always catches missing and shiny Pokémon. With the boxes nearly full, a catch, a gift or a trade is also skipped when the PC visit it brings would release it or a copy rarer than it, of any species. The Gold, Silver and Crystal post-game hunt for better DVs now picks, catches and ends by this rarity instead of the DV total, and Red, Blue and Yellow value their hunts, protect rare finds from automatic trades and judge a trade's DV gain by it too. The PC releases the most common copies first, and level no longer adds to a copy's value. The party, trained Pokémon, the rarest copy, Keep-locked Pokémon, eggs and plan roles stay. A Red, Blue and Yellow PC visit now plans for every owner release request, as Gold, Silver and Crystal do. The live soak now fails a candidate that releases a new catch at its first PC visit, or releases a copy rarer than every newer copy that pushed it out. When a Red, Blue or Yellow cartridge is set but its TMs cannot be read, the PC now rates and releases nothing and the main page says why, instead of rating with the HMs alone. The live soak report now shows how many Pokémon each adventure releases at its first PC visit, and how many it catches and releases over the whole run.
- Let a Red, Blue or Yellow party of field-move holders make room for a trade. A postgame Yellow party held its strongest Pokémon, Pikachu and four Pokémon that were each the only one with Cut, Strength, Surf or Fly, so every trade that needed a boxed Pokémon failed with "No safe unprotected reserve". When no one else may go, the trade now stores the only holder of Cut, then Strength, then Surf, since the game withdraws a partner with that move from the PC when it needs one. The only holder of Fly or Flash still stays. Once the trade is released, the same PC visit deposits the received Pokémon and puts the stored holder back in the party, unless the received Pokémon is locked in the party.
- Let a Gold, Silver or Crystal party of field-move holders make room for a trade the same way. When no one else may go, the trade stores the only holder of Whirlpool, then Surf, then Waterfall, the moves the game withdraws a PC partner for. The only holder of Cut, Strength, Fly or Flash stays.
- Give each leg of a boss approach its own heal trips, in all six games. Red spent its three trips in Victory Road and went into Lorelei unready in 10 of about 25 League entries over 2 hours, though the Indigo Plateau Center is on the way. A leg now runs from the last Pokémon Center the party stepped into, so a new Center brings three fresh trips, while trips back to the same Center still stop at three. The journal now writes quiet "Healed before" and "PP heal at" rows that stay off the feed.
- Keep CI green through a GitHub release-asset outage. The pyboy-rs and pokecore wheels are release assets, and uv checked every one of those links on each sync, so a run failed even with every wheel in its cache. CI now keeps a uv cache per job, keyed on the pyboy-rs and pokecore versions and the lock file, and syncs and exports offline from it first, and goes online with 10 retries only when the cache misses. Later steps skip the sync. The Docker build retries those downloads 10 times.
- Let the live soak survive a failed download. When building a commit's environment fails on the network, as on a GitHub 504, it now tries once more offline from uv's cache and says so in its log. The lock still checks every wheel's hash.
- List each goal once in the **Next activity** picker, in all six games. A post-game save listed about 1000 goals, most of them "Find Pidgey" once for every route, water and hunt kind. Each goal now names one thing to do, such as "Catch Ditto (missing entry)", "Better Pidgey (DV hunt)", "Train Kabutops to 60" or "Get Articuno", and setting it runs the best ranked way to do it. The picker shows the best 30, and its search box finds the rest by name.
- Stop catching Pokémon the PC lets go at its next visit, in all six games. Red caught a higher-level Tentacool with ordinary DVs over a better one it held, and Yellow a Nidorina, because a catch of an owned species still counted a higher level or a new type for the team. Now every catch of a species already owned, on the way, in the Safari Zone, on a hunt or for a returning legendary, is made only when the PC would keep it. Missing Pokémon, shinies and field-move partners are still always caught. The PC now releases only spare stored copies, never a Pokémon deposited from the party at the same visit, so Red no longer released its Lv 43 Weezing while keeping four rarer Lv 5 ones. The live soak now fails a candidate that catches a Pokémon it releases at the next visit, or releases a species' best or only copy, a Keep-locked one or a team member.
- Stop a returned legendary from coming back again and again once the PC would not keep it, in all six games. The battle refused the catch, but the return stayed open, so the plan sent the bot back and the retry timer reopened the encounter. A refused return now closes until the next walking milestone, as a caught one does.
- Stop Gold, Silver and Crystal from counting a spare as a team member when it joins the party only to give up its held item, and check every Gen II release against the PC values before it starts. A soak of Crystal withdrew five boxed spares, Kabutops, Kingler, Shellder, Goldeen and Seadra, to take their items, then released them. The PC visit counted each one as a team member for the rest of the visit, and the item release skipped the PC values. A spare the item route withdraws only to take its item is now no team member at that visit. The trainee, the League partner and any Pokémon with a role stay team members whatever their box history. Every Gen II release, from the item route, a release visit, a team change, a training partner, a trade or a Link prep, now asks the same release rule before its first press and waits when the rule refuses. The live soak judges a withdrawn spare the same way. Its obtains limit now leaves out catches kept as their species' best copy, so a full box no longer fails a long soak, and the report shows how many there were. The report also gives each catch's rarity and the rarest copy of its species held before it.
- Warn when a game goes too long without real progress, in all six games. Every few minutes the watchdog reads each running adventure's progress table and journal. In the story, a badge, a new area, a new Pokédex entry or a League win is progress, and a game is stalled after twice the slowest gap the original six games took at the same badge count, never under 3 hours. In the postgame, a League win, any Pokédex change or a level up is progress, so a trainee in Silver Cave keeps a game going, and a game is stalled after 24 hours. Experience, repeat catches and other journal entries never count, and time stopped, paused, in manual play or in a trade is left out. A stall shows on the main page and sends one ntfy alert, and the alert watch hands it over too.
- Judge each live soak catch by its own rarity. A catch now improves the PC when it is a new Pokédex entry or at least twice as rare as the rarest copy of its species held when it arrived, as the catch rule keeps it, and counts as kept while the PC holds it or a rarer copy at the end. Red's second Seel, 1 in 4 against a 1 in 2 new entry, was scored as not kept because the first catch took the credit.
- Keep the overnight watch's Gen II quality hunt check working with accounts on. It read the app's pages, so every night since accounts it got a login error and then a traceback. It now reads each adventure's files inside the container, as the alert watch does, so it needs no login in any auth mode. Empty or broken input now fails with a plain line.
- Train before another try at a boss that won, in all six games, and warn at once when a game keeps getting stuck in one place. Gold lost to Falkner again and again with a Lv 12 Chikorita and five Pokémon under Lv 6. Once Chikorita fainted, a Metapod that knows only Harden was left, Gold called the battle one that could not end, and the reload went back into it. Now a Pokémon with no damaging move, or an egg, never counts toward a readiness bar or level cap. Falkner waits for a Lv 14 fighter. A loss to a gym leader, the Elite Four, the Champion or Red raises the bar to 2 above the best fighter level that lost, up to 10 above the boss's ace, and the bar is kept across reloads. The Elite Four rooms share one bar. In Gold, Silver and Crystal a battle counts as one that cannot end only when the last Pokémon standing can heal itself, as in Red, Blue and Yellow, so a lost battle plays out to a black out. The watchdog now raises a problem as soon as a game logs 2 stall entries at one place within an hour, in all six games, where it used to wait at least 3 hours. It also raises one when every box is full and nothing has been caught for 24 hours.
- `replay_audit.py run --reseed-goals` now keys its goal seeds by `--seed` as well as the save, so two seeds on one save play different rolls. Before, every seed replayed the same game. Seed 7, the default, keeps its old seeds.
- Hold the live soak's release counts to the deployed commit on the same copy. A release check, such as a copy rarer than the newer one that pushed it out, now fails only when the candidate does it more often than the deployed commit did in the same soak, or when the deployed run failed. A problem the deployed build already had no longer blocks a deploy.
- Send Gold, Silver and Crystal training and hunting walks only to encounter tiles they can reach on a map with wild Pokémon in the cartridge's table. A walk aimed at Victory Road floor outside its walls, found no route and stood in Mr. Pokémon's House while each trainee gained nothing. A training stint that gains no experience, or ends in a reload before it gains any, now marks its map as failed, so the next trainee trains somewhere else. In all six games, a run that blacks out to a gym leader or in the League no longer counts its experience, levels and trainer wins as progress, so the stall alert and the loop guard now fire on a team that keeps losing.
- Count a stall reload inside a boss battle as a loss to that boss, in all six games. Gold at Azalea Gym had only two Metapod with Harden left after Bayleef fainted. The battle ran long, the guard reloaded it, and with no loss noted the run went straight back into the same fight. Now any reload during a trainer battle in a boss's room or the League raises that boss's bar, so the team trains first. The trainer, not the room, now names a boss, so rival battles, Giovanni and the Team Rocket executives count too. Crystal at Burned Tower lost its Quilava to the rival and was left with a Togepi that knew only Growl and Charm. A reload there now raises the bar for the story goal under way, and the team trains on the route before the next gym.
- Keep the last free PC slot for a better copy, in all six games. Silver filled all 14 boxes with only copies, so no release could free a slot and its quality hunts never started. Now the last slot, counting free party places, takes only a copy the PC rule keeps as a strictly better copy of a species it holds. The release goal runs before anything else whenever slots are wanted, so the replaced copy goes at the next PC visit and the slot is free again. A missing Pokédex entry may take the last slot only when a spare can be released after it. Otherwise the game leaves the encounter and asks for help with Boxes full.
- Stop the live soak from flagging a release as pushed out by a newer copy that no release may take. Yellow released a Grimer while holding a rarer gift Mew, the only copy of a new entry. The judge now compares only against newer copies that are not their species' rarest or only copy, not in the party and not set to Keep.
- Carry a League kit and heal between rooms from the bag, in all six games. Gold and Crystal reached Lance with the ace's strong attacks spent and no way to heal. At the Indigo Plateau mart the party now buys restores for five rooms and two Revives, the cheapest strong restore first, and keeps half its money for another run. It buys the same kit between tries. Between rooms it revives a fainted fighter, gives a fighter under the boss check's bar the smallest restore that lifts it past, and uses any Ether or Elixir in the bag on its spent strong attacks. A bag that can heal the party counts as a heal for the boss check, so no trip is spent. Over Gold and Crystal on two seeds, each run still reached the Hall of Fame, in 31 League tries in all against 34 without the kit.
- Release the lowest-value spare first at a PC visit, of any species and in any box, in all six games. A visit counted scores within 50 points as equal and then took the open box first, to save a box change. Yellow released a Grimer at 1 in 1.4 while a commoner copy at 1 in 1.3 stayed in another box, and a Bellsprout at 1 in 1.6 while a spare Bulbasaur at 1 in 1.4 stayed. Now only an exact score tie chooses by box. A trade's, a partner's or trade demand's points still keep a commoner copy. The live soak now judges a release by the same PC score, so it fails only when a released copy outscores a copy kept.
- Take a walked step through a cut tree again only while a partner knows Cut, in Red, Blue and Yellow. Trees grow back, but the walk kept every step it had seen and trusted it later. Yellow on its way to Celadon paced Route 2 for two game hours between two trees it had cut before, after no partner knew Cut. Now it takes the way through Viridian Forest.
- Run every command under `tools/load_gate.sh` at nice 10 or lower priority. Agents had to add `nice -n 10` by hand, and a full suite once ran at full priority. A command already at a lower priority keeps it.
- Accept a passing live soak for a commit with the same git tree when deploying. A merge commit that changed nothing from its soaked head needed a second 10 minute soak. The tree is read from git, never from the report, so a commit with any change still needs its own soak.
- Train before each Johto gym after Falkner and before the League in Gold, Silver and Crystal until the team matches up, as Red, Blue and Yellow do. Gold went into Azalea Gym with a Lv 13 Cyndaquil and a Metapod that knows only Harden, and blacked out to Bugsy's Scyther four times. Each boss's ace now comes from the cartridge's trainer tables, so a randomized run meets its own. The score is the one Red, Blue and Yellow use, and Gen II reads both sides' damage from the battle's own estimate. Before Bugsy and each later Johto gym the team trains on the gym's route while its best score against the ace is under 75 and its best fighter is under 10 levels above the ace. Before the League it trains on Victory Road while a room scores under 60 and the best fighter is under the top ace's level, Lv 50 on a clean cartridge. Without the trainer tables the old level bars stand. In all six games an HM now goes to another member before the ace, so the ace keeps its four attacks.
- Count no release in the live soak for a copy missing at one poll and back at a later one. A poll can read the party and the PC while a copy moves between them, and Soak red once failed for a gift Eevee the game never released.
- End the turn when a walk finds no route, in all six games, and record a failed attempt on its goal with the map and the target tile. Gold, Silver and Crystal explored for 60 turns with no route and then failed a task, and every third failure reloaded the save. The reload replayed the same missing route after a full stall timeout. Red, Blue and Yellow explored and then ran the stall recovery. Now no reload and no stall event follow. The goal picker passes the target over for a while, and the wait doubles each time the same target fails again. Gold, Silver and Crystal also send a person's errand, a contest search with no grass in reach and a roaming beast's next route only to tiles the map regions join.
- Run the overnight watch's private-save tests and Gen II quality hunt check on the local dev instance, and only the health and smoke checks on the hosted app. The quality hunt check failed with HTTP 401 on a hosted app that uses accounts. The watch now reads the dev instance's commit, Python and data folder from its systemd unit, and tests origin/main when it is not running. The main-page alerts stay with the alert timer.
- Test that Red, Blue and Yellow do the same thing as Gold, Silver and Crystal in five scripted situations: a gift with a full PC, a stall, a marathon checkpoint, a duplicate catch and a DV hunt. Gifts and hunts already match. The stall ladders differ, and neither generation writes a progress row for a checkpoint or a catch yet. Each gap is marked with the goal system v2 change that fixes it.
- Keep a quiet log of progress in all six games: each catch, received Pokémon, release, marathon checkpoint and finished goal, with the game time it happened. Only a checkpoint counts as progress, so catching the same Pokémon again or trading one in counts as nothing. Nothing acts on the log yet, so a stall is still judged the way it was.
- Add `tools/replay_progress.py`, which replays a copy of each adventure's journal through today's stall checks and the new progress model side by side, and reports the stalls each one caught, missed and raised in error. The first run on two weeks of play did not meet the bar, so stalls are still judged the old way.
- Keep a lasting record of each stall bundle, help request and restart in the adventure's database, for the progress replay. The row for a stall bundle stays after its folder is pruned, and a new game keeps every row. A restart says whether the owner, the supervisor or the app's start caused it. Nothing reads the rows during play.
- Tidy the play page. What happens after someone plays by hand is now chosen in the adventure's Settings, and the box under the screen shows only while someone holds control or waits for it. Choosing the next goal is one row across the foot of the plan, and with nothing to choose it shows only the reason. The empty party no longer stretches down the page, and Next says Finish the plan first instead of Still on this one.
- Polish the play page row by row. Choose next labels each control Goal, Pokémon and Stop when, and a goal that targets a species offers one search box that lists only the species it can reach. The whole row shares one height and one face. The screen shows one play status, without a Live tag or a Running note in the top bar while the page is connected. The speed select says Speed beside it, and the view link key reads View link.
- Add accounts. With `AUTH=accounts` everyone logs in with a password, an OpenID Connect provider or a trusted proxy header. Admins manage the Library and members see only their own adventures and the ones shared with them. The first admin comes from a one-time setup code in the log or from `POKESIM_ADMIN_USER` and `POKESIM_ADMIN_PASSWORD`, and owns every earlier adventure. Admins invite people with one-time links, owners let other people watch or make expiring watch links, trades run only between adventures one person owns, and `pokesim admin reset-password` recovers a locked-out account. With `AUTH` unset a Library stays open until it uses accounts, and an open Library that listens on more than its own machine says once that anyone who reaches it controls PokeSim. `compose.yaml` and `compose.quickstart.yaml` pass `AUTH`, `AUTH_TRUSTED_PROXIES` and the first admin pair from `.env`, and the store templates offer `AUTH`. See [Users and sharing](docs/users-and-sharing.md) and [Authentication](docs/authentication.md).
- Add trade offers between people. An owner switches on Open to offers, and people the adventure is shared with send offers from Make a trade, with or without a Pokémon they ask for. Only the owner accepts or declines, a changed Pokémon asks for a second confirm, and unanswered offers expire after 24 hours. Auto trading with other people lets automatic trading pair two owners' adventures when both switch it on. See [Trade offers](docs/trading.md#trade-offers).
- Add running limits. An admin sets a server-wide limit on running adventures and an optional per-member limit in Settings. A start over a limit is refused with the numbers, and running adventures are never stopped. Settings suggests 2 per member on an ARM machine with 4 GB of memory or less, otherwise 4. See [Running limits](docs/users-and-sharing.md#running-limits).
- Add giving an adventure away and deleting a user. An owner gives an adventure to another person from Sharing. An admin deletes a user after choosing, for each adventure they own, a new owner or Archive, so no adventure is deleted with the account. Either way the old owner's open offers, queued trades and control lease end. See [Delete a user](docs/users-and-sharing.md#delete-a-user).
- Keep one Library cartridge shelf that only admins manage. Members get no upload or remove controls and no Game cartridges panel. Everyone who can create adventures sees every Library cartridge and can start an adventure from it. Removing a cartridge is refused while any adventure, of anyone, plays it, and deleting a user leaves every cartridge. The per-user shelves of earlier builds of this branch go on the first start, and every ROM and file stays. See [Cartridges](docs/users-and-sharing.md#cartridges).
- Add `pokesim smoke`, a check of a running server through its HTTP API with throwaway users it deletes again, and an API reference at `/docs` for admins. See [API reference and smoke check](docs/authentication.md#api-reference-and-smoke-check).
- Fix account and sharing problems from review. Behind a proxy listed in `AUTH_TRUSTED_PROXIES`, logins see the client's own address from `X-Forwarded-For`, so one person's wrong passwords no longer slow everyone. Wrong passwords from strangers slow an account by a minute at most, so nobody can lock someone else out. Sharing refuses an unknown or disabled person, an offer starts at once only for someone who manages both adventures, and losing a share keeps offers sent to it from your own adventure. Archiving a deleted user's adventure stops its game, Resume and Pause keep the control lease when the game never got them, a slow game holds up only its own control lease, and a queued page that closed leaves the line. Stylesheets and health checks skip the account lookups. See [Client addresses behind a proxy](docs/authentication.md#client-addresses-behind-a-proxy).
- Fix more account and control problems from a second review. A backup during a control change no longer hangs. Pause and Resume end only the lease they were sent for. A queued page that was hidden too long leaves the line and says so. Forwarded addresses with a port, brackets or an IPv4 address in IPv6 form are read correctly. Only a browser that logged in to an account before skips its slowdown, not any browser at the same address. Losing manage of an adventure ends offers sent from it. Deleting a user checks for the last admin and the new owners in the same step that deletes them, so a refusal leaves nothing half done. A flood of failed logins no longer wipes the counts of other addresses.
- Fix more account and control problems from a third review. A forwarded address from the default gateway never counts, so a direct client cannot pick its own address. Nobody can take control while Resume or Pause reaches the game, or while a trade is being set up. Ending control tells the people waiting in line. Changing a share, demoting a user or disabling them never holds up other pages, and ends their offers and their place in line where the new role no longer allows them. Nothing new can belong to a user while they are deleted. The last-admin check counts admins at the moment of the change. A browser counts as known for 30 days at most, and no longer after a password change or the end of that person's sessions. Control stays closed after a backup until every game is back, and background work queued at shutdown still runs.
- Fix more account and control problems from a fourth review. A lower role from the identity provider or the proxy now ends offers and places in line the old role allowed, as an admin's change does. Deleting an adventure ends its control and tells the people waiting in line. A role change right after an adventure was deleted no longer fails. A failed cleanup step while deleting a user no longer skips the steps after it.
- Fix more account and control problems from a fifth review. An offer that ends while it is being accepted never queues its trade, so no Pokémon moves without both sides agreeing. A page in line whose person can no longer play hears why when control passes on. A press from someone who just lost control never reaches the game after the next person takes over.
- Fix more account and control problems from a sixth review. A held button against a slow game no longer ties up the library, presses reach the game in the order they were pressed, and a slow press waits as long as before. A press sent just before control changed hands is dropped by the game. Accepting an offer no longer holds up other offers while both games answer. A page in line whose person can no longer play now says so, instead of saying they were turned down.
- Fix more trade and control problems from a seventh review. An offer made while its adventure is given away is refused, so it can never trade the new owner's Pokémon. Accepting an offer whose Pokémon just left in another trade is refused instead of queueing a trade for a Pokémon that is gone. A game that falls behind keeps at most 8 presses waiting, and drops a press that waited over 2 seconds or whose page closed. A Take Control or Resume the game refused no longer turns the player's presses away. Resume and Pause wait behind the presses sent before them, so a late press no longer takes control back without accounts.
- Fix more trade and control problems from an eighth review. Someone who cannot press never takes a place in the line. A full line still takes Take Control, Resume and Pause, in order. A Take Control or Resume the game never answered leaves the player's presses working. Resume and Pause without control wait for a Take Control under way. A trade that finished before Accept no longer blocks it. Deleting a user hands each adventure on in one step, as giving it away does.
- Fix more control problems from a ninth review. When the game does not answer a Take Control, Resume or Pause, PokeSim asks the game what it did and makes control match. A game that cannot say gets its autopilot back once it answers. Take Control, Resume and Pause no longer fill the press line, and they are dropped after waiting too long. A queued Resume or Pause reads who holds control when its turn comes.
- Fix more control problems from a tenth review. PokeSim keeps one wanted state per adventure, so the newest Take Control, Resume or Pause always wins, and a pass of control keeps the owner's choice to resume or pause. A change the game never answered is sent again until it does. Presses from someone who does not hold control are refused before they take a place in the line, and each person has one Take Control in line at a time. A Resume the game made without answering now reports success. A game that hangs no longer slows the other adventures.
- Fix more control problems from an eleventh review. When a game refuses Take Control, Resume or Pause, for example during an exchange, control goes back to how it was and the page shows the game's reason. A game that is busy getting ready for an exchange runs the change later instead of losing it. A game that restarted hears its control state again. Losing access and starting a hand-picked trade now tell the game at once, and a backup tells every game at the same time and brings a paused adventure back paused.
- Fix more control problems from a twelfth review. A Take Control the game was slow to run no longer runs twice and drops the new player's presses. A refused Resume or Pause keeps the line for control open, and one refused during a backup gives no control back. A stopped adventure starts again on its autopilot instead of pausing itself. A hand-picked trade waits for the game to leave manual control before it prepares. The previous player hears that control was taken only once it was. A change the game keeps refusing is retried less often and logged once. The game page now says when a Pause or Resume will happen once the game can, and shows it as pending until it does.
- Fix more trade and control problems from a thirteenth review. Cancelling a hand-picked trade, or shutting down, no longer waits up to 15 minutes for a game that has not left manual control. An adventure stopped during a trade starts again on its autopilot, not paused. A page whose Pause or Resume another person replaced stops saying it is on its way.
- Fix two trade problems from a fourteenth review. When stopping one adventure fails after a trade, the trade stays finished and the other adventure still stops. An owner's Start just before the stop after a trade keeps the adventure running.
- Fix a control problem from a fifteenth review. When stopping an adventure fails, its next Start still runs on its autopilot and no longer hears an old Pause.
- Fix an account problem from a seventeenth review. Deleting the first admin makes the admin who deleted them the Library's owner, so adventures imported from the command line go to a real account. On startup, a Library whose owner was deleted gets its oldest admin as owner, with the adventures that went nowhere.
- Fix three more problems from the seventeenth review. The login page goes back only to a page on this site, even when the address it was given has a tab or line break in it.
- The first start after upgrading from 0.6.x keeps a copy of the older Library database as `app.sqlite.pre-schema-2-<time>` and logs where it is. 0.6.x cannot open the upgraded database, so going back means restoring that copy, or a backup from before the upgrade. See [Update and roll back](docs/operations.md#update-and-roll-back).
- Fix three problems from an eighteenth review. Disabling or demoting the Library's owner hands it to the admin who did it, or else the oldest admin, so `pokesim` commands keep working. An adventure given to someone else has its trading switches back at their defaults, so it takes no offers and trades with no one else's adventures until its new owner turns that on. The copy kept before an upgrade appears under its name only once it is whole.
- Tell both sides in their inboxes when an offer ends because an adventure changed hands or was deleted, or its sender lost their share or was deleted. Inbox items about a deleted adventure no longer link to it.
- Fix Take Control showing control as granted when the game refused it faster than the page could look.
- Stop a busy server from turning a right password into "Wrong username or password". The password check needs 64 MiB and its own threads, and when it could not get them, the error counted as a wrong password. It now tries 3 times, and then the login says the server is busy and to try again. At most 4 checks run at once, about 256 MiB, and a login that waits over 10 seconds for its turn gets the same busy answer.
- Move to PyBoy RS 0.1.5. The window's line counter now starts again at the top of every frame, so the first frame after loading a save in a new process draws menus and text boxes on the right line instead of one line low. The save format is unchanged. The wheels, the lock and the image's emulator source archive all point at the 0.1.5 release.
- Stop the main page from raising "an unexpected error" when a game is too busy to list its Pokémon for trading within 30 seconds. Its worker now answers busy, and trading skips that game for the round as before.
- Cap all local PokeSim work on a developer machine at 12 cores and 22G with systemd user slices in `deploy/systemd`. `sh tools/local_sims.sh install` installs them, and `sh tools/local_sims.sh start` runs a local app in the sims slice (12G). `tools/load_gate.sh` runs test jobs in the tests slice (10G), whose CPU weight beats the sims, and a heavy job may now use `pytest -n 12`.
- Test pull requests on Python 3.12 and Linux x86 only. Tags, a nightly run and manual runs test every Python and platform, which the release gate still requires for the tagged commit. A new push to a pull request cancels its older run, and push, tag and nightly runs always finish. The browser and Windows shards split by recorded module times in `tests/durations.json`, which `tools/record_durations.py` rewrites from the JUnit reports CI uploads. Local pytest runs on 12 workers.
- Gate a deploy on a boot and load smoke instead of the two game hour soak. `tools/live_soak.py smoke` starts every soak save with the candidate, plays 5 game minutes, stops so it saves, starts it again and checks that the newest save loaded. It fails on a stop that does not save, a reload older than its save, or an error or traceback in the worker log, with no comparison to the deployed commit, in about 3 minutes. `tools/deploy_host.sh` now needs a passing smoke report, and `tools/live_soak.py check` prints the soak comparison as advice when one exists.

## 0.6.2

- Publish the container image for linux/arm64 as well as linux/amd64, so it runs on a Raspberry Pi 4 or 5, an ARM NAS or an Apple silicon Mac without emulation. The release workflow builds and tests each architecture on its own native runner, pushes each as `<version>-linux-<arch>` and joins them into one multi-platform tag, then checks anonymously that the tag serves both and that each pulls the tested image ([#269](https://github.com/afk-sapien/PokeSim/issues/269)).

- Add app store templates for Unraid Community Applications, CasaOS, Umbrel and TrueNAS community apps in `deploy/stores/`. Each runs the release image with one data folder, drops every capability and takes the same `PUBLIC_URL` and ntfy settings as the quickstart. None has been submitted to its store yet ([#273](https://github.com/afk-sapien/PokeSim/issues/273)).

- Add `tools/release_version.py`, which moves every pinned version in the Compose files, installers, docs and store templates with one command, and whose `--check` lists any pin that differs from the package version. CI and the release workflow fail on such a pin, so a release can no longer ship a quickstart that installs the previous version ([#271](https://github.com/afk-sapien/PokeSim/issues/271)).

- Start the README with a three command quickstart, the note that ROMs are not included, and what the app needs: at 4x speed, 5 to 20% of a core and about 300 MB of memory for a Red, Blue or Yellow adventure, about 150 MB for Gold, Silver or Crystal, and about 170 MB for the Library ([#275](https://github.com/afk-sapien/PokeSim/issues/275)).

- Keep Red, Blue and Yellow runs out of the Rocket Hideout B1F door before its Rocket is beaten. The map data draws the door to the elevator open, but the map script keeps it shut until that Rocket is beaten, so a run walked back and forth between B1F and B2F. Routes to the elevator now take the B2F spin maze while the door is shut, and the lift leaves for B2F on the way out ([#263](https://github.com/afk-sapien/PokeSim/issues/263), [#267](https://github.com/afk-sapien/PokeSim/issues/267)).

- Keep the heal goal in front on every step while a heal is under way, in all six games. Before, a battle or nurse dialogue on the way to a Pokémon Center ran under the story goal, so the run could turn back mid trip. An errand under way, a heal or a shop trip, now also stays the goal through warps and menus until the next errand decision ends it ([#258](https://github.com/afk-sapien/PokeSim/issues/258), [#261](https://github.com/afk-sapien/PokeSim/issues/261), [#265](https://github.com/afk-sapien/PokeSim/issues/265)).

- Stop Red, Blue and Yellow leaving the Safari Zone or a dungeon to sell. Inside the Safari Zone, a pickup or detour keeps bag room for HM03 and the Gold Teeth, and a crowded bag starts a selling trip only once those no longer fit. Caves and Team Rocket buildings keep two bag entries free for story items, and a restock starts there only for a full bag or no balls ([#256](https://github.com/afk-sapien/PokeSim/issues/256)).

- Stop Gold, Silver and Crystal choosing Blackthorn City's Pokémon Center through Ice Path. Healing stands down inside the cave, so the trip stepped in, handed back to the main goal, stepped out and chose Blackthorn again. A center whose known walk passes through Ice Path is no longer a healing choice ([#254](https://github.com/afk-sapien/PokeSim/issues/254)).

- Count battle experience as progress for every goal in the replay audit, and a heal that restores HP, status or PP as support. Wild battles on a training detour ran under the goal the detour came from, and every heal counted as waste. Play is unchanged.

- Require PokeSim Core 0.11.0. Add `tools/stage_ladder.py check`, which reads each rung's save with Core's save summary and fails when the stage it reads as is not the stage its folder names. For Gold, Silver and Crystal the rung before Red reads as Kanto entered, and the post-game rung reads as Red beaten. Play is unchanged.

- Let headless Red, Blue and Yellow runs play Fair wild DVs. `tools/replay_audit.py run` and `tools/find_stalls.py` take `--fair-wild-dvs`, which rerolls every wild encounter's DVs as an adventure with the setting on does. Before, batches and replays always kept the cartridge's correlated DVs, so they played differently from such an adventure. The rerolls are keyed by the seed, or by an adventure's own key, which replays that adventure's encounters exactly. Adventures play as before.

- Count a PC visit that brings a trainee into the party as progress in the replay audit. Preparing a Pokémon for training swaps it in from a box, which keeps the number of Pokémon held, so the audit counted every such visit as wasted. Randomized Gold has more trainees to evolve, such as Mankey, which is most of why its wasted share looked higher. Play is unchanged.

- Add `tools/stage_ladder.py gate`, which plays 30 game minutes from every rung of every ladder, ten at once under the load gate, and compares each rung's stalls, errors and wasted share with a stored baseline. It exits 1 on a new stall, more errors, or a wasted share more than two points higher, and keeps a bundle for each stall. Every release now runs it before the release soak. Play is unchanged.

## 0.6.1

- Add `tools/stage_ladder.py`, which keeps a ladder of saves, one for each stage of a game, so every stage can be replayed after a change. `snapshot` plays a fresh game headless and keeps a save the first time it reaches a rung: a new game, 2, 4, 6 and 8 badges, the first Elite Four room before any Hall of Fame, and post-game. Gold, Silver and Crystal also keep the first return as Champion, the arrival in Kanto and the first visit to Mt. Silver before Red, and their post-game rung follows Red. A randomized ladder keeps a new game, 4 and 8 badges and the first Elite Four room. Each rung is a stuck scenario folder written compressed. A stall on the way keeps a bundle and the run goes back to the save before it. `adopt` keeps an existing save as a rung. Headless runs in all six games now boot the patched cartridge when `RANDOMIZER` is set, as the managed worker does. Before, they booted the clean cartridge with randomized policy tables, so the replay audit's `--randomizer` option played a clean game. Gold, Silver and Crystal headless runs can now start a new game and write a checkpoint, and Red, Blue and Yellow ones can write it compressed. Play is unchanged.

- Keep every stall bundle in `tools/stage_ladder.py snapshot`. A second stall noticed in the same game minute after a reload wrote over the first bundle, and now gets its own folder with a `-2` or later suffix. Dropping an old rolling save now removes its manifest too.

- Stop Gold, Silver and Crystal restocking at Mahogany Mart's pharmacist during the Rocket hideout. Once the player agrees to help Lance he only talks about Lance and sells nothing, so the restock and the hideout passwords took turns at his counter forever. His counter now counts as closed from then on, and the run restocks elsewhere. Red, Blue and Yellow play as before.

- Let Gold, Silver and Crystal walk the Olivine Port pier to the S.S. Aqua. A carpet tile at the top of the gangway has no warp on it, but navigation treated stepping off it as a warp and avoided it, so the pier looked cut off and the run walked in and out of the port entrance until it gave up. Only a carpet with a warp on it is avoided now. Red, Blue and Yellow play as before.

- Name the real cause when a managed worker is not ready in time. The supervisor read the worker log while another thread was still adding lines to it, so a line arriving at that moment raised "deque mutated during iteration" and hid the start failure. It now reads a copy.

## 0.6.0

- Stop Gold, Silver and Crystal swapping their first two Pokémon back and forth at a PC during the Lugia or Ho-Oh quest. The quest puts its sleeping move user in front, then a visit to free box room took over the goal and the level reorder put the strongest Pokémon back, so each step only swapped the lead and the visit never went on. The sleeper now keeps the lead while a box release or box change runs and on any step the quest made. Red, Blue and Yellow play as before.

- Count a Kanto Marathon checkpoint as progress in Red, Blue and Yellow stuck scenarios, as a Johto Marathon checkpoint already is in Gold, Silver and Crystal. A race earns nothing else and runs longer than a scenario's 20 minute quiet window, so a Red dojo return and a Yellow marathon save failed while the player was racing and then walking to Saffron. Play is unchanged. Local test runs now use up to 10 workers, and `tools/load_gate.sh` has five test slots.

- Stop journal attachments from growing without a limit. Routine journal entries now keep their screenshot, save and save manifest only for the newest 500 in each adventure, set by the new `EVENT_ATTACHMENT_KEEP` (`0` keeps all). Older ones lose them oldest first at each autosave, in Red, Blue, Yellow, Gold, Silver and Crystal. Milestones, the notable entries of priority 4 or 5 such as badges, League wins, the Elite Four, new Pokédex entries, evolutions and hatches, keep theirs forever, and every entry keeps its text. Gold, Silver and Crystal journal save manifests are now written compressed, about a third of their 28 KB, and the startup pass compresses the ones already on disk. A release older than this one cannot read a compressed manifest, so after a rollback those entries cannot be rewound to. Custom rewards and Champion counter purchases also kept a 167 KB save each in `custom-rewards/` after they were delivered, and nothing read it again. Finished ones are now removed at each autosave. `EVENT_RETENTION_DAYS` still defaults to `0`.

- Move to PyBoy RS 0.1.4. A save made with sound off could not be loaded again once the game had written the divider register, and the load failed with "Invalid scheduler state". Yellow writes that register often, so a checkpoint made a few frames later was lost. Saves made now load again. A file that 0.1.2 already wrote this way stays broken and still fails to load. The wheels, the lock and the image's emulator source archive all point at the 0.1.4 release.

- Fix three flaky checks. A stuck scenario replay whose worker process dies, as one did with a segfault inside the interpreter, broke the whole process pool, and every scenario still in it failed with a bare BrokenProcessPool. `tools/stuck_scenarios.py run` and the scenario tests now play those scenarios once more in a fresh pool, and a scenario that dies twice fails by name. A scenario that raises now fails alone in the tool too, instead of ending the run. The planner step budget test timed steps against fixed milliseconds, so slow or busy CI runners failed it at 6 to 16 ms. Each step is now timed next to a fixed piece of reference work, and the 5 ms median and 50 ms slowest step budgets grow by how much slower that work ran than on a workstation. The supervisor readiness test gave its worker 1.5 seconds to start and print, which a loaded macOS Intel runner missed. It now times out only once the worker's last line has arrived.

- Stop counting long Red, Blue and Yellow battle turns as screen recoveries. A battle decision had 900 frames to complete from the moment it was made, and the clock kept running after the game had taken the move. A knockout with a forced switch, a League move animation, a level up or the text at the end of a battle ran past it, so the run pressed B and dropped its decision in the middle of a turn that was going fine. These made up almost every Gen I recovery. The clock now stops once a shortcut hands the decision to the game, and a decision the game never took is still recovered after 900 frames. Gold, Silver and Crystal play as before.

- Plan the Victory Road boulders in Red, Blue and Yellow from the cartridge's own switch squares. The five switches and their flags are now read from the game scripts into the gate table, and any loose boulder on a floor is planned against any switch still open, in any order, with the shortest plan kept. A floor where no boulder can reach a switch from here pushes one aside first, and a corridor walled off from every ladder that leads on pushes its boulder out of the way. The hand list of boulders, switches and clearing squares is gone, and so are the coordinate boxes that sent a run north of the passage to the east corridor ladder. A run on the League side now heads for the southern entrance whenever no open route reaches it. Gold, Silver and Crystal play as before.

- Retire the last Red, Blue and Yellow goal timers in the overworld. Teaching Surf or Strength from the bag is now a candidate worth the move it gives, its share of a level 100 credit by the battle power it adds, so it goes when that is worth more per frame than the goal under way, and it pays its frames again to cut into a project. The 3600 frame teach timer is gone. A teach is tried once for a partner and its moves, and the best teach is scored again only when the party or its HMs change. A partner's training detour in nearby grass now lasts until the partner gains a level, instead of a fixed 2400 frames. It still ends after 2400 frames without any experience, or when the partner leaves the party. Gold, Silver and Crystal play as before.

- Take the wait before a missed legendary returns from the planner's shared backoff in all six games. It is still 36000 frames for each miss in a row, at most 180000, and older saves keep their waits. The Red, Blue and Yellow retreat from a legendary with no balls left, or after 50 throws, is now a rule of the resource ledger. Both play as before.

- Give the hunt's run from wild battles real scenario coverage in all six games. Red, Blue and Yellow stuck scenarios can now take a species out of the Pokédex, hold the first badges and set story events by name. A scenario can wait for a Pokédex entry by number (owned:46), which counts once two reads in a row show it, and can ask for a least number of run attempts (min_flees). Three new private scenarios use this. A weak Red party with Cut hunts Paras on Route 2 for a Cut carrier, a Yellow Hall of Fame save hunts Paras again, and a Gold postgame save hunts Mareep on Route 42. Each one runs from most of the other wild battles on its way.

- Let the goal under way decide whether Red, Blue and Yellow fight, run from or catch a wild Pokémon, through the same battle stance as Gold, Silver and Crystal. Pokédex, partner, repeat and high DV hunts, searches for a Cut, Surf or Strength partner and legendary expeditions run from every wild battle they cannot catch from, and the walk to the Cable Club runs too. Gym and partner training fights. Any other goal fights until its party falls under the Gen I heal line, which is now the battle stance's HP and PP budget, then runs on its way to heal. A Pokémon the collection wants is still caught and a shiny the run cannot catch is still run from, whatever the goal. A battle where running failed twice is fought out, a shiny too. The legendary expedition's own rule for running from other Pokémon is gone, and so is the shiny half of the legendary retreat. The replay audit now counts Red, Blue and Yellow run attempts and failed runs for each goal row.

- Let the goal under way decide whether Gold, Silver and Crystal fight, run from or catch a wild Pokémon. Travel runs from plain wild battles, training fights them, and every hunt catches its target and runs from the rest, so Pokédex, carrier, better-copy and shiny searches meet their next encounter sooner. Any other goal fights until its party falls under the heal line or runs out of attack PP, then runs on its way to heal. A wanted Pokémon is still caught and a shiny the run cannot catch is still run from, whatever the goal. A battle where running failed twice is fought out. The check for the walk to Olivine before a Battle Tower challenge and the shiny session's own flee rule are gone, replaced by these goal kinds. Red, Blue and Yellow play as before. The replay audit now counts run attempts and failed runs for each goal row.

- Let Gold, Silver and Crystal stuck scenarios edit their save. The party and money edits work as in Red, Blue and Yellow. A Gen II scenario can also take species out of the Pokédex, run the cartridge clock forward to an hour or a weekday, fill every free box slot with copies of one stored Pokémon and offer the Battle Tower again with no level cap resting. A scenario can now wait for what the planner does as well as what the player achieves: a ladder pick, a timed hunt or a stand-down, by name. It can keep playing for a while after that, wait for a later event and fail on a retry loop, the same goal standing down more than three times in a row. Two new private Crystal scenarios use this. One hunts Sunkern by day, the other has a Battle Tower team with no box room. The Crystal Tower no longer raises once its room stand-down ends. The next team choice read the room key as a level cap.

- Let the utility arbiter climb the Gold, Silver and Crystal collection ladder. Each rung, from the Super Rod and move tutors through gifts, trades, the contest, breeding, training, legendaries and Pokédex hunts to the postgame, now offers a candidate with its value and expected frames, and the arbiter keeps the best of them. A rung that loses leaves no trace, so its plan is made again next time. The Day-Care walk and the wait for the clock are passive candidates, so they run only when nothing else is offered and never win over real work. A rung that cuts into the one under way pays for the walk back to it. The 18000 frame hunt retry, the 50000 frame Battle Tower retry and the rules that held a hunt or a League run back while a timed catch was coming are gone. A hunt with no tile to stand on and a Tower with no room now stand down on the planner's own backoff, and a timed catch counts as a passive candidate worth its new entry. The shop trip no longer skips a fixed list of maps. It weighs its walk against how much the bag needs it and never breaks off an ice or boulder puzzle, a story dungeon or the League, which the map data now names. Red, Blue and Yellow play as before.

- Require pokecore 0.10.2.

- Take the open way south from Route 23 in Red, Blue and Yellow. The route search counts Victory Road boulder switches that are still unsolved as solvable, so a detour or a new goal on Route 23 could route through Victory Road to the Indigo Plateau, and inside Victory Road only open gates count, which sent the player straight back out. A Red postgame save walked in and out of Victory Road for 90 minutes. Route 23 now tries the route through open gates first and falls back to the full search when there is none.

- Sell from a full bag at the Indigo Plateau shop in Red, Blue and Yellow. Outside, a full bag planned a trip to the nearest shop, and inside the lobby only the League supplies counted, so a player with enough balls and medicine turned around at the door. A Red postgame save walked in and out of the lobby for 90 minutes.

- Count each Johto Marathon checkpoint as progress in Gold, Silver and Crystal scenario replays. A race takes about 40 game minutes and earns nothing else on its way, so a scenario with a 15 minute quiet window called a running race a stall. The runtime stall watch already counted it as progress. A scenario replay that raises now fails on its own with the traceback, and the others still run.

- Let the utility arbiter weigh the Red, Blue and Yellow overworld goals. The story, the collection plan, the project under way, ground pickups, party swaps, HM and TM teaching and Champion counter trips are now candidates, and the arbiter keeps the best of them. The lists of goal keys that each source skipped are gone, replaced by one table of goal kinds. An errand under way, such as a restock, a heal or a TM trip, is not cut into by anything but a step of the same errand. A failed precondition, such as a hurt party or a full box, still puts its fix first. A TM trip is now worth the move it gives, its share of a level 100 credit by the battle power it adds, and it cuts into training only when that is worth more per frame. The 18000 frame check and 3600 frame teach timers for TMs are gone. Options are scored again only when the party, bag, purse or Champion offers change, a bought TM is taught at once, and a trip that stalls stands down on the planner's own backoff, so the next best purchase can go. Gold, Silver and Crystal play as before.

- Free a box slot in Gold, Silver and Crystal when six are in the party and every box is full, as Red, Blue and Yellow do. A boxed spare holding an item a plan wants was only offered with the item taken off first, which needs a free party slot, so it could never go. It may now go with its item while the bag or another Pokémon keeps a copy. The last copy of a wanted item still never leaves, and stranger copies, gifts, legendaries and the party stay as before. A live Silver adventure had 280 of 280 slots full with 23 spare Snorlax each holding Leftovers, so it could not start a better-copy hunt and ran the League again and again.

- Keep training the trainee in the party before a boxed one comes out, in all six games. In Red, Blue and Yellow a boxed trainee is now offered only when it sits in a higher tier than every party trainee, such as one still short of its level 100 credit. In Gold, Silver and Crystal a party copy within 2% of its species' best potential is trained instead of a boxed best copy. Each switch took a PC trip of about 10000 frames that the walk price did not show. Silver hatched Cyndaquils one after another and trained each to a level 20 Quilava while a boxed Quilava 0.3% stronger kept the party one from training. On a seeded batch PC trips fell from 32 to 12 in Red, 45 to 9 in Yellow and 15 to 6 in Silver, and wasted frames fell in every game but Blue, which played the same.

- Let the utility arbiter decide the Gold, Silver and Crystal postgame. The random rotation, its weights and its recent list are gone. Training now goes ahead of better-copy hunts, as in Red, Blue and Yellow, through the same hunt tier. A better-copy hunt is worth each catch's expected drop in the best DV tail, for the catches it takes to find one better copy, and it ends at that first better copy, so the arbiter weighs the next one afresh. The three catch cap is gone. A shiny search is filler and still runs ahead of a League run, which stays the last fallback. Its 100 encounter cap, its hour limit and its two activity break are gone. It now runs until it meets a shiny or stalls, each wild battle met counts as its progress, so it stands down only when its map stops giving battles, and the arbiter is asked again after each of its battles. A due marathon now has a tier of its own in all six games: once eligible and past its six hour cooldown, it outranks better-copy hunts and training, while missing Pokédex entries and urgent supply projects still go first. In Red, Blue and Yellow that also puts every new Pokédex entry ahead of training, since the race sits between them. Older saves load and drop the rotation's state.

- Require pokecore 0.10.1. Core now refuses a cartridge that is not a Pokémon game before reading it, and the planner catches that refusal for its unpriced catch costs instead of any error. A Pokémon game whose tables fail to read still stops the plan.

- Let the utility arbiter decide Red, Blue and Yellow side projects after the Champion. Each candidate now carries its value from the approved weights and its expected frames, the walk plus the catch, and the arbiter picks the most value per frame. The fixed priorities, the new entry and last rematch filters, the rematch weight, the per-project cooldowns and the 600 frame gap between projects are gone. A plan that finds nothing is not drawn again until the Pokédex, bag, boxes, party, flags, map or purse change. A legendary counts as a new entry only while the Pokédex lacks it. Training for a family that already has its level 100 credit is now filler. Training toward a credit goes before any hunt for another copy of a registered species, quality or plain, since at the approved weights a quality catch earns about ten times what a training step earns per frame and Red's training share fell from 57% to 2%. A training step is priced by the experience its trainee's growth rate needs, not by a flat price per level, since Red trained a level 50 Dragonair on Route 23 ahead of level 25 partners and walked to the Pokémon Center every few battles. A partner whose attacking moves hold fewer than 20 uses between heals is no longer trained. A Red Chansey whose only attack was Double Slap trained for 600000 frames and walked to the Pokémon Center a hundred times. Catch costs come from the cartridge's own grass, water and fishing tables, read once per adventure through pokecore 0.10.0, so a randomized cartridge prices its own slots. Each catch also pays a fixed 30000 frames for the battle, the throws and the walk between encounters, which matches what postgame hunts took on three Red and three Yellow saves. A hunt now buys up to 30 balls while the purse stays above what the ledger still needs, since Red hunts threw about five Ultra Balls a catch and walked to a mart after every catch with 15. A hunt whose purse cannot buy its balls no longer walks to a mart for one or two, and it ends once fewer than five are left, so a rematch can refill the purse. A Yellow hunt for Growlithe in the Pokémon Mansion spent its money at Cinnabar, then searched with no balls. The committed Gen 1 wild table and `tools/gen1_wild.py` are removed. Gold, Silver and Crystal read their wild rows through the same module and play as before. Older randomized adventures load, replay and accept their share codes as before.

- Show what the bot is working on in all six games, in a new panel on the Stats page: the current goal, the share of game time each goal took and the most recent stand-downs, each named after the goal that was running. Counting starts when this version first runs an adventure and is saved once a minute. `/api/statistics` adds a `goal_time` object in both generations.

- Add the Johto Marathon to Gold, Silver and Crystal. The course runs from New Bark Town to Ecruteak City and back through Cherrygrove, Violet, Azalea and Goldenrod, with 10 checkpoints, each on the tile below a Pokémon Center door or Elm's Lab door. Every leg is on land and walks both ways, so no leg needs Surf and no ledge blocks the way back, and the runner never flies or surfs once past the starting line. The way to New Bark Town is not timed, so the player may fly or surf there, which a player in Kanto needs. It becomes eligible once the player is Champion, has finished four postgame activities, has Cut in the party and has Sudowoodo off Route 36. It keeps the Kanto Marathon's six hour cooldown, 50 minute budget and two minute idle limit. Both courses now run on one engine, which takes a course's checkpoints and name, so Red, Blue and Yellow play exactly as before. Gold, Silver and Crystal get every part the Kanto Marathon has: the objective with the next checkpoint and race clock, journal entries with screenshots at the start and finish, the finish report, personal best and record announcements, and the marathon panel and Marathons completed count on the Stats page. The panel is named for the course. `/api/statistics` now sends a `marathon` object and a `marathons` count in both generations.

- Count money earned and spent in all six games, in a new Money earned and spent panel on the Stats page. Each change in the purse is counted once, by source: prize money is any rise during a battle, Pay Day included, other income is any other rise, the blackout penalty is a drop within 30 seconds of the whole party fainting, and shops and fees are any other drop. Counting starts when this version first runs an adventure, and the panel says from when. `/api/statistics` adds a `money_flow` object in both generations.

- Answer a page asked for in the moment an adventure starts with a short "starting" reply, status 503 and a retry hint of two seconds, and log one line. The library still listed the adventure as stopped while its worker came up, so the page tried to open a read only view, failed because the adventure was running, and logged a full traceback.

- Show how fast each adventure catches, in all six games. Collection details on the Stats page now give catches per hour of simulated playtime and wild encounters per catch, and the Pokémon page gives wild encounters per catch for each species. When catches were only counted from part way through, the pace says it is set against all of the playtime. The Collection and League history chart now starts with badges, out of 8 in Red, Blue and Yellow and 16 in Gold, Silver and Crystal. A new Shiny log lists each shiny seen or acquired by species and date. Shiny receipts now keep their date, and receipts from before this change show Date unknown. `/api/statistics` adds `collection_records.rates` and `collection_records.shiny.log`, and each species on `/api/statistics/activity` adds `per_catch`, in both generations.

- Run the utility arbiter in shadow mode in all six games. Where the planner already picks a goal (the Red, Blue and Yellow collection pick and overworld chain, and the Gold, Silver and Crystal journey ladder, hunt pick and postgame rotation), it now also builds the arbiter's candidates and records what the arbiter would have picked, while the current order still decides. The approved weights live in one place: a new Pokédex entry is one unit, a first level 100 credit and a first perfect copy half a unit each, a better copy half the expected drop in its best DV tail, and a rematch its prize while the purse is short and a small constant otherwise. The comparison goes only to the log and to `tools/replay_audit.py`, which now reports per game how often the two agree, the share of frames by the kind of goal the arbiter would have chosen and the kinds of disagreement. Shadow code runs only at those picks, draws no random number, is never saved and logs a failure once without stopping the run. Nothing acts on it yet, so no game plays differently.

- Bring the Gold, Silver and Crystal Stats page in line with Red, Blue and Yellow. Their history no longer records a Kanto Marathon count of 0, since the race is Red, Blue and Yellow only. Their steps chart is now named Steps walked, since it charts every step the cartridge counts, not a sample. Their history now thins out after 30 days to one row a day, as Red, Blue and Yellow history does, so it stops growing by one row an hour. Their collection charts wait for two matching reads, so a box read in the middle of a PC transfer is not charted. A spare that a release visit, training or a team change lets go now gets a journal entry, as it does in Red, Blue and Yellow. Only releases for link preparation had one before.

- Keep lifetime tallies of faints, blackouts, trainers defeated, evolutions and releases in all six games, with a trainer win rate, in a new Battles and moments panel on the Stats page. Each one is counted as its journal entry is written, so pruning old entries no longer loses it. An adventure from before this change starts from the entries its journal still holds, once, and the panel says from when if older ones were already pruned. A blackout counts as a trainer loss unless its entry names the wild Pokémon it was fighting, which both generations write in a wild battle. `/api/statistics` now sends a `tallies` object in both generations.

- Add a shared cost model to the planner. The cost of a search, the walk to its map plus the battles it takes to meet what it wants, now lives in one place for all six games, and Gold, Silver and Crystal get exactly the costs they had. Nothing else reads it yet, so no game plays differently.

- Add a utility arbiter to the planner, shared by all six games. It takes candidate goals in four tiers (story, upkeep, progress and filler), picks the highest tier first and then the most value per frame, counts the frames lost by cutting into a running goal, never picks a passive wait such as Day Care steps, and breaks ties on the goal key. It can also report how its pick differs from the goal the current planner chose. Nothing uses it yet, so no game plays differently.

- Stop counting the heals, restocks and box changes a Red, Blue or Yellow project needs, and the walk back from them, against its two minutes without progress or its expedition budget. A hunt in Seafoam Islands walked to Cinnabar for a box change, a Route 23 fishing trip went back to Viridian three times to heal, and a hunt in Mt. Moon walked back from a restock in Saffron. Each stood down on the walk back. A Yellow hunt on Route 21 ran out of its expedition budget after three box changes. Maps first reached on such a trip no longer count as a new route either. The walk back ends on the map the trip left from, and a walk back longer than the trip, or than two minutes, counts again. Gold, Silver and Crystal already spend a hunt's or training trip's budget only while that goal is active.

- Stop counting wild battles on the way to a Gold, Silver or Crystal hunt's map against its search budget. A Gold hunt fishing for a better Goldeen in Silver Cave Room 2 walked back through Room 1 after each trip to the PC, and the cave battles there spent the whole budget, so the hunt stood down on all three seeded replays while Goldeen bit at 70%. Battles on the hunt's own map still count.

- Weigh what a Gold, Silver or Crystal hunt for a better copy is worth against what it costs. A catch is worth half the expected drop in the species' best DV tail, and a hunt now runs only while its next catch earns at least as much per decision as a species met in every battle earns down to the top 5%. A rare species therefore ends its hunt at the first good copy, and a species whose next catch would not pay is never hunted, so its best copy goes to training at once. A 5% Larvitar on Mt. Silver used to take three catches every time, and its run of luck moved Silver's wasted frames by more than ten points between two seeded replays. Hunts now also pick the species whose next catch earns the most per decision, not the one with the worst best copy. The rate counts what the hunts for each species have actually met: a dry run stretches the expected decisions per catch, so a hunt that is not finding its species ends cleanly before its stand-down budget runs out, and later hunts pass it over. The postgame shiny search is now filler and runs only once no better-DV hunt or training is left. Each 100-battle outing took about 150,000 frames and almost never found a shiny. A wild shiny met at any time is still caught.

- Give each hunt its own row in the `tools/replay_audit.py` report. One goal key covers every hunt, and the row took the first description it saw, so a Silver row named for a Girafarig on Route 43 also held a Larvitar hunt on Mt. Silver, the other quality hunts and every shiny session. Runs now record a row per hunt kind and target, such as `collection_hunt quality Larvitar`, with all shiny sessions in one row, and a row per trainee for training. Red, Blue and Yellow rows now show their goal titles too. Run files from before this change keep each hunt or training goal in one row marked `(all)`, since they hold no split.

- Stop counting the catch against a Gold, Silver or Crystal hunt's search budget. A hunt gets three times the decisions its encounter rate predicts, but the battle with the Pokémon it wants counted too, and a dozen balls at a Golduck at full health took more decisions than the whole search was expected to take. Two Gold hunts for better copies stood down in the middle of that battle. Battles with an item carrier still count, since most carriers hold no item.

- Keep a Red, Blue or Yellow Kanto Marathon going through a release visit. The marathon still runs its race clock while another goal's PC visit holds it, but that visit also counted as two minutes without progress, so a long one deferred the marathon before it resumed. Now that releases reach every slot, one Red adventure started a release visit right at the start line and lost its marathon that way.

- Take the chosen Hitmon at the Fighting Dojo in Red, Blue and Yellow. The gift walk goes from the Karate Master to a ball under one goal, and the stall timer from the battle kept running, so it ran out beside the ball. The recovery step then walked and pressed A at random and could take the other Hitmon. The project then waited for a ball that was gone until it stood down. Any goal whose targets change now restarts the stall timer, a ball is no longer approached from the tile under the other ball, and a gift or static Pokémon that leaves before it joins ends its project at once.

- Add `--reseed-goals` to `tools/replay_audit.py` for comparing two code versions. A small timing change early in a replay used to shift the game's random numbers, so a later hunt caught or missed by luck, and one Silver comparison moved the wasted hunting frames by 87,000 for that reason alone. With the option each goal start on a save gets the same encounter rolls in both versions, seeded from the save, the goal and how often it started before. The audit also reads linked trainer ids from `AUDIT_PARTNERS` and lists each Pokémon a Gold, Silver or Crystal release visit let go. The application never reseeds a game.

- Require pokecore 0.9.5. A nickname received in a trade can hold a text command such as <CONT>, which stops Bill's PC list as it draws. Core now presses through all nine such commands once it can read the stack, so releases, withdrawals and trades reach every Pokémon stored after such a name in all six games. Red, Blue and Yellow used to skip those Pokémon, and Red's live adventure kept every spare stored after WETFUND in Box 11. Every game now passes the stack pointer to Core's PC menus. Gold, Silver and Crystal never passed it, and Yellow's PC did not open without it. When the stack pointer is missing, PokeSim still keeps away from the slots Core cannot reach: in Red and Blue the name and every slot after it, in Yellow its whole box, and in Gold, Silver and Crystal any box holding such a name.

- Release only the player's own Pokémon and copies from linked adventures in all six games. A Pokémon from any other trainer stays in the box, as do legendaries and the player's own gifts and fossils. A trainer id counts as linked once a Pokémon from that trainer arrives in a completed trade, or when the coordinator lists it with its collection requests. Releases also take spares from the open box first, so fewer visits change boxes. Gold and Silver do not record where a gift or event Pokémon came from, so those games cannot tell them apart and only Crystal keeps them. A wanted held item never leaves with its holder, and a cheap one still may. Gold, Silver and Crystal now count free party slots as room when deciding to start a release visit, so depositing a training partner no longer starts another one. The internal inventory now reports the player's trainer id and collection requests accept a `partners` list. Gold, Silver and Crystal can still stall on a nickname that ends in a text command in Bill's PC list, which Red, Blue and Yellow already avoid. A later change fixes that in all six games.

- Require pokecore 0.9.3. Core now names the title screen and the main menu, which it used to read as the overworld. A Gold, Silver or Crystal menu task that finds either screen ends at once and presses nothing. Core 0.9.2 also read Bill's PC, battles and dialogue in Gold and Silver as the title screen, so box changes stalled and the PC release visits repeated. 0.9.3 reads them correctly.

- Let Gold, Silver and Crystal replays buy at the Champion shop. The headless runner never added the planned TM or supply to the clerk's list, so each visit ended "This mart does not sell that item" and stood down, and the replay audit counted those stand-downs against the planner.

- Count a Pokémon let go at the PC as progress in the planning monitor and the replay audit. A release visit frees the slot the next catch needs, but the audit counted Gold and Silver release visits as wasted frames.

- Stop Gold, Silver and Crystal planning during the start of a wild battle. The battle transition draws over the map the plan reads, so a postgame hunt saw no grass and switched to "Wait for the encounter map to finish loading", and a Pokédex hunt dropped its target as if it had no route. The wait then lasted the whole battle, so most postgame hunting showed as waiting. The hunt that met the Pokémon now carries on through the battle.

- Count more Gold, Silver and Crystal purchases, catches and trades. Drinks from the Goldenrod and Celadon vending machines, Moomoo Milk and the Mahogany RageCandyBar now count as purchases with their item, as the Goldenrod Underground bargain shop already did. The Pokémon kept at the end of a Bug-Catching Contest now counts as caught on the Pokémon page and in Total caught. A cable session that trades more than one Pokémon now counts every one of them in traded in and traded out, where before only the first exchange counted.

- Show how long ago the last achievement was on the Gold, Silver and Crystal Live page. It always read "just now" before. Stats → Items now names the Red, Blue and Yellow Champion shop counter at the Celadon Dept. Store, as it already did for Goldenrod. A new test compares what both generations send to the Live, Statistics and Items pages, so a field one generation fills and the other leaves empty fails unless it is listed with a reason.

- Require pokecore 0.9.1. Gold, Silver and Crystal randomized adventures that shuffle trainers now give each new Pokémon a fitting move set, where before it kept the moves of the Pokémon it replaced. A share code still gives the same Pokémon as before.

- Count Gold, Silver and Crystal custom gifts in Total caught and Pokémon caught, as Red, Blue and Yellow do. A new level 100 species or perfect find now reaches the progress history and the day and week level 100 counts right away, instead of waiting for the next journal entry. The Marathons completed chart, which stayed at zero, is hidden for these games since the Kanto Marathon is a Red, Blue and Yellow race.

- Let the strongest Pokémon lead again in Gold, Silver and Crystal once every roaming beast is caught. The beast search kept its sleeper on record after the last catch, so a Crystal team led with a level 20 Charmeleon on each return to Sudowoodo, lost in Victory Road and walked back to heal over and over.

- Keep Gold, Silver and Crystal walking to the same Pokémon Center when two are equally near. At Rock Tunnel the choice swapped each time the player crossed the warp to Route 10, so a trip to make room in storage walked in and out of the tunnel forever.

- Stop Red, Blue and Yellow jumping a ledge on a short detour from the route. On Route 22 a detour over a ledge sent the League return around the whole route, again and again, until the rematch gave up and the adventure waited for its next try.

- Add one resource ledger for bag entries, box and party slots and money in all six games. Gold, Silver and Crystal now use it to pick the item put in the PC when a held item has no free bag entry to come back to, with the same choice as before. Red, Blue and Yellow read it beside the fund check and log where it would sell a different item. Later changes move the separate bag, box and money rules onto it.

- Keep the field moves Gold, Silver and Crystal never replace in one place on the resource ledger, shared by taught machines, level-up moves, the Champion shop TMs, training, trades and the Battle Tower. The moves kept are unchanged. A Move Deleter visit now names the field move it makes room for, where it always said Waterfall.

- Move the Red, Blue and Yellow shop onto the resource ledger. What a crowded bag sells for room, what sells to raise the Safari Zone fee, and the cash the shop leaves alone now come from the ledger, with the Safari fee held back as a reservation until Surf and the Gold Teeth are both in. The shop makes the same choices as before.

- Add one precondition check for goals in all six games. A goal can now say which items, badges, event flags, places and room on the resource ledger it needs before it starts, and the check answers with what is missing and the errands that would fix it. Nothing uses it yet. Later changes move the gate lists in navigation and the full box and ball checks in collection onto it.

- Generate the Red, Blue and Yellow gate table from the game scripts. The Cycling Road, Saffron, Route 23 and Cinnabar Gym gates now come from tools/gen1_gates.py, and a test regenerates the table from the pinned disassembly and fails when it drifts. The table matches the lists navigation uses today, so play is unchanged. A later change moves navigation onto it.

- Move Red, Blue and Yellow navigation onto the generated gate table and the precondition check. Each Cycling Road, Saffron, Route 23, Silph Co and Cinnabar Gym gate is now one condition on its tiles, and the separate hand-written lists are gone. Navigation closes the same gates as before, except that the Earth Badge guard on Route 23 now leaves the tiles east of him open, as the game does.

- Let Red, Blue and Yellow collection sources say what they need through the precondition check. Room to catch, a ball, Surf, the rod, the Safari fee, room to take a gift or fossil and five balls for a repeat hunt are now one requirement list per source, in place of the separate checks in the project chooser. The chooser picks the same projects as before.

- Let a Gold, Silver or Crystal clock wait ask the resource ledger for room to catch. A wait that ends in a catch now needs a free party slot, a free box slot or a spare the ledger can let go, through the precondition check, in place of its own full storage check. It waits for the same things as before.

- Free a box slot in Gold, Silver and Crystal when the party and every box are full of trained Pokémon or Pokémon holding items. Replays of one Silver and one Gold run stood still because the only spares left were trained or held an item, and those were never released. The resource ledger now ranks every spare by what it would cost to lose. A plain duplicate goes first, then a trained one or one holding an item no plan uses. When the party has a free slot, the held item is taken off and kept before the Pokémon goes, and an item a plan uses is always kept that way. A visit to the PC in all six games now frees slots until ten are open, so a run that keeps catching no longer goes back to the PC for one slot after each catch. In Red, Blue and Yellow the time spent on that visit no longer counts against the hunt it interrupted. In Crystal a spare withdrawn to take its item off now closes the PC text first, and a spare whose item cannot be taken goes back to its box instead of staying in the party. The visit also stops at ten open slots once a spare whose item is coming off is gone, where a Crystal replay kept starting the next one and released until 34 slots were open.

- Base money decisions in all six games on what the money is for. Gold, Silver and Crystal used fixed amounts for when to sell, when to keep balls, when to win League prize money and when to fund Red, and Red, Blue and Yellow ran the League for money below a fixed 10,000. The resource ledger now holds the cash reserve and any Day Care fees, and each decision asks whether the money past them pays for what it needs. A League run funds Red when the money cannot buy the Hyper Potions the bag is short of, which is 14,800 with none left, and it pays for ball money when there are fewer than four balls and the money cannot buy four of the best ball. A shop visit for balls may now spend the cash reserve. An ordinary catch now keeps the last three balls after the eighth badge too, unless the money can buy four Poké Balls back, and Sudowoodo, Snorlax, the red Gyarados and the legendaries always get a throw. Selling for ball money now keeps the TMs the Battle Tower team learns, such as Shadow Ball. Red, Blue and Yellow now run the League for money while the money cannot cover the cash reserve and ten Ultra Balls, which is about 12,300.

- Give Gold, Silver and Crystal the journal entries Red, Blue and Yellow already write. The journal now lists first sightings, faints, blackouts, trainer wins, key items and HMs, money and play time milestones and the rival's name, so the Elite Four, trainer, exploration and blackout notifications now fire for these games too. A wild Raikou, Entei, Suicune, Lugia, Ho-Oh or Celebi caught in battle now reads "Caught the legendary Suicune!" and goes out as a Legendary Pokémon notification. Faints, sightings and other timeline-only entries keep a picture but no save, and they do not count as progress for the stall watch.

- Bring Gold, Silver and Crystal settings in line with Red, Blue and Yellow. The Goldenrod Champion shop now opens to every Champion, as in Gen I, instead of only with Extra store items on. Steps between gift, trade, Sudowoodo and Snorlax returns now also reopen Bill's Eevee, Kiyo's Tyrogue, Crystal's Odd Egg and Dratini, and Kim's Aerodactyl trade, the only trade whose Pokémon has no other source. Each return shows on the Statistics page and in the journal. Red, Blue and Yellow now ask for help when a run stops making game progress, as Gen II already did, so the watchdog can show it. Gen II adventures refuse a policy other than strategic, which is the only one they play.

- Bring the Gold, Silver and Crystal Pokédex up to Red's. Each entry now has the Bulbapedia, Serebii and Wikipedia links under Read more. Where to look also lists gifts, standing encounters, in-game trades and Game Corner prizes with their coin price, and fishing spots show a Fishing tag with the rod. The optional item icon download in Settings now covers Gold, Silver and Crystal items too, so Stats → Items shows them. If you installed icons before, choose Download icons for all games to add the new ones. The trade board also shows portraits up to Celebi.

- Give every hunt, training trip and errand a time allowance that grows back when it makes progress. A project used to stop after a fixed time even while it was catching Pokémon or gaining experience, and in Gold, Silver and Crystal a hunt stopped after a fixed time whatever its odds. Now the time allowed is three times what the work is expected to take, and a catch, a new Pokédex entry, experience or a story event gives the full time back. The time spent carries over a reload. Gold, Silver and Crystal base it on the encounter rate and the maps on the way, and a training trip that gains no experience for a while is set aside too. Red, Blue and Yellow keep the time each kind of project had before. TM shopping trips count only the time spent on the trip.

- Count battles, catches, gifts, trades, purchases and item use in Gold, Silver and Crystal. The Pokémon and Items stats pages used to show "Not counted" for every Gen 2 count and only listed what was held. They now count wild and trainer Pokémon met, opponents defeated, catches, custom gifts, cable, Time Capsule and in-game trades, shop purchases, and items used up, and every item is listed. Counting starts the first time an adventure runs on this version. An adventure that was already under way says "Counting since" that date at the top of each count, and catches and earlier cable trades are counted from their own records. A blank count now says why. "Not tracked yet" means the adventure has not run since counting began, and "Not counted" is kept for reusable items, which are never used up.

- Keep Crystal's Battle Tower waits through a reload. A level the team kept losing at waited longer after each loss, but a reload while the Tower team was being put together forgot the wait and tried the same level again. Gold, Silver and Crystal now keep every stood down hunt, training, activity team and Tower level in one place that a reload carries over, and older saves keep the waits they had.

- Stop Gold and Silver hunting a wild King's Rock or Dragon Scale without end. Only 2% of wild Poliwhirl, Slowpoke and Seadra hold one, and replays of one Silver run spent about a third of their frames hunting carriers that held nothing. A carrier hunt now sets itself aside for a while once its time runs out, and other work comes first. The time allowed is three times the battles the item is expected to take on that spot, and at most two game hours. A carrier met with the item is still caught at any time.

- Run the League again only once every other postgame project is done. Blue spent 46% of its frames on rematches with its money at the 999,999 cap, and Gold spent 28% even with Pokédex, shiny and training work left. Pokédex entries, legendaries, shiny hunts, better-DV hunts and training now come first in all six games. A rematch runs when money is short or nothing else is left, so a finished run still keeps playing.

- Stop Crystal turning back to a Pokémon Center again and again on the walk to the Battle Tower. Plain wild battles on the way to Olivine were fought, so the team kept needing to heal, and replays of one Crystal run spent about a third of their frames on that walk. The walk now runs from plain wild battles the way a shiny search does. A shiny or a wanted Pokémon is still caught.
- Offer Fair wild DVs on the New adventure form for Red, Blue and Yellow. It is off by default and can now be turned on or off in adventure Settings while the adventure runs, from the next wild encounter. The randomizer is still chosen only when creating an adventure, and Settings now lists what it shuffles and its seed.

- Keep Gold, Silver and Crystal running after an unexpected error. One error anywhere in the loop used to stop the adventure until it was restarted. The error is now logged and the next step goes ahead, the same way Red, Blue and Yellow recover. The adventure stops only after ten errors in a row, or when a committed gift needs a restart to recover.

- Stop Gold, Silver and Crystal pacing Route 29 "while Lapras waits for Friday" when every box is full and nothing can be released. The Lapras, the Bug-Catching Contest and the timed wild Pokémon all end in a catch that could not be kept, and naming the wait also held back the postgame League run. Replays of one Gold run spent 98% of their frames on that walk. Those waits now count only while a catch has somewhere to go.

- Stop Gold, Silver and Crystal retrying "Give Exp. Share" without end when the bag is full. The partner in training held a Pearl, and the game refuses the swap when the items pocket has no free entry for it, so replays of one Gold run spent over half their frames on that retry. The run now stores the cheapest item no plan uses in the PC, or tosses it if the PC is full, and then makes the swap. Medicine, evolution items and held items for training stay, and Nuggets and Pearls go last since they sell for money. The same applies to taking back an Everstone or a held item before a time-of-day evolution. When nothing can go, the partner trains in the lead as it does without an Exp. Share. An item task the game refuses three times also sets the training aside for a while.

- Fix Red, Blue and Yellow giving up on Articuno, Zapdos and Moltres with "Need money or bag space for legendary capture supplies" while holding plenty of money. A bag of 20 key items and supplies left no slot for Ultra Balls and nothing the shop would sell. When the bag is nearly full the shop now also sells repels weaker than the best one held, and keeps the best one.

- Show a stopped adventure read only instead of the "not running" page. Every panel loads from the newest save, and the screen shows the last frame greyed out under a Stopped label. Nothing runs or is written, controls are hidden, and the view closes after five idle minutes or when the adventure starts.

- Stop Gold, Silver and Crystal pacing Goldenrod City while the Day Care makes an egg. One Gold run spent about a fifth of each day there while it bred spare copies. The Day Care counts the steps of any walk, so the run now trains, hunts, collects stones or does postgame work in that time and goes back only to collect the egg or swap a parent. The Goldenrod walk is left only for when nothing else is useful.

- Fix saving on Windows failing with "Access is denied" when another process was reading the same file. Windows refuses to replace an open file, so the save now retries for up to about a second before giving up.

- Stop Red, Blue and Yellow walking into the Cycling Road gates without a Bicycle. The guards at the Route 16 and Route 18 gates turn back anyone who has no Bicycle in the bag, but the route planner did not know, so a run without one paced the Route 18 gate on its way to Route 16 Gate 2F until the explore project gave up. Without a Bicycle the run now treats those tiles as closed and goes another way or explores something else.

- Add randomized adventures for all six games. New adventure can shuffle wild Pokémon and starters, and trainer parties if chosen, from a seed. Each run gets a share code such as `PSR1-RED-WS-12345` that recreates the same world, shown on the Live page with a copy button. The cartridge is patched in memory only, and the planner follows the shuffled tables. Fishing, gifts, in-game trades and fixed encounters are not shuffled.
- Require Core 0.9.0, which adds the randomizer and is now published as `pokecore`. The installers and `uv sync` remove the old `pokesim-core` package. With pip, run `pip uninstall pokesim-core` before upgrading.

- Pick the sound buffer automatically and remove the Audio mode select. Watching keeps about one second of sound and delays the live screen by the same amount. Take Control drops to about 0.1 seconds with no screen delay, and handing back grows the buffer again without a silence.

- Fix live sound going quiet for a second or more. Gold, Silver and Crystal still told the page the measured speed, so a catch-up burst read above 4.5x and its sound was cut, and the page then cleared its queue and waited a full second. They now report the speed setting like Red, Blue and Yellow, and a hole in the audio no longer clears what is queued. After a dropout sound now resumes after 0.4 seconds instead of a full second and the buffer refills by playing up to 4% slow.

## 0.5.3

- Fix Red, Blue and Yellow workers still growing after many Time Capsule trades ([#111](https://github.com/afk-sapien/PokeSim/issues/111)). Each trade with Gold, Silver or Crystal loads a fresh copy of the Gen II data, and two lookups cached their results by that copy, so every copy stayed in memory. Red held about 24 copies, about 1.8 million lists, after a day of trading. The lookups now keep their results on the copy itself, and Red's worker stays near 19,000 lists.

- Fix browser sound jumping in pitch or cutting out. The page was told the speed measured over the last second, so after a short stall the catch-up burst read as 7x and the next second as 2x. The page now hears the speed setting, or 1x when playing by hand, and smooths the bursts itself. Sound cut because the speed is too fast to hear now counts as dropped audio.

- Fix a Gold, Silver or Crystal adventure stuck for hours with "no route" to every goal after its cartridge reset. The title menu had read the save, so the game looked started on its last map, but no map was loaded and every tile read as a wall. A started game with no loaded map now presses through to Continue. Repeated failures of one goal now also add up toward a reload, which they did not before.

- Fix Red, Blue and Yellow trades failing with "The selected Pokémon cannot be identified uniquely". The trade offered the spare the game was about to release at the PC, so the Pokémon was gone a few seconds later. That spare is no longer offered.

- Fix automatic trades failing over and over when a game's party cannot make room. Each attempt picked a different boxed Pokémon and failed with "No safe unprotected reserve", or "The party has no safe reserve to deposit" in Gold, Silver and Crystal. Like a full PC, that failure now pauses automatic trades for the whole game.

- Add floating image tags ([#115](https://github.com/afk-sapien/PokeSim/issues/115)). Each release moves `latest` to the newest stable release and `0.5` to the newest release of the 0.5 line, so automatic updaters can follow releases.

## 0.5.2

- Update Pillow to 13.0.0 for its security fixes, through Core 0.7.1, which allows it. Nothing else in Core changes.

- Fix Red, Blue and Yellow workers growing to about 900 MiB over a day of play ([#111](https://github.com/afk-sapien/PokeSim/issues/111)). Every autosave rebuilt the learned map as about 300,000 small lists, twice, and each trade and reward check parsed it again, which fragmented memory faster than it was returned. The map is now saved as two flat lists of numbers, which cuts the peak during a save from about 31 MiB to 6 MiB. Older saves still load. A save written by this version starts a fresh map if it is opened by an older one.

- Fix automatic trades failing over and over when one game's PC is full. The wait after repeated failures counted each Pokémon separately, and Blue offered a different Pokémon each time, so new trades kept being planned and kept failing. A repeated full-PC failure now pauses automatic trades for that whole game until it completes a trade.

- Add `POKESIM_MEMORY_REPORT_MINUTES`, off by default. When set, each adventure writes a memory summary to its worker log at that interval.

- Fix Gold, Silver and Crystal adventures stuck in the Route 36 National Park Gate with "no route" to every goal. The officer's corner behind the counter opens only onto the warp carpets by the National Park door, and route planning treated those carpets as walls, so a trainer who stepped into the corner after a Bug-Catching Contest found no way out, and trades failed with "No reachable Pokémon Center for this offer". Route planning now walks over warp carpets and only warps from one when walking off it the warp's way, and in the stuck save the trainer walked out and went back to training.

- Fix Gold, Silver and Crystal League runs reloading the League entry save again and again at Koga. When only a level 100 Ditto was left standing, the trainer saw a battle that could never end because Transform does no damage, so it restarted the attempt before Ditto could copy the foe. A Ditto with Transform left, or one already Transformed, now plays the battle out, and in the stuck save it beat Koga. After three restarts of the same attempt without a new League win, the run is now treated as lost, so the team leaves to train before trying again.

- Add **Fair wild DVs**, an optional Red, Blue and Yellow adventure setting that is off by default. The cartridge never gives a grass or cave Pokémon shiny or perfect DVs. With the setting on, each wild encounter gets fully random DVs, while trainer, cable and Transform battles keep theirs. With it off, Statistics notes the cartridge limit.

- Bring the Route 12 Snorlax back in Red, Blue and Yellow. After becoming Champion and battling the original Snorlax, every 100,000 steps it blocks the road again, set by the same setting as gift and trade returns. The trainer walks to it with the Poké Flute, wakes it and battles it. A battle that ends without a catch waits for the trainer to leave Route 12 before Snorlax returns, so the road stays clear in the meantime. A missing Snorlax is a new Pokédex entry and goes before repeat work.

- Fix Gold, Silver and Crystal Time Capsule trades stalling at the Pokémon Center PC until "The trainer did not reach the Cable Club before the preparation deadline". When the lead had fainted and the only other party member could not enter the Time Capsule, the game refused to deposit that last Pokémon able to battle, so the PC opened and closed for the whole preparation while the partner waited at the Cable Club. The trainer now walks to the nurse first, then deposits it at the nearest PC from there. A full party also skips a reserve whose deposit the game would refuse.

- Fix the Live page totals overlapping between phone and desktop widths. From 641 to 1099 pixels the badges, registered count, areas, League wins, money and play hours were squeezed into one row, so Gen II's sixteen badges ran into the registered count and play hours were cut off. The badges now take their own row with the five readings beneath.

- Fix Red, Blue and Yellow trades failing with "The PC could not withdraw for this trade: Menu did not respond". A nickname received in a cable trade carried a text command, so the PC box list stalled on that name while scrolling and never reached the Pokémon stored after it. Red offered Muk, Kabutops and others from behind such a name in Box 11, and each trade travelled to the PC only to fail. Those Pokémon are no longer offered, and a trade that picks one stops before travelling with a reason.

- Fix trade failures that did not say which game held them up. When one side never reached the Cable Club, the reason now names that adventure. A Gold, Silver or Crystal trainer that missed its preparation deadline now reads as taking too long to reach the Cable Club, and a paused or manually controlled adventure is named as the reason, instead of both reading "could not finish safely".

## 0.5.1

- Keep counting Gold, Silver and Crystal League wins past 200. The cartridge stops recording Hall of Fame entries at 200, so a finished run kept challenging the League for a victory that never arrived, earned no rewards and raised "Stuck? N game hours without progress" every six hours. A win from Lance's Room into the Hall of Fame now counts once the cartridge stops, and each League win counts as progress.

- Let a Pikachu traded into Yellow go to the PC. Only the starter, a Pikachu with the player's own trainer ID, stays in the party, as on the cartridge. A party of field-move holders with a traded Pikachu had no one to deposit, so every trade into Yellow failed with "could not safely make room in its party".

## 0.5.0

- Remove the generic "Stuck? No progress for a while" warning from Library cards.

- Let encounter maps finish loading before abandoning a Gen II postgame hunt. An outing no longer ends immediately when a map transition briefly leaves its encounter tiles unavailable.

- Train a Gen II partner to level 12 before challenging Falkner, so an underlevelled team does not repeatedly lose without earning experience. Respect scripted escape restrictions when an uncatchable shiny appears, including red Gyarados, instead of choosing Run forever.

- Fix finished Gold, Silver and Crystal adventures walking the Route 29 grass forever with "Walk the grass until a trade or a return brings new collection work". A Gen II run only went back to the League when it was short of money or stock, so once every Pokémon was registered and the party reached level 100 nothing else was left. With no collection, training or clock-gated work and the Champion beaten, it now challenges the Elite Four again and records another Hall of Fame entry, then starts the next run, the way a finished Red, Blue or Yellow adventure loops the League. A League run that has started finishes before new work. Carried eggs and a clock wait such as Lapras's Friday still keep the walk.

- Give finished Gold, Silver and Crystal adventures the postgame of Red, Blue and Yellow. Once the collection work runs out, the adventure rotates between four activities instead of only looping the League. It hunts better-DV copies of an owned species whose best copy has ordinary DVs, catching up to three copies per hunt and at most three hunts per species, and the boxes keep the best copy. It trains the best copy of a species ten levels at a time at Mt. Silver, skipping a species whose level 100 copy is already as strong. Each shiny-hunting outing checks up to 100 wild encounters on one grass map, running from ordinary battles. It finishes the current battle, then gives two other activities a turn before another outing. An hour of simulated gameplay, including travel, is a fallback limit when encounters are scarce. Pausing or changing playback speed does not change these limits. A stronger boxed copy stays safe even when a weaker copy of its species is in the party, and both Special stats count when comparing copies. And it challenges the Elite Four again. Better-DV hunts and training weigh most and the League least, and no activity is picked three times in a row. Pokédex, trade, breeding and clock-gated work still go first, and a wild shiny met at any time is still caught.

- Show shiny Pokémon in their shiny colours in Gold, Silver and Crystal. The Live party, the PC, a Pokédex copy's popup, the Trading pages and view links now draw a shiny partner with the cartridge's own shiny palette, served from `sprites/shiny/<dex>.png`. Shiny portraits are extracted with the normal ones when an adventure starts, and drawn on first request for a library extracted before this version. A hand-installed image in an adventure's `sprites/shiny` folder wins. The community sprite pack has no shiny images, so a shiny partner shows the cartridge portrait. Pokédex species cards keep the normal colours. Red, Blue and Yellow have no shiny palettes and are unchanged.

- Move to hash-pinned PokeSim Core 0.7.0 and drop PokeSim's own copies of the Gen II code Core now owns: the memory map and RAM decoder, clock, snapshot and save handling, hooks and resets, ice and Ruins puzzles, breeding, portraits, screens, Battle Power, NPC trade and prize tables, the Time Capsule rules, and the Gen I and Gen II cable drivers, as well as the Gen I sprites, save export, Pokémon Center checks, text matching and DV checks. Gameplay policies, navigation and the adventure's clock memory stay in PokeSim. A failed save export now says "No save was produced" in every game.

- Move to PyBoy RS 0.1.2. A Gold, Silver or Crystal write to a clock register now sets exactly that counter, the halt bit stops the clock, and loading a save state rebuilds the clock latch from the loaded clock, so loads are deterministic. Saves and checkpoints from 0.1.1 still load. This fixes the clock of an adventure that reaches day 140, where the game takes 140 days off its clock: 0.1.1 turned that write into a clock racing ahead by minutes every frame. Adventures now remember the clock's latest reading instead of the largest one, so a restart after such a write resumes at the game's time instead of going back to the moment of the write. The wheels, the lock and the image's emulator source archive all point at the 0.1.2 release.

- Keep Never trade locks when rolling back to 0.4.20 without restoring a backup. The upgrade moved each lock to the new trade key and deleted the old one, which is the only one 0.4.20 reads, so after a rollback a locked Pokémon could be traded or released as a duplicate. The old row now stays as a copy that follows every lock and unlock, and a lock set in 0.4.20 after a rollback is kept when upgrading again.

- Catch shiny wild Pokémon in Gold, Silver and Crystal. A shiny wild opponent is always a catch, even when the species is registered or money and balls are low: the adventure weakens it without a knockout, uses status moves and its best balls, keeps a Master Ball as the last resort unless a roaming beast, Lugia, Ho-Oh or Crystal's Suicune is still to catch, and never runs from it or knocks it out. A shiny in the Bug-Catching Contest is kept over any prize, taken straight to the judges and counted as acquired. A transformed Ditto is judged by its own DVs, and trainer Pokémon are never targets. Shiny wild encounters and catches are now counted, so Stats shows shinies seen and acquired for Gen II and the First shiny acquired milestone can unlock. A shiny that hatches from an Egg, the Odd Egg included, and a shiny received in a PokeSim trade also count as acquired, once and only on the receiving side; no in-game trade in Gold, Silver or Crystal gives a shiny. The Gen II Pokédex marks species with a shiny acquired or held, as in Gen I, and adds a ★ Shiny seen marker for species seen shiny in the wild but not acquired. Counting starts when an adventure first runs this version.

- Fix Gold, Silver and Crystal knocking out a wild shiny it could not catch. With a full PC, no balls, or only a Master Ball kept for a legendary, the adventure fought the shiny as it would any other opponent. It now runs, as Red, Blue and Yellow do, and the journal and notifications record "Shiny <species> could not be caught: no storage space", "no balls" or "only the Master Ball, kept for a legendary", once per battle at low priority. A failed escape tries again next turn. Only a trap that forbids running, such as Mean Look, leaves the turn to be fought. The Bug-Catching Contest keeps its own Park Ball rules.

- Fix the party popup on the Live page missing the stats table, Stat Power with its level 100 ceiling, Battle Power and the DV rating. It drew from the Live party record, which lacked them, until the PC record arrived, and kept that record if the request was slow or failed. The Live party now carries the same fields, built by the same code as the PC, for Gen I and Gen II.

- Port the TM shop and Champion shop to Gold, Silver and Crystal under **Extra store items**. After the Hall of Fame the Goldenrod 5F clerks also sell the 34 one-time TMs (₽50,000, ₽25,000 or ₽10,000 by tier, as in Red and Blue), and the 4F clerk sells a Master Ball (₽100,000) and five Rare Candies (₽25,000), each once per 1,000,000 steps, plus Elixir, Max Elixir, Leftovers and Lucky Egg. The adventure buys a TM only for a real level-100 Battle Power gain on a level 50+ partner and teaches it at once, uses Rare Candies on the partner they were bought for, gives a held item to a partner with empty hands, keeps ₽20,000 in reserve, and uses Elixirs in the League when an attacking move is out of PP. Prices above ₽65,535 are charged in full through a hook on the cartridge subtotal; the cartridge is unchanged. Stats → Items shows the Gen II walking offers. PP Up is priced but not bought yet, because the Core item shortcut does not recognise the Gen II move list.

- Split each game's Trading page into a Make a trade tab and a History tab under the Auto trading switch. The tab is kept in the address as `#make` or `#history`; a Trade… link from the PC opens Make a trade, and a trade completed notification opens History.
- Add an **Extra store items** setting for Gold, Silver and Crystal, on by default for new adventures. The Goldenrod Dept. Store 4F clerk also sells the six evolution stones for 2100 each, and the 3F clerk sells King’s Rock, Metal Coat, Dragon Scale and Up-Grade, so a spent one-time item no longer blocks a Pokédex entry in Gold or Silver. The cartridge is unchanged: the items are added to the opened BUY list in memory. An adventure buys one only for a missing, prerequisite or requested evolution that the bag, an unused one-time item, a Crystal phone trainer or a linked peer's trade cannot cover, runs the League first when it is short of money, and stands down after a purchase that does not land. With the setting off the store keeps its normal stock.

- Give Gold, Silver and Crystal adventures repeatable evolution stones once the one-time stones are spent, so a missing Pokédex entry or a peer's request can still be evolved. In Crystal the adventure registers Picnicker Gina (Leaf Stone), Schoolboy Alan (Fire Stone), Lass Dana (Thunderstone) or Fisher Tully (Water Stone), waits by a Pokémon Center phone for the call, and collects the stone the same day. Every game also visits Mt. Moon Square on Monday night for the Moon Stone the Clefairy uncover, and enters the Bug-Catching Contest for a Sun Stone a peer needs. Gold and Silver phone trainers never give items, so those games still have no second Leaf, Fire, Water or Thunder Stone. A source that cannot progress, such as a full phone list or a call that never comes, stands down for a while instead of looping.

- Trading page trimmed to the essentials; wishlist removed.

- Make each game's Trading page one page. The Auto tab is gone: the automatic trading switch sits at the top, then Make a trade and History follow. Lock a Pokémon on the PC page instead: press it and press **Locked: never traded** in its popup. Every Pokémon can be traded automatically unless it is locked, and a locked one has a lock icon in the PC grid and the party. Locks are the old Never trade setting, so existing choices carry over. The Library loses its Trading tab and keeps Library, Notifications and Settings. `/trading` and `/trade` now redirect to the library, and a trade notification opens the first game's Trading page.

- Fix Crystal adventures stuck in Battle Tower 1F with "A conversation in Battle Tower 1F made no progress" logged every two seconds. The Tower team was chosen for level 20 at levels 16 to 18, and Silver Cave training toward level 20 took two partners to 21 in one battle, so the receptionist answered "A party POKéMON tops this level." and asked for the level again, forever. A partner that outgrows the chosen level now cancels the challenge at the level question, the adventure team is restored, and that level backs off like a lost challenge. The next challenge is chosen from the partners' current levels.

- Fix Red, Blue and Yellow adventures standing at a Pokémon Center PC on "Make room in storage" until the stall alert. A Pokémon received in a cable trade had a text command in its nickname, so the PC box list stopped drawing at that name and the release menu could never reach the spare chosen behind it. The same release failed every minute for hours. Spares stored after such a name are no longer chosen, and a release that fails lets the next spare go first. Releasing about once per new catch, League reward or trade is expected while every box is nearly full.

- Stop Gold, Silver and Crystal adventures putting duplicate eggs ahead of training. Gold kept 28 Sneasel eggs in the PC from an old breeding loop and fetched them one at a time, so Crobat waited in the PC for days of game time. A trip to the PC now brings only eggs that would add something: a species not yet registered, or a copy another adventure asks for by cable. Other eggs stay safe in the PC, and one already in the party may go back to make room for the next Pokémon in training.

- Stop Gold, Silver and Crystal adventures reporting "Stuck? 6 game hours without progress" while walking eggs from the PC to hatching. A level 100 party earns no experience and a hatchling of a registered species adds nothing new, so a box of slow eggs such as Sneasel tripped the stall alert and asked for help every few eggs. Every egg cycle walked off and every hatching now counts as progress, once each, so a reload back to an older save does not.

- Keep the original Bench Instrument look: the putty panel, near-black dark theme, rust and orange accent, uppercase pixel-face labels, tabs and keys, the plain journal list and full open party bays. A short-lived Game Boy Color restyle (grey shell, slate bezel, berry keys, bundled Inter) is gone, and sentences use the system font again, so the app bundles only its own pixel face. Newer parts, such as the Trading tabs and the lock toggle in the PC popup, use the same look. The top bar ends in one clean line that the tabs sit on. Separator dots and arrow marks on links are gone (slots read "Box 1, slot 2" and versions read "v0.5.0 (abc1234)").

- Ask before rewinding the live game. The rewind key on a journal entry now opens a question that names the play time it goes back to and how much play would be lost, with Keep playing as the default. Nothing is sent until Rewind and lose progress is chosen.

- Give each library card one main key and a settings key. Stop, Details, Download save, Archive and Delete now sit in a More menu that works from the keyboard (arrow keys move, Esc closes). The status chip says Trading, Manual control or Paused instead of Running when the game is held, and every card key and backup key names its adventure or date for screen readers.

- Fit every page on a 390 pixel phone without sideways scrolling. The adventure tabs scroll inside their own strip and keep full names, the Stats figures no longer overlap, and the toast and Pokédex detail respect the notch and home bar. Popups no longer scroll the page behind them.

- Show the Pokémon on journal entries for catches, gifts, hatches, evolutions and level-ups, using its sprite instead of a cutscene screenshot. Journal and live page labels are plain words ("Caught", "Party", "Plan", "Now", "Next"), and the live page no longer repeats the plan title under it.

- Fix the Stats page saying shinies are "Not tracked" next to a shiny in the PC. When arrivals were not counted it now shows the shinies held, with a note saying why.

- Keep keyboard focus clear of the sticky header, label the Pokédex move list for keyboard and screen reader users, show text while the fonts load, and lay out Pokédex and PC sprites in one pass.

- Fix Gold, Silver and Crystal adventures stalling on "Train … toward level 100 in the lead" with the Pokémon in training never leaving the back of the party. A roaming-beast search that was put off for later still kept its sleeper in the lead, so the trainee joined no battles, earned nothing, and the adventure reloaded every half hour. The training walk now leads with the trainee, and the sleeper leads again when the search resumes.

- Fix a Red, Blue or Yellow Pokémon being sent to Gold, Silver or Crystal every few minutes when the Time Capsule always refuses it. A Pokémon whose saved types do not match its species (the game says it "appears to be abnormal" and cancels the trade) is now left out of Time Capsule trades with that reason, a session stops as soon as the game shows the message instead of pressing on for half a minute, and automatic trading leaves out any Pokémon whose last two trades failed the same way for 30 minutes, doubling up to a day.

- Keep training Gold, Silver and Crystal Pokémon after the Exp. Share is gone. Each cartridge has only one, and Crystal and Silver lost theirs to earlier automatic trades, so Silver spent almost all its time walking the grass with nothing to do. The Pokémon in training now leads the party and switches out on the first turn of a battle it would lose, which still shares the experience with it.

- Open any Pokémon listed under "With you right now" on a Pokédex entry. Each one is now a key that shows its full record in the same popup the PC uses, on top of the Pokédex, and Esc or Close returns to the entry where it was. The popup has a Show in PC key that opens its box, or the party, with the Pokémon marked and its popup open. The PC also opens one slot from its address, such as `/pc?box=12&slot=4`.

- Make Gold, Silver and Crystal adventures wait for the cartridge clock less. Breeding, hatching and evolving now go ahead of a weekday or time-of-day wait, and labels name what is waited for ("Bring eggs from storage to hatch while Lapras waits for Friday"). A levelling plan left without the Exp. Share no longer keeps stored eggs from hatching, stone and trade evolutions run without it, breeding raises its Day Care money first, and the Exp. Share holder is never released or traded.

- Redesign the Pokémon detail popup on the PC and Trading pages. A head with the portrait, name, one line of facts and one row of same-height stamps (Healthy is no longer stamped), then one strip of equal cells for HP, XP, Stat Power and Battle Power, then Moves and Stats as two cards of equal height, stacked on a phone. Each move reads as two lines, name and type, then kind, power, accuracy and PP, with blank slots up to four, so a phone no longer shows a broken table header. The pixel face is kept for the name and the keys, numbers use tabular mono, and the footer keys stay in one row on a phone with shorter labels.

- Fix Gold, Silver and Crystal adventures standing at a Pokémon Center PC for hours on "Bring the breeding partner from storage". With a full party of field move holders and eggs brought out to hatch, the PC had nothing it could take, so the errand pressed B in front of it forever. The party now walks until an egg hatches and then swaps the new Pokémon for the parent. Fetching the Day Care man's partner while an egg waits also collects the egg first, since he stands outside on Route 34 until then.

- Run the Gold, Silver and Crystal cartridge clock on game time instead of wall time, and show the in-game day, time and period (such as TUE 08:14 MORNING) beside the place name on Live. The clock moves with emulated frames, about 5.16 million frames to an in-game day, so at Max a wait for a weekday or night passes in under an hour instead of a real day. It never runs backward across restarts, crashes, save reloads, trades and backups, each side of a trade keeps its own clock, and existing saves start from their current reading. The state API reports it as `clock` with `weekday`, `hour`, `minute` and `period`.

- Queue hand-built trades with a game that is busy trading instead of refusing them. Under Trade with, a busy game stays pickable and shows its Pokémon, from the last known PC when needed, with "Busy with a trade. Your trade will wait in line." Queued trades run in order once the game is free, and a waiting hand-built trade goes before new automatic trades for its two adventures. When its turn comes both Pokémon are checked again, and a trade whose Pokémon has gone ends with a reason such as "Cancelled: Pikachu is no longer in Red’s party or boxes" without touching either save. A waiting trade has a Cancel trade key on its adventure's Trading page, through `POST /api/v1/interactions/trade-builder/<id>/cancel`. A trade that has started can no longer be cancelled.

- Lay out every Settings panel in one full-width column. Nicknames, Backups, Import and Close PokeSim no longer sit two to a row; each shows its explanation on the left and its keys on the right, stacked on a phone, and every Settings key is the same height and size.

- Draw the first 40 cards of the PC's All Pokémon view and the Pokédex at once and the rest over the next frames, so a full PC of about 280 cards no longer holds up the first paint.

- Show grey placeholder cards on the PC and Pokédex while their first data loads, instead of a blank area under the page frame.

- Show the PC and Pokédex as last seen the moment they reload, then swap in fresh data as soon as it arrives. Each adventure keeps the last PC and Pokédex it drew in the browser's IndexedDB, the connection label reads Updating… until the server answers, and the PC's Trade… key waits for fresh data. A browser that blocks or fills its storage simply waits as before.

- Keep Pokémon portraits in the browser for a year instead of downloading about 280 of them again on every PC or Pokédex reload. Each adventure's pages stamp portrait addresses with a fingerprint of the artwork it shows, which changes when the community pack is installed or restored, cartridge portraits are extracted, or a hand-installed portrait is added or replaced, so new artwork still shows at once.

- Speed up the PC, Pokédex and Trading pages. Their live status is written with the standard JSON encoder instead of FastAPI's per-value one, which took about ten times as long on a full PC, and the PC and Trading pages no longer build the Gen II Pokédex plan they never show. The species reference behind the Pokédex is built once per adventure and carries an ETag, so a browser that already has it gets a 304 instead of 650 KB of JSON. A Gen II adventure answers it without first reading the game's status.

- Move Copy view link from under the live game controls into the top bar, as a small link key beside the connection status that shows "Copied" for a moment. The controls stay one row. The top bar now gives the tabs their own row below 1280 pixels instead of clipping them. Tidy the PC detail popup's spacing: type and status tags share one row, the head lines up with the body, every type fits the moves table, the stats table no longer wraps on a phone, and the Stats guide, Pokédex and Trade… keys share one footer row at one size. Smaller fixes: the trade builder's swap chip is level with the slots, recent trades on the library Trading page no longer break names mid-word, Settings sections have even gaps, cartridge details line up, the Hide item icons key keeps its own width, and footnotes on the Stats page no longer touch the panel above.

- Fix Crystal adventures reloading every few minutes on Route 22 with "Stuck? The adventure had to reload twice". Halfway over a ledge the game reports the player on the blocked tile it hops across, so a Tower trip from Kanto saw no walking route to Olivine for that moment, flew back to Viridian City, walked to the same ledge and flew again until 30 game minutes passed without progress. Fly is no longer chosen during a ledge hop. A Tower trip also counts the PC slots its swaps need before it sets off: a party of six with one free slot used to travel to Olivine, fill the boxes, stand down and start the same trip again after the wait. It now keeps to its other activities until the boxes have room.

- Fix Gold, Silver and Crystal adventures filling their PC with eggs that never hatch. An egg only hatches in the party, but a full party sent its lowest level member to the PC, which was the new egg, and Day Care breeding only counted eggs in the party, so it collected another one. A Gold adventure stored 54 Sneasel eggs this way. Breeding now skips any line with an unhatched egg in the party or the PC, PC errands keep eggs in the party, and once the party carries none the adventure brings up to three stored eggs into the party to hatch on the walks of its other errands. One egg at a time takes the place of a spare partner, and a trainee or Exp. Share swap that would otherwise store the only holder of a field move waits while training walks the egg to hatching.

- Simplify trading to two kinds: automatic trades, which start on their own, and trades you build by hand between your own adventures. Trade offers and manual Cable Club sessions are switched off for now, and so is the Ask me first approval from the release candidates. The Trading page has Trade, Auto and History tabs, and Trade queues the trade at once and opens History. A view-only adventure is a greyed-out choice under Trade with, with the reason. Waiting and running trades show under Current exchange on both adventures' pages. The trade builder's API is `/api/v1/interactions/trade-builder`. The `/api/v1/interactions/trade-offers` and `/api/v1/interactions/cable-sessions` routes, the `/games/<id>/cable` page and the `/api/v1/interactions/trade-requests` routes now return 404. Offers and sessions saved by an earlier build stay in the database and are ignored, as are a stored Ask me first setting and waiting suggestions, and a session left running is still rolled back at startup.

- Rename the trade settings to Can trade, Prefer to trade and Never trade, each with a one-line hint, and say everywhere that shiny and perfect DV Pokémon are always protected. Stored values are unchanged.

- Redesign the Trade tab as a trade builder. Pick a game under Trade with, then fill the You send and You get slots. Each slot opens a picker with the PC's search, filters and sort, which scrolls inside itself, closes with Escape and fills a phone screen. A picked Pokémon becomes a compact card that opens its details. Trade works only once both slots are filled and the pair is allowed, and the reason shows when it is not, such as a twin or a protected Pokémon.

- Fix hand-picked and automatic trades failing with "An adventure needs a free PC slot to prepare its Pokémon for this trade" when a Gen II game held six in the party and 280 in the PC. Preparation gave up once every box was full, and the release rules kept every duplicate holding an item, which in Gold left nothing to let go. Preparation now releases one spare duplicate at the PC through the ordinary menus, weakest first and only when nothing safer is spare, and logs "Released <name> (<species> Lv N) to make room for a trade". It never releases an egg, a shiny, perfect or rare-DV Pokémon, one set to Never trade, one hand-picked for a pending trade, a wished species or the last copy of a species. A game with a releasable spare is no longer left out of automatic trades or greyed out for hand-picked ones. When nothing is safe to release, the failure names the game, such as "Chaotic Escape (Gold) has a full PC and no spare duplicate it can safely release".

- Tidy the PC detail popup so it fits one desktop screen. It now has two columns, with HP, XP, Stat Power, Battle Power and moves on the left and the full stats on the right. Stat Power reads as now against its level 100 ceiling, such as "312 / 480", or one number marked (max). Moves line up as a compact table of type, kind, power, accuracy and PP. Original trainer, Elite Four wins, friendship, catch data and the trade block are gone, and the trade setting and Pokérus are small tags under the name. The Trading page shows the same popup. The Boxes and All Pokémon switch moves from the PC's stats row into its filter bar, where it no longer wraps on a phone.

- Fix Crystal adventures stuck inside with "no route to Travel to Olivine before preparing the Tower team from Cherrygrove Pokémon Center 1F" logged about 45 times a minute. Fly only works on town and route maps, so inside a Pokémon Center, a cave or a gate with Route 36 blocked again, the adventure saw neither a walking route nor Fly and gave up over and over. It now walks out to the nearest town or route it can reach and flies from there. A Tower trip also no longer starts, or carries on to Olivine, while six Pokémon are in the party and every PC box is full with nothing spare to release, since the team could not be put together there. The adventure keeps to its other activities and tries again later.

- Fix Crystal adventures stuck on Route 46 with "no route to Travel to Olivine before preparing the Tower team" logged about once a second. A returned Sudowoodo stood on Route 36 again, which cuts every walking route from Route 29 to Ecruteak and Olivine, and Fly was only considered as a shortcut for a route that could be walked, so the adventure wandered between Route 46 and Route 29 and gave up over and over. When no walking route exists, the adventure now flies to a visited town it can walk on from, here Olivine.

- Fix automatic trades failing over and over with "An adventure needs a free PC slot to prepare its Pokémon for this trade". A Gold and a Silver adventure each held six Pokémon in the party and 280 in the PC with nothing they could release, so preparation could not deposit anyone to withdraw the boxed offer. They were still proposed, and over 100 trades with Crystal, Yellow and Blue failed this way. An adventure whose party and every PC box are full, with no spare to release, now offers nothing for automatic trades until it has room, and its boxed Pokémon are greyed out for hand-picked trades with the reason shown. Party Pokémon can still be hand-picked. The banner now names the game that is short of space, such as "Chaotic Escape (Gold) needs a free PC slot", and says that game is left out of automatic trades until its PC has room.

- Rebuild the Trading page around the PC's Pokémon cards. The Trade tab now picks your Pokémon, then the other adventure, then their Pokémon from grids with the PC's search, DV rating, sort and order controls, plus a trade setting filter. A Pokémon the cable cannot take stays in the grid greyed out, and hovering or tapping it shows why. Tapping a card opens the PC's detail popup with a button to choose it, and a chosen Pokémon folds into one card with a Change button. Each card carries a stamp for its trade setting. The Auto tab shows the same cards and changes a setting from the detail popup. History uses the same plates, type stamps and status lamps. The old `/trading` page shares the same cards and filters. The PC page and the Trading page draw their cards from one shared script and stylesheet, and both fit a 390 pixel phone in light and dark themes.

- Fix Pokémon that could not be traded with "Another Pokémon has the same trainer and stats, so this one cannot be picked out safely". Neither generation stores a unique ID per Pokémon, and trades told Pokémon apart by trainer ID and DVs alone, so emulator reloads and Day Care breeding left different species with the same trainer and DVs blocked, such as 31 Pokémon in one Red adventure. A trade key now adds the Pokémon's evolution family, named by its lowest Pokédex number across both generations, so different species trade normally and a key stays the same through evolution and the Time Capsule. Only two Pokémon of the same family with the same trainer and DVs are still blocked, with the reason "Another Rattata from the same trainer has identical stats, so the game can't tell them apart". Trade settings saved under an old key move to the new one when exactly one Pokémon matches, and otherwise stay unassigned. Trades in progress with an old key still find their Pokémon by the same rule.

- Make a trade on the library page now links to each adventure's Trade tab, and the separate trade picker at `/trade` is retired. Old links to `/trade` go to the Trading page, and the admin API behind the picker is removed.

- Put everything about trading on the Trading page. Each adventure's Trading page now has Trade, Auto and History tabs. Trade picks one of this adventure's Pokémon, another adventure and the Pokémon you want back, with anything the cable cannot take greyed out and the reason shown, and Trade now starts it at once. History shows hand-picked and automatic trades together. A changed trade setting is confirmed under its own row instead of in a toast over the list. The PC no longer has lock badges or an offer banner. It shows each Pokémon's trade setting read only and a Trade… link that opens the Trade tab with that Pokémon chosen.

- Replace locks and trade offers for automatic trading with one trade setting per Pokémon: Auto decides, Trade first or Keep. Locked and withdrawn Pokémon become Keep and offered ones become Trade first, once, and the stored values stay readable by older releases. The Auto tab adds an on or off switch per adventure and a wish list of species to trade for, which ranks ahead of everything else. Automatic trading never moves a shiny, an active party member or a Pokémon already in a hand-picked trade or open offer, and keeps the last copy of a species unless the trade evolves it or fills a new Pokédex entry. Hand-picked trades ignore all of these and still go before automatic ones.

- Remove the bundled authenticated HTTPS proxy (`compose.proxy.yaml` and `deploy/proxy`). PokeSim has no built-in login, so for remote access put it behind your own reverse proxy with a login, Tailscale, or Cloudflare Access. If you use the bundled proxy, keep your existing compose files or switch to one of these before upgrading.

- Fix Gold, Silver and Crystal adventures reloading in the middle of Day Care breeding. An egg keeps its species, level and experience when it hatches, so walking eggs on Goldenrod's nursery stretch, or walking while a poorly matched pair took a long time to make an egg, changed nothing the watchdog counted. After 30 game minutes it logged "no progress for 30.0 game minutes" and reloaded an older save, throwing away the eggs hatched since, and the run went round between "Retrieve the Day Care partner" and "Walk with the eggs and the Day Care partners". Each egg cycle, each hatch and each step while a compatible pair waits for its egg now count as progress. All three end once the egg is made or hatched, so a walk that never gets there is still caught.

- Fix Gold, Silver and Crystal adventures freezing on the Pokémon Center 2F stairs after a cancelled trade preparation. A cancel could leave the player standing on the stairs, and standing there does not take them, so "Return downstairs after the Cable Club" pressed A until the screen watchdog warned "the screen has not changed for 1800 frames". The adventure now steps off the stairs and walks back onto them, which takes it downstairs.

- Fix Gold, Silver and Crystal adventures freezing at a Pokémon Center PC after a cancelled trade preparation. A preparation that began during a wild battle let the bot pick a move, and that move task outlived the battle. When the preparation was cancelled with the PC open, the move task took the PC text for battle text and waited, which also kept the bot from closing the PC, so the screen watchdog warned "the screen has not changed for 1800 frames" and pressed B to get out. Preparation now drops a battle task as soon as the battle is over.

- Fix Crystal adventures stuck at the Olivine Pokémon Center before a Battle Tower challenge. The Tower leads with its strongest partner, and when that partner was more than five levels below another one the general rule that puts the highest level first swapped it back, so the party was reordered back and forth between "Lead with the strongest Tower partner" and "Enter the Battle Tower challenge" until the run reported "no progress for 11.0 game hours". The level rule now leaves a prepared Tower team's lead alone, so the challenge is entered, and a challenge that falls short backs off as before.

- Fix Gold, Silver and Crystal adventures flagged as stalled while training. Progress counted only a new high of the party's total experience, so after a level 100 trainee was swapped for a fresh one, hours of training never counted and the run raised "no progress for 8.2 game hours" and asked for help. Experience now counts per Pokémon, so any trainee gaining experience is progress.

- Fix Gold, Silver and Crystal adventures freezing in front of a Pokémon Center PC with "BILL's PC accessed." on screen. With no menu task running, the bot pressed down to reach TURN OFF, but the message holds the cursor until it is dismissed, so nothing moved, the status read "opening" with no objective and every later autosave was taken in the same screen, so 12 reloads landed back in it. A message over the PC list is now dismissed with B before the list is navigated, the status reads "Close the PC", no autosave is taken while backing out of a screen no plan owns, and a reload prefers a save taken outside any menu.

- Stand down Gold, Silver and Crystal objectives that cannot progress instead of reloading into them. Battle Tower team assembly matches members copy for copy, withdraws before depositing, releases a spare when every box is full and stands down when a partner is gone. A refused rod, Headbutt or Rock Smash drops the hunt target. Training releases a spare or stands down when storage is full. A reload carries the stalled objective over into the restored run, so it does not walk back into the same trouble.

- Fix Gold, Silver and Crystal adventures stalling at a Pokémon Center PC once all 14 boxes are full. "Make room for Sudowoodo" or "Make room for the legendary encounter" walked to a PC with nowhere to put anything, then reloaded 12 times and stopped. When fewer than 5 box slots are free, the adventure now releases a spare duplicate at the PC, the most numerous species and its weakest copy first. Each species, and each Unown letter, keeps its best copy or as many as a plan needs. Party members, eggs, shiny, perfect and rare finds, Pokémon holding an item, trained partners, breeding parents, assembled teams and offered or locked trade partners are never released. If nothing can be spared, catch errands stand down instead of looping.

- Fix Gold, Silver and Crystal adventures reloading while they wait for a weekday, such as the Bug-Catching Contest. Standing still on purpose counted as stuck, so the adventure reloaded older saves, logged "stuck for 0s" and ended flagged as stalled. The wait now shows as Waiting and is never reloaded. Reloads now pick the save by game frame instead of file time, the log gives the stuck time in game minutes, and "reloads did not help" is logged once. Collection planning counts held Pokémon once per step instead of once per encounter, which cut each decision from about 146 ms to 11 ms with full boxes.

- Keep Gold, Silver and Crystal adventures busy while they wait for the cartridge clock. When the only objective left was a weekday or time-of-day event, such as the Bug-Catching Contest, the adventure stood on one tile of Route 29 for real hours and the screen watchdog warned that nothing had changed. It now walks the Route 29 grass and battles wild Pokémon, shown as "Train in the grass while waiting for …", heals when it needs to and goes to the event as soon as its window opens. A patrol that keeps moving is never reloaded for lack of progress, but one that stops moving is still treated as stuck. With six Pokémon in the party and every box full with nothing to release, training now uses only the party instead of walking to the PC for a boxed trainee or Exp. Share it cannot take out. A Battle Tower level that ends a challenge short of seven wins now rests before it is tried again, twice as long after each further loss, and other levels with a team are tried meanwhile. This stops the adventure from repeating a losing challenge as filler forever.

- Fix gaps in the PC detail popup and Pokédex. Red, Blue and Yellow boxed Pokémon now show their HP bar, status and move PP. Gold, Silver and Crystal Pokémon now always show their trade state, including those kept back and those listed while trading is paused. The Gold, Silver and Crystal Pokédex no longer flashes "/151" before the total loads. Evolution text names held items ("Trade holding Metal Coat"), and place names keep their apostrophes ("Diglett's Cave").

- Include the optional navigation acceleration in the Docker image, so Red, Blue and Yellow route searches are compiled on the server. The moves are the same as before. Repeated searches are faster and each adventure uses about 115 MB more memory. Set `POKESIM_NAVIGATION_BACKEND=python` to turn it off.

- Make the Victory Road and Seafoam boulder planner reuse its earlier walks after each push instead of searching every square again. The pushes are unchanged, and a search after a push takes 2 to 7 ms instead of up to 100 ms.

- Keep gift and static Pokémon coming in Gold, Silver and Crystal adventures through the Day Care. Families with no wild source in the cartridge, such as Bill's Eevee and the Eeveelutions, Togepi, Kiyo's Tyrogue and the Hitmons, Sudowoodo, Snorlax, Lapras and Pokémon that arrived by cable, now breed another copy whenever a linked adventure asks for any stage of them, and the copy is raised into Espeon, Umbreon or the requested Hitmon. The last Ditto and the last member of such a family are no longer offered for trade, so a parent always stays home, and a Ditto is caught again if none is held, even with a full Pokédex. Spare copies wait until the boxes have room. An Eevee one level from Espeon or Umbreon at the wrong time of day gives up its Exp. Share until the clock suits, and friendship estimates follow the cartridge's +5, +3 and +2 level up gains.

- Fix Gold, Silver and Crystal post-game adventures flipping between League funding and "Collect the Moon Stone in Tohjo Falls" after every Hall of Fame entry. When a Game Corner prize partner needs more money, the League run now starts in the same decision instead of showing one later goal first.

- Fix Red, Blue and Yellow adventures walking into the closed doors of the Cinnabar Gym. The map file draws every door open and the game shuts each one until its quiz trainer is beaten, so the route planner now treats a locked door as a wall and the Volcano goal faces the trainer of the first locked door before Blaine.

- Fix a Yellow Cable Club or Time Capsule trade offering the first Pokémon in the party instead of the agreed one. Yellow draws the trade menu quickly enough to take a held A as a choice, so no button is pressed until the menu cursor appears. Verification had already refused the wrong exchange, so no adventure kept it.

- Fix Gold, Silver and Crystal adventures stalling in a Poké Mart. After a purchase the shop menu task ended while the clerk's box was still up, so the bot pressed A through the clerk's menu again and again, ending with "You don't have enough money." and reloads that landed back in the loop. The buy task now keeps pressing B until the shop screen has been gone for several frames, never chooses or quantities an item the money cannot cover, and a conversation in which nothing changes for 80 decisions drops the shopping errand, backs out with B and is then reported as a failure.

- Fix Gold, Silver and Crystal adventures standing still beside a person who blocks the tile they chose, such as Amphy at the top of the Olivine Lighthouse. A blocked tile is no longer scored as already reached, the next open side is used, and an objective that stays unreachable is reported as stuck. `tools/play_gen2.py` no longer asks the emulator to run zero frames.

## 0.5.0

- Fix Gold, Silver and Crystal adventures stalling at a Pokémon Center PC after a trade sent away their only Waterfall, Whirlpool or Surf partner. With six Pokémon in the party, all 14 boxes full and nothing that could be released, "Prepare a place for a field move partner" tried to deposit a party member into a full box again and again until the run was flagged as stalled with "Manage Pokémon storage". The partner errand now waits until storage has room, and the adventure carries on with its other objectives. The watchdog also no longer picks a save from before a completed trade or custom reward, which it is not allowed to load: it spent every other reload on the refused save, swung between it and the trade checkpoint and gave up after 12 reloads. When every save predates the trade it keeps playing instead of power-cycling.
- Fix Gold, Silver and Crystal adventures reloading while they train in the Route 29 grass waiting for the cartridge clock. A reload rewinds the game frame counter, but the watchdog kept waiting for the old frame before it checked anything again, so after one reload the wait was never seen. The status read "Making progress" instead of "Waiting", and when the checks resumed in the middle of a wild battle the adventure logged "no progress for 30.0 game minutes" and reloaded again, round and round. The checks now restart from the restored frame. The wait also names the next contest day, such as "waiting for Thursday" after Tuesday's Bug-Catching Contest, instead of "tomorrow".
- Send each page only what it draws. The live page's state leaves out the boxed Pokémon (337 KB to 13 KB on a full Crystal save, `?storage=1` adds them back), the trading page's offers carry only names, places and trade controls (481 KB to 114 KB), and the PC and Pokédex ask for their own view of `/api/pokedex/status` (709 KB to 394 KB and 354 KB). The supervisor and backups read the new `/api/summary` (about 1 KB) in place of the full state every few seconds. `/api/pokedex/status` without a view is unchanged for the trade broker and tools.
- Fix every page of a library hanging for up to a minute while an adventure's trading page was open. The page asks for its trade status every 5 seconds, and the library built that status on the thread that serves all pages, reading the whole Gen II game data file again for every Gen II Pokémon it showed. The status is now built off that thread, Gen II species data is read once, trade views build only the rows they return, and the trade history comes from one query. With 300 Gen II trades an adventure's trade status drops from about 10 seconds to 0.2 seconds, and the library's trade overview from about 110 seconds to under 0.1 seconds.
- Turn on the GS Ball event by default for new Crystal adventures, as the Mew event already is, so a new Crystal adventure goes for Celebi after becoming Champion. Existing adventures keep their setting, and it can still be turned off in Adventure settings.
- Add a Trade page for trades you choose yourself. Open it from Cable Club trading with Make a trade, pick an adventure and any Pokémon in its party or PC on each side, and press Trade. Locks, offers, party protection and the last-copy rule do not apply. Only limits the cable cannot get past stop a pair, each with its reason: eggs, Pokémon that cannot be told apart, the only Gen II party member that can battle, and Time Capsule limits such as species past 151, Gen II moves or Mail. Chosen trades go before automatic ones, wait in line when the Cable Club is busy, show each step from travelling to the Cable Club to the saved trade, and can be cancelled until the trade commits. The API is under `/api/v1/interactions/manual-trades`.
- Add view links. **Copy view link** on an adventure's live page copies `/view/<adventure id>/`, which shows the same pages with every control hidden: the screen, team, journal, progress and statistics. The server treats each request under `/view/` as view-only, whatever the adventure's settings: only `GET` and `HEAD` are allowed, every other method returns 403, and the save state list and save export are refused. `VIEWER_ONLY` still makes a whole instance view-only. To share an adventure publicly, expose only `/view/*` through your reverse proxy. The new [authentication guide](docs/authentication.md) has Authelia rules for public view links and for logged-in watchers, and a Traefik example.
- Add Pokémon Yellow adventures. A Yellow ROM is recognised in the Library, plays from a new game with Pikachu as the starter through the Elite Four, and trades with Red and Blue over the Cable Club and with Gold, Silver and Crystal through the Time Capsule. Yellow uses its own game data and story events, such as Jessie and James and the gift Bulbasaur, Charmander and Squirtle, and runs on the Rust backend. A 0.4.x release cannot open a Yellow adventure.
- Add a Game cartridges shelf in Settings with one slot each for Red, Blue, Yellow, Gold, Silver and Crystal. Each slot shows whether its cartridge is installed, with a short hash, size and date, and takes Upload, Replace or a dropped file. PokeSim identifies every upload by its hash and files it in the right slot, says so when it was dropped on the wrong one, and refuses other files in plain words that name the supported games. Remove asks first and refuses while an adventure uses the cartridge. New adventure now picks the game from installed cartridges, greys out missing ones with an Add cartridge link, preselects a lone cartridge, and points to Settings when none is installed. The upload and Custom ROM choices are gone from the dialog. `POST /api/v1/assets/rom` keeps working, and `GET`, `POST` and `DELETE /api/v1/cartridges` are new.
- Make the optional community portrait pack cover every supported game. One click in Settings → Pokémon artwork now downloads the pinned PokéAPI artwork for Red/Blue and Yellow (Pokémon 1 to 151) and Gold, Silver and Crystal (1 to 251), 1,055 images, with progress, four downloads at a time, a size limit per image and for the pack, and finished images kept in the data folder so a retry only fetches what is missing. Each adventure shows the set for its own version, and Gold, Silver and Crystal adventures now use the pack too. Without the pack, portraits still come from the owner's ROM, and an image placed in an adventure's own `sprites` folder still wins over the pack. A Red/Blue pack installed by an earlier release keeps working and upgrades without downloading its images again.
- Fix Gold, Silver and Crystal adventures looping at the Blackthorn Gym boulder puzzle. A boulder push or the Strength question leaves the player in place, which was recorded as a wall on the tile the player must stand on next, and a pushed boulder left a duplicate object behind. Neither is blocked now. Repeated reloads without new progress now count across reloads and report the adventure as stalled with a help request after 3, and reloading stops after 12.
- Fix Gold, Silver and Crystal adventures showing no portraits for Pokémon 152 to 251. The adventure sprite route only allowed the first 151.
- Fix a stopped or failed adventure opening what looked like a second, broken Library. Its page now says Stopped, Failed or Starting, gives the reason in words (a lost connection reads "Couldn't download the Pokémon Silver game data (no network). Retry."), offers a large Start or Retry key, and links to Cable Club trading and back to the Library. Library cards for such adventures show the state, the same reason and a one-click Start or Retry instead of a "View adventure" link back to the page. Gen II and Gen I data downloads now retry brief network failures with backoff, a failed download is retried again after 30 seconds, 2 minutes and 5 minutes, and the Retry key resets that. Gen II data is still generated on first start rather than baked into the image, and the self-hosting guide now states the network it needs.
- Fix Gold, Silver and Crystal adventures being restarted about every 65 seconds and ending as failed. The supervisor asked Generation II workers, which have no screen palette, to apply one, and counted the refusal as a failed health check. Optional settings now never decide whether a worker lives, a refusal is reported on the setting, workers that report no palette are left alone, and the Library hides the palette choice for Generation II games. Opening a Generation II adventure on 0.4.x still fails with "Unknown settings: celebi_event" (documented in the operations guide), since that release cannot be changed.
- Remove the automatic pause for a shiny that cannot be caught (added in 0.4.18). Balls cannot be bought and storage cannot be freed during a battle, so the pause only looked like a stall. Keep at least 10 balls in stock before heading out, on top of the existing free-storage reserve, so a shiny stays catchable. If one still cannot be caught, the player runs as it would from any other uncatchable encounter, and the journal and notifications record "Shiny <species> could not be caught: no balls" or "no storage space". The notification follows the "Stuck or needs attention" setting. Shiny release and trade protection, Take Control, and the Transform check are unchanged.
- Run every adventure on PyBoy RS, a Rust port of PyBoy 2.7.0, through PokeSim Core 0.2. PyBoy is no longer a dependency, and installation needs no Rust toolchain.
- Add Gold, Silver and Crystal adventures with Gen II Cable Club trading, the Time Capsule with Red and Blue, portable save export and cartridge real-time clocks. They run on the Rust backend only.
- Keep the 0.4.x checkpoint tag on Gen I checkpoints so a 0.5.0 library rolls back to 0.4.x. Gen II adventures and locked-clock checkpoints cannot be opened by 0.4.x.
- Report both Core and PokeSim capability errors as HTTP 501 with the real message instead of the busy response.
- Read the wild Pokémon's original DVs for shiny protection after Transform through Core's decoder.
- Require the NO THANKS entry before reading a list as the Game Corner prize menu, so other lists are not mistaken for it.
- Fix live sound stutter over a jittery connection. The page now keeps an adaptive lead of 0.4 seconds that grows to 1.5 seconds after dropouts and shrinks slowly, trims drift by at most 2%, and skips forward with a short fade instead of clearing. The server keeps about 2 seconds of audio and serves it without truncation. Take Control uses a lead of about 0.1 seconds. Playback speeds snap to fixed rates, and sound is off above 4.5x. Short network failures are retried for 6 seconds. The new `tools/audio_jitter_harness.py` measures gaps in Chromium.
- Let a library that only holds Gen II adventures start a worker. Preparing Gen II data also prepares the shared Gen I tables, and a missing set is reported in words.
- Refuse to rewind past a trade or a custom reward from the load-state command as well as the rewind list, and return command errors to the caller instead of ending the adventure.
- Stop the Gen II policy crashing on empty choices when it plans a Pokémon Center, a fishing spot or a field move partner.
- Download a Gen II save as a `.zip` holding the `.sav` and its `.rtc` clock file, because a save without its clock is read as having lost the time. Gen I stays a single `.sav`.
- Keep the live audio ring for the full buffer so a stall under two seconds resumes without a gap, and have the page resync when the server reports missed frames.
- Show a short cause and the log path when a worker is not ready in time, in place of forty log lines.
- Show what idle Gen II collection is waiting for, such as Tuesday for the Bug-Catching Contest or night for a time-gated encounter. The cartridge clock follows wall time.
- Remove unreachable Core clock probes. An older Core still gets a clear capability error, and the package's capability error now shares the backend's 501 handling.
- Require every job of the CI and Python install workflows by exact name in the release gate, including the browser and native test shards and all four Windows shards. The old prefix matching let `container-proxy` stand in for `container` and `macos-15-intel` for `macos-15`.
- Make the release validate job and gate fail while any temporary pin remains, check the `#sha256=` fragments, the Dockerfile source checksum and the published emulator assets against `uv.lock`, and add `tools/finalize_release_pins.py` to rewrite the pins from the final release assets.
- Stop `pokesim-core` from being requested on platforms without a pyboy-rs wheel (Windows ARM64, 32-bit ARM, FreeBSD, musl), so pip never looks those names up on PyPI. The installers and the application now say plainly that the platform is unsupported.
- Derive the bundled pyboy-rs source archive check from `uv.lock` instead of a hard-coded file name, and fail when the archive's own metadata names another version.
- Fix Gen II hangs caused by nicknames that look like menu words. A Pokémon named CANCEL, PROTOTYPE (contains TYPE) or MOSQUITO (contains QUIT) made the bot read the battle screen as the wrong menu and press the same button forever. Battle HUD names and party nicknames are now blanked before the screen is classified, keywords match whole words only, and generated or custom full nicknames can no longer equal a menu word. The same whole-word rule fixes Gen I lookalikes such as FRESH, SODA, PP and RELEASED nicknames, with the 0.4.20 PP fix kept.
- Add Gen II stuck recovery. A screen that does not change for 1800 frames makes the player back out with B and then try seeded exploratory buttons. Longer trouble reloads an autosave from before it began, with a random idle so the same save does not replay the same hang. Every Gen II menu task now gives up after a step limit, and repeated failures escalate to a reload. The Stuck? badge and notification now come with a real recovery, and reloads, glitched state and help requests are reported truthfully.
- Fix a KeyError before the game starts that made the trade inventory return HTTP 500. Unknown Gen II YES or NO prompts now answer NO, then YES after three repeats so the story cannot deadlock. Preparing a Gen II trade with every PC box full now fails with a clear message and resumes play instead of pausing, and a leftover trade hold with no live exchange no longer blocks resume.
- Fix a Gen II slot machine stall at 9899 credits. Once the adventure decided to leave, it pressed only B on the Start! box, which does nothing while the reels spin, so it pressed B forever. It now stops the reels with A, backs out of the bet menu, answers NO to Play again, and treats the 9999 coin case cap as the budget. Slot, coin vendor and prize tasks fail to the stuck path when the screen stops changing, a name entry screen closes after 600 presses, and the Gen II player harness no longer ticks zero frames.
- Generate Gen II game data in CI so the Gen II runtime tests run there, and read all local Gen II test inputs from `GEN2_DATA_DIR` and `GEN2_CARTRIDGE_DIR` (`GEN2_ROM_DIR` is gone).
- Extend the private-string scan to case-insensitive matches, personal paths, private network addresses and contact details, and make it fail when git is missing.
- Fix Gen II adventures stalling on ice, found in the Ice Path pocket on the Mahogany side of B2F. The route planner now reads object positions from the map data, treats hidden objects and warp events on plain ice correctly, replans after every slide, and no longer counts a tile it only slides over as somewhere it can stop. When no route to the goal exists the player returns to the main objective, then explores the least visited way out, and finally asks for a reload instead of waiting forever. `tools/check_gen2_ice.py` lists which warps of every ice map can reach which from the generated map data.
- Make the shiny-not-caught notification low priority, under "Everything else". Narrow the new-adventure starter list from the chosen cartridge file and refuse a starter from the wrong game before creating the adventure.
- Correct the release documents: rollback wording (Red and Blue need no restore, Gold, Silver and Crystal need 0.5.0, locked-clock checkpoints are refused by 0.4.x), Gen II in the package description, third-party notices, and a test that loads a Rust-written Gen 1 state into PyBoy 2.7.0.

## 0.4.20

- Fix PC box lists with a nickname containing PP being read as the PP Up menu, which stopped the Release goal from freeing storage.

## 0.4.19

- Keep shiny encounter protection after Transform by reading the wild Pokémon's original DVs.
- Free a full bag for story items by selling a limited TM only when no ordinary surplus remains. Champion purchases leave one bag slot free.

## 0.4.18

- Fix Settings failing to load when saved backups exist.

- Add optional locally stored PokéAPI artwork for all 125 item statistics entries, independently of Pokémon portraits. Include move names in TM/HM labels.
- Allocate TMs by projected level-100 Battle Power gain using actual DVs, with a level-50 minimum and material improvement requirements.
- Replenish Moon Stones, PP Ups, Elixirs, and Max Elixirs at the Champion counter. Add separate capped million-step offers for a Master Ball and five Rare Candies, with progress in Items.
- Remove stale validation records and unused assets, update maintenance guidance, and keep optional browser imports out of normal test collection.

- Add a Champion TM counter at Celadon Department Store for the 38 limited TMs.
  The AI purchases useful upgrades for compatible party members with a supply
  reserve, then teaches them through cartridge menus. Purchases recover safely
  after interruption and count in item statistics. Protect limited TMs from selling.

- Add Traded in and Traded out to Pokémon Stats, with verified cable-history recovery, final received evolution forms, NPC exchange tracking, and duplicate protection.

- Give Stats its own main tab with Overview, Pokémon, and Items pages. Add searchable action totals for each species and item, preserve recorded catch history, and start new counters without estimating earlier activity.

- Reorganize Stats around shared overview totals, durable milestone times, recent progress, and collection highlights. Show detailed charts in open sections and combine legendary returns with the return-visit and gift cards, preserve unknown historical times, and label existing power charts as Stat Power.

- Simplify adventure controls with Stop and Download labels, a Settings icon beside Open adventure, and always-visible Archive and Delete actions that save and stop first.

- Make all Pokédex header counters species coverage out of 151. Credit perfect and shiny final evolutions to their earlier forms, remove the separate shiny panel, and move individual catch, perfect-find, and shiny totals to Stats.

- Remove Elite Four wins from PC cards, details, and sorting to reduce visual clutter.

- Add moves-aware Battle Power to PC sorting and details, keeping Stat Power and natural potential separate.
- Evaluate learned moves with the Pokémon's attacking stats, coverage, accuracy, and useful effects.
- Delay stone evolution for useful level-up moves that would be lost. Improve empty move slots with owned Surf or Strength HMs, even when another partner already knows the field move.

- Hold the mobile direction and action buttons to repeat input, with larger touch targets and cancellation on release, page hiding, or focus loss.
- Identify Gen 2 shiny-compatible DVs with a distinct star badge in the party, PC, and Pokédex. Add shiny filters, wild sighting counts, capture and custom gift counts, and a current collection count.
- Preserve shiny partners from automatic release, NPC trades, and trade offers. Prioritize shiny captures and pause for manual control if a shiny cannot be caught with the available balls or storage space.
- Permanently delete stopped adventures using typed name confirmation. Interrupted deletions stay archived and can resume, while independent backups and shared ROMs remain available.
- Keep emulated sound hardware running while muted so reconnecting listeners and cable trades preserve audio state. Upgrade supported older muted checkpoints in memory.
- Add 12 GBC-inspired whole-screen palettes in Adventure Settings. Apply palette changes live, including while paused, without changing game state. Remember the choice per adventure.

## 0.4.17

- Exclude unfinished sprite downloads from backups so installation and backup creation can safely overlap.

- Add an optional community sprite installer in Settings, with download progress, previews and a switch back to default artwork.

- Refresh migrated cartridge portraits without requiring a hard refresh, and recheck replaced image files on later page visits.

- Heal Pokémon whose stored HP exceeds their recalculated maximum after PC withdrawal, preventing repeated save reloads during League rematches.
- Add a nickname pool editor with full names, built-in choices, exact exclusions, and a pool size preview.
- Load adventures from verified backups as separate stopped copies, with automatic trading disabled. Show backup dates and sizes in Settings.
- Present repeat visits and Mew walking requirements as progress cards in Adventure Stats, with separate ready, pending and League-win states.
- Delete saved backups with confirmation, browse five per page, and see total backup storage.
- Accept legacy discordapp.com webhook addresses and normalize them to discord.com.

- Add live per-adventure speed controls and clearer Pause, Resume, and Save now actions.

- Fix adventures waiting forever when a poison faint message interrupts a map crossing.

- Add opt-in live game audio at any simulation speed, including Max.

- Add bright type-colored backgrounds with soft spotlights behind Pokémon portraits in the live team, PC, and Pokédex.
- Update the Docker build tool uv to 0.12.21 from dependency PR #32.
- Fix PC layouts at intermediate window widths and fit collection cards to the available space.
- Add editable trainer and rival names with random suggestions when creating adventures.
- Suggest editable adventure names with a button to generate another.

- Expand built-in nickname vocabulary to 100 prefixes, 70 suffixes and 6,117 names.
- Add Discord webhook and Telegram bot notifications in the Library. Enable any
  number of named ntfy, Discord and Telegram integrations, each with its own event
  filters, adventure subscriptions and test button. Existing settings migrate automatically.
- Preserve ntfy settings and separate provider credentials when switching.
- Reuse event filters, screenshots, journal links and test delivery across providers.


## 0.4.16

- Add global custom nickname prefixes and suffixes for future catches and League gifts.
- Rotate a capable reserve into each new League rematch while retaining the strongest
  teammate, field-move coverage, and trade reservations.
- Adopt hash-pinned PokeSim Core 0.1.4 for reusable naming, menu, screen, storage and event flag mechanics. Keep reward timing and gameplay policies in PokeSim.


## 0.4.15

- Set speed independently for each adventure and remove the running-game cap.
  Show actual speed, CPU use, memory use, and recent activity on Library cards.
- Reduce repeated collection decoding, rendering, training destination scans, and
  navigation cache memory. Preserve the original evolution-training destinations.
- Export standard cartridge `.sav` files from the Library. Return to the Library
  through the PokeSim logo and fit the complete game image in fullscreen.
- Improve Victory Road return routing and release held inputs after restoring saves.
- Reopen legendary encounters after walking milestones. Add repeat Eevee, dojo,
  fossil, and supported NPC trade visits after 100,000 new steps by default.
- Keep League rewards to random starters. Repeat Mew requires 1,000,000 new steps
  followed by another League win, with one initial Champion gift.
- Count custom gifts in catch totals and protect the last copy of legendary Pokémon.
- Record marathon times and personal bests. Recover individual League wins only
  when historical identity evidence supports attribution.
- Refresh README screenshots and lead installation with Docker for servers and
  package-manager commands for desktops.
- Update security checks to exercise supported controls after removing global limits.

## 0.4.14

- Split Journal into Entries and Stats with matching segmented navigation.
- Track collection power, strongest-six power, average DVs and level, catches,
  recorded steps, battles, observed damage, marathons, and game hours.
- Preserve activity totals across restarts and checkpoint restores. Keep hourly
  trend samples for 30 days and daily samples afterward with bounded chart responses.
- Label chart scales, reveal small collection improvements, and leave gaps for
  missing measurements. Express DV changes in percentage points.
- Preserve collection measurements when saving immediately after restart and retry
  failed statistics transactions without losing capture counts.
- Route Stats correctly through the multi-adventure manager.

## 0.4.13

- Give all Generation I type badges a shared color palette on the live team,
  Pokédex, and PC, including Pokémon details and Pokédex move types.
- Include permanent species typing for party and stored Pokémon in the PC API.
  Keep text labels and high contrast in light, dark, and automatic themes.

## 0.4.12

- Add an occasional Kanto Marathon after the Champion victory. Follow an ordered
  seven-town course, record steps, battles, healing stops, and time, and celebrate
  with a short journal entry and screenshot.
- Save marathon progress and personal bests across restarts. Keep missing Pokédex
  entries and urgent supplies ahead of recreation, with bounded attempts and a
  six-hour game-time interval between races.

## 0.4.10

- Add estimated DV rarity and fully trained potential Power to Pokémon details,
  using the shared probability API in PokeSim Core 0.1.2.
- Prioritize strong DV candidates for training, require meaningful potential gains
  before retraining duplicates, and bound hunting before training ordinary partners.
- Keep trained veterans until their replacements catch up. Protect rare finds from
  automatic release and trading, with existing locks and explicit offers respected.

## 0.4.8

- Use PokeSim Core 0.1.1 for ROM identities, memory addresses, text and numeric
  decoding, individual Pokémon fields, and party and bag reads. PokeSim and
  PokeAgent Bench now consume the same versioned implementation.
- Install Core automatically with the native package and Docker image. Preserve
  existing adventures, saves, trading, automation, and application data types.

## 0.4.7

- Fix Game Corner prize confirmation when an older menu cursor remains visible.
  Adventures with enough coins can finish purchasing Porygon instead of timing out.

- Keep Pokémon details focused on stats and counts. Move DV, training, ranking, and
  victory-count explanations to the linked Pokémon stats guide. Separate stats,
  PC storage, and trading into clearly named documentation pages.
- Default All Pokémon to highest Power first. Calculate Power from offense,
  durability, and speed instead of adding stats equally, and keep Stat total as
  a separate sort and API field.

## 0.4.6

- Fix the first ROM upload on fresh Docker and native installations. Generate portraits
  after automatic adventure setup, using the library's verified reference data instead
  of the legacy data directory. No manual prepare-data command is needed.
- Gate Docker releases on first ROM upload, automatic reference setup, portrait generation,
  worker startup, saving, and restart in an empty library without legacy game data.

## 0.4.5

- Resolve equal filesystem timestamps using autosave filename timestamps, so selecting
  and pruning saves consistently keeps the newest checkpoint.
- Add user-account installers for macOS, Linux, and Windows that manage Python 3.12
  and install the released wheel without Git or pipx.
- Add a Docker quick-start configuration with a persistent named volume, removing
  manual data-folder ownership steps for new installations. Existing bind mounts keep
  their defaults. Local browser URLs now follow custom HTTP ports automatically.
- Refresh installation, updates, backups, and troubleshooting guides, and move retired
  single-game instructions into the historical archive.
- Test installer retries and the Docker quick-start lifecycle in CI, isolate smoke tests
  from inherited Compose settings, and preserve named volumes in the HTTPS proxy recipe.
- Include versioned installers and quick-start configuration in release downloads. Keep
  releases in draft until all uploads are verified, so install commands keep working
  while the next release is built.

## 0.4.4

- The Pokédex filter strip pins flush against the top rail. A gap between them let the cards
  show through as they scrolled past.
- On a phone, adventure pages pin only the tab strip again, as the Library does. The rail's script
  measured the Library breadcrumb instead of the tabs, so all three rows stayed pinned, about a
  sixth of the screen.
- PC storage's box list scrolls inside the window on wide screens, so its top no longer slides
  under the rail while the lower boxes are out of reach.

## 0.4.3

- A missing Pokédex entry now always comes first. Weighting it only raised its odds, so DV hunts,
  rematches and the rule against repeating an activity kept taking turns, and two adventures passed
  1,500 game hours with Dragonite one evolution away. Rematches still come first when money runs out.
- Training toward a level evolution counts as progress. A turn that ended on time was deferred as a
  failure, with a longer wait each time, even while the partner gained levels all turn. Those turns
  now last as long as a training step and can be picked again straight away.

## 0.4.2

- The road so far charts the long goals. Badges are done within the first day, so their line
  gives way to level 100 species and perfect finds, counted the way the Pokédex counts them. Their
  history starts with this release; the journal never recorded them.
- The Pokédex drops the "About these counts" panel below the totals.

## 0.4.1

- The Journal's road-so-far charts now show. Their section shared an id with the live page's
  exploration count, which the shared page script wrote into it, replacing the charts with a line of text.

## 0.4.0

- The Journal opens with the road so far: Pokédex registered, badges and League wins over time,
  one step line each on a shared clock. Adventures from before this release are rebuilt once from
  their Journal entries; seen counts start with this release.
- Finished exchanges stop piling up on disk. Aborted exchanges drop their staged snapshot as released
  ones do, only the newest twenty finished exchange folders are kept, and an adventure database with
  more than 32 MB of free pages is compacted when the adventure starts.

## 0.3.8

- Journal screenshots no longer catch a fade. An entry recorded on a blank screen keeps waiting,
  up to ten seconds of game time, for a frame that shows something, and its ntfy push waits with it.
- The trading page never waits on an adventure worker. Inventories for a new exchange are read with
  no lock held and checked again before the exchange is recorded, so a slow worker no longer blanks
  the page or holds up adventure starts for up to 110 seconds.
- Automatic trade matching is about eleven times faster: 0.19 s instead of 2.1 s for a pair of full
  libraries, every ten seconds, in the manager process.
- Ruff checks the Python code for unused and undefined names in CI.

## 0.3.7

- Pages load fast. Pooled worker connections and `TCP_NODELAY` remove a ~40 ms stall on every
  proxied request; assets are fingerprinted and cached for a year; responses are gzipped. Local
  game requests go from 21–45 ms to 2–5 ms, and a repeat visit to the live page from about 1 MB
  to 30 KB.
- Pages hold still while they load. The scrollbar track is reserved, the status pill and the
  adventure switcher have fixed slots, and the version is printed by the server. Worst layout
  shift goes from 0.96 to 0.02.
- The live screen streams native PNG frames. `/frame.jpg` and `/stream` keep their paths but now
  carry `image/png`.
- Polish: a cleaner Library › adventure trail, correctly spaced digits and punctuation in the
  panel font, one-line Pokédex card heads, matching dropdowns on every page.

## 0.3.6

- Every page moves onto one instrument-panel design: shared tokens, one component sheet and a
  light and a dark theme. Six drifting stylesheets are gone.
- Boxes line up. The live screen and the six party bays end on the same line and the plan spans
  the page; settings panels, library cards, journal entries and the PC's box list are sized to
  their neighbours.
- Portraits scale by whole pixels everywhere, from one shared scaler.

## 0.3.5

- Read the 151 front portraits out of your own cartridge. Adding a ROM now decodes every front
  sprite from it into `assets/sprites`, so the Pokédex and the PC are illustrated without anyone
  hunting for artwork. Nothing is shipped and nothing is fetched for this — the pictures were
  always in the ROM you supplied. A file already in that folder is never replaced, so a
  hand-installed pack still wins. The decoder is a port of pret/pokered's `home/uncompress.asm`
  and every one of the 151 matches that project's reference art pixel for pixel, including Mew,
  whose header sits outside the base-stats table because it was squeezed into 300 bytes of
  leftover space late in development.
- Stop storing a save state with journal entries at all. 0.3.4 narrowed this to eight event
  types; it should have been none. The rewind it powered is refused outright on any adventure
  that has completed a trade, because `can_rewind` requires no `trade_barrier` and every earlier
  checkpoint predates the barrier — so two live adventures were holding 456 MB of save states for
  a button that could not appear on either of them. Going back to a moment is what the twenty
  rotating autosaves, the League entry checkpoint and the before-stall checkpoint are for, and
  those are bounded. A journal entry now costs its screenshot, about 3.6 KB. Entries written
  earlier keep the states they already have, so nothing that rewinds today stops working.

## 0.3.4

- Keep a save state only for moments worth returning to. A rewind stores a whole emulator save
  state, and one was kept for every *notable* entry — which conflated three different questions,
  because notable also decides what reaches the feed and what sends a notification. Levelling up
  and walking into a Pokémon Center are worth reading and are not worth a snapshot: across two
  live adventures they were 1,261 of 2,840 states, and 82% of states belonged to types nobody
  would rewind to. States are now kept for badges, Hall of Fame runs, new partners, evolutions,
  blackouts, stalls and legendary retries only. Existing entries keep the states they already
  have, so no rewind that works today stops working.

## 0.3.3

- Compress the save state kept with every notable journal entry. A PyBoy state is 167 KB of
  mostly zeroed RAM and gzips about ten to one; one is stored for each notable entry so the
  journal can rewind to that moment, and they are only ever added to. A live server was carrying
  456 MB of them across two adventures — 2,836 states against 68 MB of screenshots — which is
  where essentially all of the "40 MB an hour" went. States written before this release stay
  readable, so an existing library keeps resuming and every old entry keeps its rewind.

## 0.3.2

- Stop staging backups and imports in the container's `/tmp`. `create_backup` copied `assets`,
  `adventures` and `interactions` into an unqualified `TemporaryDirectory` before writing
  anything, and the shipped Compose file mounts `/tmp` as a 256 MB tmpfs on a read-only root, so
  the copy went to RAM and failed on any library past about a quarter of a gigabyte — a library
  reaches that in a few hours. The backup stops every adventure first and restarts them in its
  `finally`, so the pre-upgrade backup an operator is told to take was exactly the operation that
  could not finish. Both legacy import paths had the same defect, including the one that extracts
  up to two gigabytes. All three now stage inside the application folder, which is what the
  restore path and three other callers already did.
- Delete the attempt directories of finished Cable Club exchanges. Every attempt keeps two save
  states, two cartridge saves and two screenshots — about half a megabyte — and nothing ever
  removed them, so `interactions/` grew with every exchange and every backup copied the whole
  accumulated tree into its archive. The live server had 377 of them, 174 MB. The newest twenty
  resolved exchanges are kept, an unresolved one is never touched whatever its age because
  recovery still needs its outputs, and zero means keep everything, as it does for autosaves and
  stall bundles. The legacy coordinator already did this; the application one never got it.
- Let an adventure bound its own journal. Every notable event stores a full save state beside its
  screenshot, about 40 MB an hour, and `prune_events` has always existed to trim it — but
  `event_retention_days` was missing from the Library's settings whitelist, so a managed
  adventure could not set it and the pruning call was permanently dead. The live server had
  560 MB of event states across two adventures.
- Answer a busy emulator with a retry instead of an internal error. `runtime.call` raises
  `TimeoutError` when the emulator thread has not reached a queued participant operation in
  45 seconds, and its message asks the caller to retry the same operation — but `TimeoutError` is
  an `OSError`, not a `RuntimeError`, so it escaped the handler's tuple and became a 500 with a
  full traceback in the worker log. Seen firing during ordinary play on the live server, not only
  during shutdown.
- Back off a recovery that keeps failing. An interrupted exchange that cannot be finished — a
  participant record lost to a restore, say — was re-driven every 30 seconds indefinitely, and
  each pass starts the worker again through the recovery path that deliberately ignores a stop
  request. Retries still never give up, because a committed exchange has to be completed on both
  sides, but the interval now doubles to ten minutes and the status explains itself after the
  third failure rather than repeating that progress is saved.

## 0.3.1

- Stop reporting a blackout for a Pokémon that is still being named. `AddPartyMon` raises the party
  count and writes the species list before the nickname screen, and only fills the struct at
  `wPartyMons` once naming is over, so for the 27 seconds that screen is up the new partner reads as
  species 0 with no HP. That counted as a fainted team, so every new adventure recorded two
  "Blacked out!" entries on its way out of Oak's lab and sent the matching notifications, and the
  live page showed the slot as `No Mon`, level 0, fainted. A counted slot the cartridge has not
  filled in yet is now held apart from the team it is joining.
- Stop registering four starters the player never received. The region the Pokédex flags will later
  occupy holds other values for a couple of seconds in Oak's lab, which read as owning Bulbasaur,
  Ivysaur, Charmander and Squirtle at once and put all four in the journal. Every cartridge path
  that registers a species also marks it seen, so an owned flag arriving without its seen flag is
  not Pokédex data and is no longer read as any.
- Keep the post-trade checks when assertions are turned off. The verification that a staged
  exchange left the party, badges, bag, box counts and every untraded slot alone, and that the
  arriving Pokémon is the agreed one down to its struct and original trainer, was written as bare
  `assert` statements, as was the checksum compared just before a staged checkpoint is adopted.
  `python -O` removes those outright, which would have marked a corrupted exchange staged and
  adopted it without a word. They raise now.
- Decode an adventure's response in the application before forwarding it. The proxy streamed the
  child's raw bytes while dropping `content-encoding` from the headers it passes on, so any
  compressed response would have reached the browser as undeclared gzip. Nothing compresses one
  today, which is the only reason this was invisible.
- Name the commands in `pokesim --help`. The help listed the flags for serving the library and
  nothing else, so `adventures`, `import`, `import-pair`, `backup` and `restore` could only be
  found by reading the source, and the usage line called the program `__main__.py` rather than the
  command that was installed.
- Darken the small print on the Pokédex cards. The entry number, the caught and seen notes and an
  unencountered species' name sat between 2.5 and 3.7 to 1 against the card, at nine pixels, so the
  line telling you whether you have caught something was the hardest thing on the page to read.
  Every one of them now clears 4.5 to 1.
- Remove four tools that did nothing of their own. `gen_collection.py`, `gen_strategy.py` and
  `gen_tables.py` were byte-identical shims around `pokesim.prepare_data`, which the data tools now
  name directly, and `prepare_desktop_test_data.py` differed from its sibling by one word of
  docstring. A personal checkout path no longer appears in `link_spike.py`'s error message, and
  `sample_live.py` asks for a host instead of defaulting to one homeserver's name.
- Retake the README screenshots against a library that has a portrait pack installed. Every
  collection view in the old set showed empty squares where the portraits go, which is what a
  reader saw first and is not what the application does: a missing portrait has drawn a numbered
  placeholder since 0.2.0. The live shot is now a battle at 1x rather than whatever frame Max
  speed happened to be on, the PC is sorted by DV rating the way the text beside it claims, the
  Journal has a picture of its own for the first time, and the unreferenced PNG copy of each view
  is gone from the source package.

## 0.3.0

- Stack the plan row on a narrow screen. The three columns it reads across kept their layout at
  every width, so the live page scrolled sideways on a 320 pixel phone.
- Stop reading finished Cable Club trades at startup. Every completed exchange kept the whole
  policy snapshot it was staged from, which on a long-running adventure is mostly the learned
  navigation graph, and startup parsed all of them to act on none of them. An adventure with 229
  finished trades needed more than three gigabytes to open, missed its readiness deadline, and was
  started again by the trade recovery waiting on it, which held the machine in that loop until
  nothing else on it could run. Recovery now reads only unfinished exchanges, releasing a trade
  drops the snapshot it no longer needs, and records kept by earlier versions are compacted as
  adventures start.
- Say why an adventure would not start. The cleanup that stops a worker which never became ready
  reported its own shutdown deadline instead, so the reason the adventure failed was replaced by a
  message about stopping it everywhere that error was shown.
- Train in steps of ten levels instead of aiming straight at 100. Training was also the only kind
  of work exempt from the planner's recency decay, so once it started it kept winning the draw and
  a single partner could hold an adventure for hundreds of game hours while trades and unregistered
  species waited. It still leads when there is nothing new to register, by 247 draws to 173 in the
  settled case, rather than by never stopping.
- Value a trade that triggers an evolution at 40 even when the evolved species is already
  registered. Kadabra coming back an Alakazam scored nothing once Alakazam was in the book, despite
  the cable being the only way it can happen.
- Say what crossed the Cable Club. A completed trade recorded the same sentence every time and drew
  a placeholder beside it; the entry now names both Pokémon and the trainer on the other end, and
  the journal card shows the two of them either side of a swap arrow. Events gained a `detail`
  column for that, added by the store's own migration. Trades staged by an older build keep the
  previous wording.
- Build nicknames from prefix and suffix pairs, 1,616 of them instead of 100. An adventure
  remembers every name it has used, so after a hundred Pokémon the draw fell back to the whole list
  and began repeating. The written names are unchanged and still come first.
- Encode a game frame only while something is asking for one, and no faster than the stream shows
  them. At Max speed the emulator was encoding about 1,100 JPEGs a second for a viewer that shows
  fifteen, whether or not a browser was open: Max goes from about 74x to about 314x real time.
- Decode screen tiles and event flags from lookup tables, worth about 14% of a headless run on its
  own.
- Simplify the top bar. The adventure bar carried eight items in one row using three different
  looks for navigation, and the link that left the adventure was bolder than the page you were on.
  One breadcrumb answers where you are, tabs share one active treatment with the library, and the
  edition badge that three other places already stated is gone.
- Give the live page its space back. The plan moves to a full-width row along the foot, the game
  screen grows from 400 to 560 pixels, and the team column runs the full height beside it with six
  slots, each card carrying its moves, remaining PP and DV rating.
- Hold the plan steady. The planner reports its gap between projects as an objective of its own, so
  the row cycled between the real goal, "Plan the next adventure project" and the ceremony several
  times a minute.
- Cut the Pokédex overview to registered, seen, caught, level 100 and perfect finds. Level 100 was
  labelled and badged with a star, which put a milestone in the same visual language as the DV
  ratings beside it; it reads as a flag now. Three-star DVs are still recorded, badged and
  filterable.
- Give the app a mark of its own, a handheld rather than the `p.` lockup, in the browser tab and
  the top bar.
- Let the seed vary a stall hunt that continues from a checkpoint. A checkpoint carries the policy's
  own random state, so `tools/find_stalls.py --seed` was ignored and four postgame hunts with four
  seeds were one hunt repeated four times. Scenario replays still make the original choices.
- Put new Pokédex entries before the level 100 grind. While any missing species can be caught or
  evolved, those projects are chosen about two times in three and training about one in five. It
  used to be the other way round, and wild Pokémon stop near level 45, so two adventures spent most
  of 400 game hours in Pokémon Mansion with 27 obtainable entries missing. Once nothing new is on
  offer, training leads as before.
- Evolve a partner with a stone before training it to level 100. A Weepinbell was being trained
  with Victreebel unregistered.
- Stop building standalone executable bundles. The PyInstaller build, its checks and its workflow are
  removed. Install the Python package with pipx, or run the container.

## 0.2.1

- Train for the League in Route 23's grass. Training places were found by the overworld's grass
  tile, and Route 23 uses the Plateau tileset's, so the goal had no destination. A fresh run with
  eight badges drifted along Route 21 for seventeen game hours before entering the League.
- Keep Mt. Moon as the goal wherever a side project leads before it is cleared. Back in Viridian
  Forest the goal became training for Misty on Route 24, which lies beyond the mountain, so two of
  three fresh runs wandered between Route 1 and Route 22 and reached Misty after nine game hours
  instead of three.
- Choose the second League battler the same way whatever the party order. With two partners tied
  for the highest level, moving the chosen partner to the lead changed the choice, and a run with
  eight badges swapped Lapras and Muk in the party menu of Pokémon Mansion indefinitely.
- Keep each stall for later. An adventure's `stalls/` folder holds the moment a stall was reported
  beside the first autosave after the last achievement, which the rotating autosaves had long
  dropped by then. `KEEP_STALL_BUNDLES` sets how many are kept, 5 by default, 0 for none.
- Replay stuck scenarios as regression tests with `tools/stuck_scenarios.py`. A scenario is a copied
  save, optionally edited into a harder situation such as a frozen party with no cures at the League door.
- End a battle in which nobody can act. The original trainer routine favours any move of a super
  effective type, so Lorelei's Dewgong only uses Rest against a frozen Muk and never knocks it out.
  The player hands over to a partner the foe does attack, and when there is none the save from
  before the battle is reloaded at once instead of after the battle timeout.

## 0.2.0

- Respect the badge checks on Route 23, plan restocking only at shops that can be reached, and spend
  vitamins and Rare Candies when the bag is too full to buy Poké Balls. A run with six badges and a
  bag of keepsakes argued with the Volcano Badge guard on its way to the Indigo Plateau shop.
- Restart a League attempt that cannot be finished. A checkpoint is kept from the moment the
  attempt begins, and it is used when a battle runs past the timeout twice with no progress between.
- Tell party members of one species apart when changing the lead. With two Haunters the run
  thought the stronger one already led, and reopened the party menu at a gym door forever.
- Buy Full Heals before the League, keep the save from before an endless battle until the
  timeout reloads it, and idle a random moment after that reload so the battle plays out
  differently. Lance's Dragonair can use Agility forever against a frozen last partner.
- Heal at a real Center once Silph Co is freed, because its nurse stops healing then, and stand
  next to her before that instead of two squares away. A sleeping partner kept a run at her side indefinitely.
- Hand over or revive a partner when the active Pokémon is frozen. Freeze never thaws in these
  games, and a foe with only Normal attacks could not finish a frozen Ghost, so the battle never ended.
- Find a Cut, Surf or Strength partner in any PC box and open that box before withdrawing.
  A run whose gift Lapras sat in another box hunted for a Surf partner it could never reach.
- Keep fighting with the last partner standing. The party menu used to choose the partner
  already in battle, which the game refuses, and the battle never ended.
- Leave edge exits such as cave mouths by walking outward. A run that needed healing paced
  between Victory Road 2F's two east exit squares indefinitely.
- Sell a spare valuable to raise the Safari Zone entry fee. A run that reached the gate
  short of the fee used to talk to the attendant indefinitely, and shopping now leaves
  the fee untouched until Surf and the Gold Teeth are collected.
- Report a stall. An adventure with no achievement for two hours of game time and
  fifteen real minutes records a `stall` journal entry with the saved moment, shows
  Stuck? on Live, and sets `stalled` in the Library summary. Managed trades do not
  count as progress. `STALL_ALERT_GAME_MINUTES=0` turns it off.
- Add `tools/find_stalls.py`, which plays an isolated adventure at full speed and keeps
  a replayable bundle for every stall it finds.
- Keep the last Surf partner out of automatic trades, and stop revisiting the Silph
  worker once his Lapras is registered. A run that traded the gift Lapras away before
  collecting HM03 had no reachable way to cross water.
- Set up phone notifications from the Library's new Notifications page, with no
  account or settings file. Choose the ntfy server and topic, generate a random
  topic, add an optional access token, and send a test notification.
- Choose which adventures notify and which kinds of news are sent, including a
  "Stuck or needs attention" kind. Changes reach running adventures right away.
- Name the adventure in every notification title, and announce completed trades once.
- Keep `NTFY_URL`, `NTFY_TOKEN`, `NTFY_MIN_PRIORITY` and `NTFY_MUTE` as the defaults
  until notifications are saved in the Library.

## 0.1.2

- Install with one pipx or pip command from the repository, with no checkout, uv,
  or release URL to keep up to date.
- Point the container quick start at the latest published release and image.

## 0.1.1

- Show All Pokémon in the PC as a compact card grid again, so many more partners
  fit on screen. Lock and trade actions are in each partner's details.

## 0.1.0

- Show the trainer, badges, registrations, League wins, money and play time above
  the Live game and party panels.
- Publish GHCR images automatically when a GitHub release is published, with anonymous pull
  verification, and versioned Compose downloads for Python and Docker releases.
- Consolidate the Adventure Library and independent Red and Blue workers on main.
- Coordinate automatic Cable Club trading with protected partners and recovery.
- Add PC DV star ratings, rating filters, and persistent three-star Pokédex counts.
- Keep level 100 and perfect-DV milestones across checkpoint restores.
- Track captures, current ownership, and individual League victories.
- Improve repeat catching, training, NPC exchanges, healing, and PC cleanup.
- Preserve party detail dialogs and use one global simulation pace setting.
- Update dependencies and verify Python installations across five native targets.
- Align publication with Python packages and Docker, verified draft checksums,
  and the Adventure Library startup and worker lifecycle.

## 0.2.0rc31, experimental beta

Desktop setup, collection controls, and lifecycle hardening. Existing deployments
must be upgraded separately.

### Lifecycle and verification

- Report final-save failures as unsuccessful server exits.
- Share runtime ownership between desktop and server launchers. Hold an adventure
  directory lock until the worker stops and its database closes.
- Clear stale input, recovery timers, and transient menu state on appropriate
  transitions while preserving checkpoint memory and existing journal history.
- Extract shopping and storage controllers with explicit state and decision inputs.
- Report source revision and dirty state, and embed build identity in distributions.
- Add real Chromium scenarios to CI and release checks, plus bounded private replay
  comparisons with progress sampling and input-integrity checks.

### One-time Mew reward

- Award one level-5 Mew after defeating the final Champion rival, separately from
  repeatable Championship rewards. Existing Mew registrations and delivery records
  prevent another gift after rematches, trades, or reloads.
- Remove Mew from the random reward pool. Preserve pending selections for the other
  seven species and existing Pokémon. Reward-enabled coordinators also enable the
  separate Mew gift, including policies carrying the older disabled Mew flag.

### Desktop and collection controls

- Add the desktop launcher with local browser setup, verified reference preparation,
  persistent save locations, process locking, and native packaging workflows.
- Add game-local trading views, explicit offers and withdrawals, and partner locks
  that protect against automatic release and trading.
- Separate physical box browsing from the sortable whole-collection view.

### Repository maintenance

- Index current documentation and archive earlier roadmap, status, and operations logs.
- Extract event-page rendering and its rewind handler. Display rejected rewind requests
  without leaving the event page.
- Run all browser checks and local documentation link checks in CI and release validation.
- Include README screenshots in source packages and verify newer runtime assets.

## 0.2.0rc30, avoid distant shopping for optional supplies

- Require affordable core supplies or saleable items before starting distant ordinary
  shopping trips. Keep optional top-ups in the current mart and preserve legendary preparation.

## 0.2.0rc29, renew preparation through real training gains

- Renew preparation time only when the selected trainee gains XP. Bound total training
  and preparation to 150 game minutes while retaining inactivity checks.

## 0.2.0rc28, productive training with bounded preparation

- Separate preparation from active training budgets, persist progress across saves and
  trades, and favor nearby training targets. Show preparation separately in Live.

## 0.2.0rc27, include the party in PC comparisons

- Include party members in combined searches, sorting, and strongest-partner rankings.
  Add a Party scope with the same stat details as boxed Pokémon.

## 0.2.0rc26, find the strongest stored partners

- Add Power and individual-stat sorts using calculated current-level stats, plus a
  strongest-partners shortcut and five-stat breakdown.

## 0.2.0rc25, retreat from stalled Victory Road healing

- Try one ordinary Escape Rope when healing recovery stalls in Victory Road. Preserve
  the attempt across saves and trades until the party is fully healed.
- Preserve recent valid event observations through short invalid PC-transfer readings.

## 0.2.0rc24, independent exchange safe points

- Request each game's safe checkpoint independently within a shared retry window.
  Abort rejected or timed-out preparation and release its holds.

## 0.2.0rc23, share safe points between rewards and trades

- Give overdue useful exchanges a turn after reward delivery attempts. Persist the
  scheduling state so a reward backlog cannot indefinitely displace trades.

## 0.2.0rc22, recognize PC withdrawals in either write order

- Avoid recording a release when cartridge RAM updates a withdrawal in separate steps.
  Retain genuine release events and existing journal history.

## 0.2.0rc21, complete Articuno's current puzzle

- Plan the Seafoam B3F boulder drops before attempting Surf on B4F, preserve completed
  drops across reentry, and avoid dropping the player through the holes.

## 0.2.0rc20, recover missed legendary encounters

- Restore eligible missed encounters after leaving the room and waiting a persistent
  retry delay. Preserve damage, spent items, and progress. Registered species stay resolved.
- Correct generated toggle-object indexing used by late-map visibility flags.

## 0.2.0rc19, prepare and complete legendary expeditions

- Give legendary projects their own priority, bounded budget, supply preparation, and
  progress accounting. Use status and balls without potentially lethal damage attacks.

## 0.2.0rc18, repeatable Championship rewards

- Award one random level-5 starter, Eevee, fossil Pokémon, or Mew for each newly observed
  Championship, with durable delivery and pending claims when storage is full.
  The rc31 candidate above separates Mew from this historical pool.

## 0.2.0rc17, varied choices and broader exchanges

- New runs choose a seeded random fossil and Eevee evolution, persisted across reloads.
- Optional last-copy trades unlock new Pokédex registrations while protecting parties,
  current projects, and explicitly protected species. Unique partners are not exchanged
  merely to restore collection gaps or improve stats.
- An optional one-time postgame PokeSim Mew distribution uses backed-up checkpoints,
  verified inventory preservation, and the existing durable hold and recovery controls.
  Gifts are labeled as custom events and counted separately from trades.
- Starter and Eevee supply farming remain outside scope.

## 0.2.0rc16, scoped automatic trading

- Coordinate trades through authenticated controls and durable game holds, without Docker access or a root service.
- Recover holds across game restarts and load both committed inventories before releasing either adventure.

## 0.2.0rc15, regular exchanges between trusted adventures

- Enable useful spare exchanges for explicitly configured peers, including exclusives, trade evolutions, and meaningful training upgrades.
- Stage and verify both saves, journal completed exchanges, and recover interrupted transactions without repeating a swap.
- Prevent restores from undoing one side of a completed exchange. Show trade history and opportunities on the board.

## 0.2.0rc14, compare stored partners

- Sort selected or all storage boxes by level, total DVs, total stat experience, total experience, Pokédex number, species, nickname, or box order.
- Apply sorting before pagination, keep the selection in the URL, and show individual stat totals on cards and in details.

- Record verified training gains as partial progress when the idle guard abandons a project.
- Keep the idle deadline and retry delay, without escalating productive attempts as repeated failures.

## 0.2.0rc13, count reserve preparation once

- Start a fresh training idle window when the selected partner first reaches a stable party snapshot.
- Persist that milestone through reloads and keep the overall expedition deadline unchanged.

## 0.2.0rc12, leave Seafoam through the ladders

- Avoid Seafoam floor holes during routine navigation, including remembered steps that previously fell between floors.
- Route exhausted parties out of the fall-and-current loop to healing and resume the adventure.
- Keep the held rc11 obstacle experiment out of this release.

## 0.2.0rc11 candidate, respect obstacles on remembered routes

- Apply observed solid-object positions to remembered steps on the current map. Preserve distant learned routes until fresh object positions are available.
- Stop walking through a remembered Victory Road route when a boulder has returned to the path.
- Allow the route again when the object moves away or is confirmed hidden.

## 0.2.0rc10, verify training after PC transfers

- Accept training progress in battle or after returning to the overworld, avoiding temporary level values during PC withdrawals.
- Keep transfers and missing party entries from resetting the training idle timer.
- Preserve project state across reloads and count subsequent experience and level gains normally.

## 0.2.0rc9, recover routes after Victory Road switches reset

- Ignore remembered steps through currently closed puzzle gates.
- Reach the upper puzzle by ladder when reentry leaves the lower boulder inaccessible.
- Preserve existing saves, parties, and ongoing postgame projects.

## 0.2.0rc8, persistent postgame projects and varied starters

- Collect nearby reachable ground items during ordinary travel and collection expeditions, including caves. Verify collection, respect bag capacity, and preserve the original project during bounded detours.
- Choose a seeded random starter for new adventures, with a persisted choice and a fixed `STARTER` setting.
- Rotate postgame collection, evolution, training, and exploration projects using persistent recent choices and outcomes.
- Train party and stored partners toward level milestones, with progress measured for the selected partner.
- Increase retry delays for repeated failures and bound the retained planning history.
- Keep old checkpoint compatibility and retain existing Pokémon when configuration changes.

- Register the received Pokémon and any trade evolution in the recipient's Pokédex when staging a save-based exchange. Verified on copied Red and Blue saves. Live trading remains disabled.

## 0.2.0rc7, continuing adventures and visible progress

- Restore planner timing safely and replan stationary objectives without rewinding the game.
- Clear the loose east-corridor boulder when returning through Victory Road.
- Check every expedition's route and retire unproductive objectives with a retry cooldown.
- Show Live activity and the last achievement with its age.
- Keep playtime announcement history across checkpoint reloads.
- Package the read-only trade board and save-based trade executor.
- Consolidate the deployed Live, Pokédex, PC, journal, nickname, storage, and persistent clock work into a reproducible release.

- Add a `/pokedex` page: all 151 entries with types, base stats, learnsets, evolution families, and Kanto locations, filtered by search, type, record, and availability.
- Show the traveling party and every storage box, with each resident linked to its Pokédex entry.
- Serve entry data from `/api/pokedex` and live records from `/api/pokedex/status`, and link out to Bulbapedia, Serebii, and Wikipedia.
- Add sixteen tests covering the reference data, the live status shape, and the new endpoints.
- Stop planning Pokédex projects that need the PC when storage cannot serve them: with a full party and every box full, the run no longer walks to a PC and cycles its menu.
- Release spare stored duplicates to keep about five storage slots free, so an unattended run never runs out of room. One copy of every species always survives, the lowest-level duplicate goes first, and a current evolution project's partner is never released.
- Answer a release confirmation only while a release is the active goal, and decline it otherwise.
- Record releases in the journal at minimal priority.

## 0.2.0rc6, unidentified ghost encounters

- Flee wild Pokémon Tower encounters before obtaining the Silph Scope.
- Preserve normal decisions for trainers, identified ghosts, and battles outside the Tower.
- Add ten regression cases and verify escape from a copied stalled checkpoint.

## 0.2.0rc5, storage withdrawal fix

- Allow an evolution partner to be withdrawn from a full box when the party has space.
- Stop selecting the source box again once it is already active.
- Keep capacity handling for full parties and boxes without the requested partner.
- Add four regression tests and verify the fix against a copied game checkpoint.

## 0.2.0rc4, reliable game display

- Load and decode one game image at a time, capped at 10 display frames per second independently of game speed.
- Retain the last good image through request failures and invalid frames, with bounded timeouts and automatic recovery.
- Stop hidden-tab frame downloads and remove competing MJPEG reconnect handlers.
- Add browser-controller regression tests for serialization, decode failures, timeouts, and visibility changes.
- Leave emulator behavior, game speed, save formats, and health checks unchanged.

## 0.2.0rc3, planner reliability fix

- Share one bounded navigation search across collection candidates to prevent repeated route searches from stalling emulation after the League.
- Keep the health threshold unchanged and add regression tests for search reuse, directionality, obstacles, and search limits.
- Preserve failing health details and correct stopped-run statuses in the endurance harness.
- Detect campaign completion from the saved Hall of Fame count after leaving the ceremony.
- Include Docker, Compose, proxy, and validation files in the Python source archive.
- Correct release status claims to disclose the failed earlier endurance run.

## 0.2.0rc2, experimental public beta

- Start a clean public source history with original code under MIT.
- Publish versioned Docker image archives and source packages with checksums, without requiring registry or GitHub credentials to download.
- Document local game-data preparation, supported platforms, access controls, backup, upgrade, and rollback.
- Provide private vulnerability reporting and explicit beta limitations.
- Preserve the gameplay and checkpoint behavior of the candidate under endurance testing.

The prior engineering candidate established atomic checkpoint recovery, rootless containers, authenticated proxy deployment, dependency notices and emulator source preservation, and local preparation of game content. The first endurance run later stopped on a campaign health failure. See RELEASE_STATUS.md for current results.