Commit Graph

1341 Commits

Author SHA1 Message Date
bryanthaboi ba201aa4ad issue template: add Silver and Crystal to the version dropdown 2026-08-25 06:33:08 -04:00
DESKTOP-8SRFDDM\cam95 7d6566fa51 engine: catch.party_full custody for a full-party catch (RFC 0018)
A capture the party cannot hold silently falls through to the box; the
new partyFullDestination seam lets a mode claim custody at that moment
instead, and pokemon.caught reports destination "mod" so the mode can
find the mon again.  Guarded call site, file-local vanilla, docs and a
public-API modkit case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N1DVpYXGabigHqMwviDoKV
2026-08-24 21:06:07 -05:00
1jamie 1ad6c810fa fix SurfingMinigame column definitions 2026-08-24 17:30:09 -05:00
1jamie 233082967c Enhance Surfing Pikachu minigame assets and functionality
- Updated .gitignore to include new generated assets for the Surfing Pikachu minigame.
- Added new image assets for the minigame, including title background and intro frames.
- Implemented extraction of Surfing Pikachu title art in RomExtractor.
- Updated CacheContract to include new asset paths.
- Enhanced SurfingMinigame with new constants and functions for improved gameplay mechanics.
- Added unit tests for new features and ensured existing tests pass.
2026-08-24 17:24:11 -05:00
1jamie d76d173b60 fix(android): keep Gen1 Game.load after in-process EXIT GAME
Stop fanning out arbitrary field:release() during Game/Game2 reset — shared
modules use :release as a handle API, and that teardown left the Gen1
singleton unbootable (Game:load nil) on Play-again. Harden bootGame and
endGameSession to rebuild the module if load is missing.
2026-08-24 14:33:43 -05:00
AverageConsumer 56fc4653d7 Add Gen 2 party reorder API parity 2026-08-24 19:07:56 +02:00
bryanthaboi 0142468125 gender name string 2026-08-24 13:07:11 -04:00
bryanthaboi 4794ddcfdf chris (and all gen2) fix 2026-08-24 12:35:35 -04:00
bryanthaboi 6503e982db potential fix for shaders 2026-08-24 12:10:15 -04:00
bryanthaboi 7d5856f93b Merge pull request #1774 from thibautbus/fix/translate-pcmenu-changebox-save
Translate the PC's CHANGE BOX save flow
2026-08-24 11:33:52 -04:00
bryanthaboi ef43814efc Merge pull request #1773 from ShaneMcGovernIE/codex/launcher-navigation-performance
perf(launcher): keep MODS and MOD INDEX navigation responsive
2026-08-24 11:33:43 -04:00
bryanthaboi bed1062a5f chris 1.1 hotfix 2026-08-24 11:32:42 -04:00
Shane McGovern 190c03cfca perf(launcher): keep mod index navigation responsive 2026-08-24 15:24:10 +01:00
bryanthaboi 041051e154 cartkit: skip the scaffold round trip when there is no engine checkout
The generated cart release workflow curls cartkit.py into RUNNER_TEMP and
runs the selftest from the cart repo, where find_repo() finds nothing and
scaffold exits non-zero, so every cart release failed at the first step.

Report failures and skips even under --quiet; the workflow passes it, so
the only output was the FAIL count with no indication of which check.
2026-08-24 10:20:27 -04:00
bryanthaboi 07c828cab0 fixerino 2026-08-24 10:10:59 -04:00
bryanthaboi b89771508e Merge branch 'dev' of https://github.com/bryanthaboi/gen1recomp into dev 2026-08-24 10:00:57 -04:00
bryanthaboi 2c1c2fe080 Create liblibrashader_bridge.dylib 2026-08-24 10:00:42 -04:00
bryanthaboi 6f4c59df8b Merge pull request #1771 from bryanthaboi/spidercar2
CLOSES #1483, CLOSES #1610, CLOSES #1615, CLOSES #1646, CLOSES #1649, CLOSES #1651, CLOSES #1653, CLOSES #1656, CLOSES #1683, CLOSES #1685, CLOSES #1686, CLOSES #1687, CLOSES #1688, CLOSES #1689, CLOSES #1690, CLOSES #1693, CLOSES #1694, CLOSES #1695, CLOSES #1696, CLOSES #1702, CLOSES #1704, CLOSES #1705, CLOSES #1706, CLOSES #1707, CLOSES #1708, CLOSES #1710, CLOSES #1711, CLOSES #1712, CLOSES #1713, CLOSES #1716, CLOSES #1717, CLOSES #1718, CLOSES #1719, CLOSES #1720, CLOSES #1721, CLOSES #1725, CLOSES #1732, CLOSES #1745, CLOSES #1748, CLOSES #1749, CLOSES #1751, CLOSES #1754
2026-08-24 09:58:53 -04:00
thibautbus 0d14980205 Translate the PC's CHANGE BOX save flow (PcMenu.lua)
PcMenu.lua's own CHANGE BOX save confirmation stayed in English on every
non-English build: its overwrite/saving/done prompts and its YES/NO choice
were bare literals, invisible to a translation mod's `strings` registry,
even though the overwrite/saving prompts are the exact same two cart
messages Gold's SAVE screen (SaveMenu.lua) already routes through
Strings().

SaveMenu.lua now exports OVERWRITE_PROMPT_SOURCE, SAVING_PROMPT_SOURCE and
twoLines() so PcMenu:savePrompt() can call through them instead of
duplicating the two shared prompts. The now-unused plain
OVERWRITE_PROMPT/SAVING_PROMPT tables (PcMenu's old direct-read contract)
are gone along with them, removing a second copy of the same literal text
that had to be kept in sync by hand. The CHANGE BOX confirm prompt itself
("#MON BOX, data\nwill be saved. OK?") gets its own new Strings.source()
key -- it is not shared with SaveMenu, and the port's own English text is
already a same-shape truncation of the cart's three-line
_ChangeBoxSaveText, confirmed against poke-corpus GoldSilver
en_msg.txt:4897. The done message and YES/NO now go through the exact
same Strings() keys SaveMenu.lua already uses ("%s saved\nthe game.",
"Could not save.", "YES", "NO"), so a translation covering SaveMenu's
screen needs no PcMenu-specific fork for any of those.

Added tests/engine/gen2_pcmenu_changebox_save_translation_test.lua,
mirroring gen2_save_menu_translation_test.lua's technique for PcMenu's own
CHANGE BOX flow, and updated the stale cross-file-contract regression case
in gen2_save_menu_translation_test.lua to match the new shared-export
shape instead of the old plain-table one.
2026-08-24 15:55:08 +02:00
bryanthaboi 1bd6e35931 copy rintro 2026-08-24 09:02:56 -04:00
bryanthaboi da73a4fe25 Update crystal_version_test.lua 2026-08-24 08:51:20 -04:00
bryanthaboi cd4ef14f13 Merge branch 'dev' into spidercar2 2026-08-24 08:48:24 -04:00
bryanthaboi d575a64287 Merge pull request #1734 from BoLayerDev/feature/mew-dock-occupancy-seam
Add composable map occupancy and active-block APIs
2026-08-24 08:37:27 -04:00
bryanthaboi ff826ce01e Merge pull request #1769 from MaxTomahawk/adaptive-trainers/mod-developer-mode
feat(mod-api): expose loader developer mode
2026-08-24 08:35:49 -04:00
bryanthaboi 0ab4ef2755 Merge pull request #1766 from MaxTomahawk/adaptive-trainers/field-residual-hook
feat(mod-api): expose field residual descriptors
2026-08-24 08:35:10 -04:00
bryanthaboi 6f343d9b29 Merge pull request #1746 from campavao/engine-mod-seams
engine: generic seams for mod-driven multiplayer modes
2026-08-24 08:34:33 -04:00
bryanthaboi 41790637f0 Merge pull request #1738 from thibautbus/fix/translate-gold-naming-screen
Translate Gold's naming/keyboard screen
2026-08-24 08:32:22 -04:00
bryanthaboi 4ab0ac433b Merge pull request #1736 from thibautbus/fix/gold-ttf-printthrough-invisible-text
Stop drawing invisible TTF text on Gold's palette-shaded screens
2026-08-24 08:32:13 -04:00
bryanthaboi 44c304574b Merge pull request #1727 from dlloa/upstream-cache-contract-1724
Centralize ROM cache readiness and publication
2026-08-24 08:31:50 -04:00
bryanthaboi c8b05e7aa1 Merge pull request #1722 from syybott/fix-mod-options-marker
Add opt-in marker for mod options screens
2026-08-24 08:30:25 -04:00
bryanthaboi 8c6c360ce0 Merge pull request #1715 from caorthann-celt/dev
Enable UWP HTTP requests and Skin Studio controller support
2026-08-24 08:30:09 -04:00
bryanthaboi 6b6b8f46a1 Merge pull request #1735 from thibautbus/fix/translate-gold-options-menu
Translate Gold's in-game OPTION screen
2026-08-24 08:29:21 -04:00
bryanthaboi 2d62805128 Merge pull request #1747 from 1Jamie/android-restart-perf
Refactor session management and resource cleanup
2026-08-24 08:29:10 -04:00
bryanthaboi d27c59b18d Merge pull request #1759 from thibautbus/fix/translate-gold-title-and-save-menus
Translate Gold's title menu and SAVE screen
2026-08-24 08:29:00 -04:00
bryanthaboi 1905261c5b Spider Car Unleashed
CLOSES #1483, CLOSES #1610, CLOSES #1615, CLOSES #1646, CLOSES #1649, CLOSES #1651, CLOSES #1653, CLOSES #1656, CLOSES #1683, CLOSES #1685, CLOSES #1686, CLOSES #1687, CLOSES #1688, CLOSES #1689, CLOSES #1690, CLOSES #1693, CLOSES #1694, CLOSES #1695, CLOSES #1696, CLOSES #1702, CLOSES #1704, CLOSES #1705, CLOSES #1706, CLOSES #1707, CLOSES #1708, CLOSES #1710, CLOSES #1711, CLOSES #1712, CLOSES #1713, CLOSES #1716, CLOSES #1717, CLOSES #1718, CLOSES #1719, CLOSES #1720, CLOSES #1721, CLOSES #1725, CLOSES #1732, CLOSES #1745, CLOSES #1748, CLOSES #1749, CLOSES #1751, CLOSES #1754
2026-08-24 07:52:05 -04:00
MaxTomahawk 333949ce0d fix(mods): normalize developer mode option 2026-08-24 11:13:30 +02:00
MaxTomahawk fb95dc5b6a docs(gen2): correct developer mode guidance 2026-08-24 10:56:05 +02:00
MaxTomahawk 96ed862b50 docs(mod-api): clarify developer mode sources 2026-08-24 10:51:09 +02:00
MaxTomahawk 58681fe62e feat(mod-api): expose developer mode 2026-08-24 10:38:31 +02:00
MaxTomahawk 68fc01dd1c fix(mod-api): silence optional dataset absence 2026-08-24 10:25:37 +02:00
MaxTomahawk cec19db5e0 test(mod-api): cover reserved metadata replace 2026-08-24 10:19:33 +02:00
MaxTomahawk 38d515f547 fix(mod-api): reserve generated metadata ids 2026-08-24 10:10:23 +02:00
MaxTomahawk 7e069df740 fix(mod-api): validate dataset roots lazily 2026-08-24 09:57:57 +02:00
MaxTomahawk ca700c44d7 fix(mod-api): harden imported dataset views 2026-08-24 09:33:51 +02:00
MaxTomahawk 2ad2e028d1 feat(mod-api): expose field residual descriptors 2026-08-24 09:32:34 +02:00
MaxTomahawk b286e6584f feat(mod-api): add imported dataset views 2026-08-24 09:10:35 +02:00
thibautbus 654650e3ff Translate Pokegear's AM/PM too, and warn instead of corrupting a 3rd line
An independent review flagged two gaps:

Pokegear.lua's clock card (drawClock and the card-list clock view) prints
the same AM/PM information MainMenu's clock box does, but was left as bare
literals -- so a mod translating AM/PM would now show it correctly on the
title screen and in English on the Pokegear for the exact same hour. Both
call sites now go through Strings("AM")/Strings("PM"), the same source key
MainMenu.lua already added, so no new corpus entry is needed on the
translation-mods side.

SaveMenu.lua's twoLines() only ever split on the first "\n": drawPanel's
box has room for exactly two Chrome.print calls, so a translation needing
a third line (nothing in the current fr/de/es/it overrides does, but
nothing stopped one from trying) had nowhere on screen to go, and the
extra "\n" landed as a literal newline byte drawn as glyph garbage on the
second line with no indication anything was wrong. It now warns once per
source text instead.

Added a gen2_save_menu_translation_test.lua case driving drawPanel() with a
three-line mod translation: confirms only the first two lines render, the
warning fires exactly once (not once per frame), and drawing does not
crash. Pokegear.lua has no engine-tier test suite to extend for the AM/PM
change; verified by direct inspection and a syntax check instead.
2026-08-23 21:49:06 +02:00
thibautbus fad7443f94 Route Gold's title menu and SAVE screen through Strings()
MainMenu.lua's row labels (CONTINUE/NEW GAME/OPTION/EXIT GAME), its clock
box's AM/PM half, and its CONTINUE save-summary panel (PLAYER <name>/
BADGES/POKéDEX/TIME, or NO SAVE FILE) were bare literals, invisible to a
translation mod's strings registry. SaveMenu.lua's confirm/overwrite/
saving/saved prompts, its YES/NO choice, and its own copy of the same
summary panel had the same gap. Both mirror the Gen 1 port's already-
translated equivalents (src/ui/TitleState.lua, src/ui/StartMenu.lua),
which route every one of these rows through Strings().

SaveMenu's two-line prompts (module-level OVERWRITE_PROMPT/SAVING_PROMPT,
plus the dynamically-built "%s saved\nthe game." and the confirm/failed
messages) are now single Strings()-resolved strings with an embedded "\n",
matching the Gen 1 port's own single-call convention for two-line messages,
split into the two-slot table drawPanel's fixed-position Chrome.print calls
expect only at draw time -- so a translation sees one whole sentence to
reorder, not two independently-translated fragments.

Added tests/engine/gen2_main_menu_translation_test.lua and
gen2_save_menu_translation_test.lua: drive both screens' drawPanel()/
drawSavePanel() with a mod-loaded Strings catalog and check the translated
text reaches Font.draw, plus a vanilla no-mod case proving the fallback is
unchanged. Confirmed both catch the regression: reverting either file to
its pre-fix content fails the corresponding suite (7 and 15 checks
respectively).
2026-08-23 20:57:01 +02:00
bryanthaboi f895293217 Teach custom carts about Crystal
Both features landed independently and each was green on its own, so the gap
only appears in the combination.

- tools/cartkit.py BASES did not list crystal, so cartkit rejected a Crystal
  cart as an unknown base game. The Lua validator never had this problem: it
  asks GameVersion.VERSIONS, so it accepted Crystal the moment the row existed.
- Two self-tests used the literal "crystal" as their never-a-game sentinel and
  invert now that Crystal is real: tests/engine/cart_manifest.lua and
  cartkit's own t_identity. Both re-pointed at "nonesuch", the token the rest
  of the suite already uses for this.
2026-08-23 12:21:50 -04:00
bryanthaboi ebf44f20d3 Add custom carts: named, version-pinned mod sets that play as their own game
A custom cart pairs an identity (title, shell colour, label art) with a base
game, a list of mods pinned to exact builds with their option values frozen,
a load order, and a seal. It ships no code of its own: every mod it names is
a separately published mod, which is what keeps a cart auditable before it
runs and reproducible after an author's repo disappears.

Format and storage:
- src/carts/CartManifest.lua parses and validates cart.json, canonicalises it
  for hashing and reads/writes the .g1rcart bundle. The bundle is a data-only
  serialised table read through SaveSerializer, so an imported cart can never
  execute code. Canonical strings are length-prefixed because option keys and
  values are author-controlled and could otherwise forge a record boundary and
  collide two different carts onto one hash.
- Pins name a public source: a GitHub release with its sha256, a GameBanana
  file id with its md5, or "local" for a capture that only exists on this
  install. A local pin is unpublishable by construction, which is what makes
  "build it here, publish later" possible without inventing a hash.
- Label art rides alongside the manifest rather than inside its identity, so
  re-arting a cart does not tell every player their run is out of date.
  src/core/Base64.lua decodes it; strict, with no whitespace tolerance.

Saves:
- Cart playthroughs live in the cart's own slot namespace (saves/cart_<id>/),
  so a cart's file never sits beside a vanilla one and uninstalling a cart
  never orphans a save. Every save records the cart build it was made under.

The seal:
- A sealed cart loads its pinned list, in its order, with its options, and
  nothing else. A pinned mod with no frozen options gets an empty bucket so
  unfrozen keys fall to schema defaults, identical for everyone; otherwise two
  players on one cart quietly run different games.
- A sealed cart refuses to load when a pin is missing or installed at another
  version. Playing a subset of the cart is the exact dishonesty the seal
  exists to prevent, so the refusal loads nothing at all.
- Breaking the seal is permanent, marked per save slot, and downgrades that
  playthrough to open behaviour. It cannot be cleared through any public API.

Launcher:
- A game's page carries a Custom Carts control and a picker; choosing a cart
  turns the page into that cart's page, with its own cartridge, title and save
  slots. The rail of five games never grows and a cart id never reaches
  imp.tab or imp.panelVersion.
- Loader.planCart runs before boot so a refusal is visible on the page instead
  of being discovered as an error after launch.
- Save as cart captures the enabled mods for a game and names, before the
  player confirms, every mod that could only be pinned to this install and
  whether the result can be shared at all.

Authoring:
- tools/cartkit.py scaffolds, validates, pins and packs a cart, and installs a
  release workflow. Its writer is byte-identical to the engine's serialiser.
2026-08-23 12:18:29 -04:00