Commit Graph

1288 Commits

Author SHA1 Message Date
bryanthaboi ab61d08fe9 Merge pull request #1786 from 1Jamie/more-android-lc
fix(android): keep Gen1 Game.load after in-process EXIT GAME
2026-08-25 08:10:21 -04:00
bryanthaboi c94ff016d9 Merge pull request #1794 from 1Jamie/pika-surf-title-import
Enhance Surfing Pikachu minigame assets and functionality
2026-08-25 08:09:39 -04:00
bryanthaboi 85e47bc422 Merge pull request #1799 from campavao/rfc-0018-catch-party-full
engine: catch.party_full — custody of a catch the party cannot hold
2026-08-25 08:08:15 -04:00
bryanthaboi 1850b50ee6 CLOSES #941, CLOSES #1081, CLOSES #1349, CLOSES #1602, CLOSES #1618, CLOSES #1624, CLOSES #1630, CLOSES #1633, CLOSES #1661, CLOSES #1669, CLOSES #1676, CLOSES #1731, CLOSES #1739, CLOSES #1740, CLOSES #1742, CLOSES #1744, CLOSES #1753, CLOSES #1757, CLOSES #1758, CLOSES #1760, CLOSES #1761, CLOSES #1762, CLOSES #1763, CLOSES #1765, CLOSES #1770, CLOSES #1777, CLOSES #1781, CLOSES #1783, CLOSES #1784, CLOSES #1785, CLOSES #1787, CLOSES #1788, CLOSES #1789, CLOSES #1790, CLOSES #1792, CLOSES #1797, CLOSES #1803 2026-08-25 07:55:52 -04:00
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
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 2ad2e028d1 feat(mod-api): expose field residual descriptors 2026-08-24 09:32:34 +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
bryanthaboi ca4d3d283c Add Pokemon Crystal as a sixth supported version
Crystal boots from a user-supplied ROM, imports a full cache and is playable:
copyright, the Crystal intro movie, the animated title, gender select, Oak,
and out into Johto. 122 of the cart's 169 script specials are implemented.

Import and data
- tools/make_crystal_manifest.py derives the manifest by importing
  make_gold_manifest as a library, with three additive keyword seams. Gold and
  Silver still regenerate byte-identical, which is the standing requirement for
  touching that generator.
- crystal_symbol_deltas.py and crystal_movie_symbols.py carry the symbol delta:
  Crystal renames the credits mons, splits the trainer card, Pokegear and
  pack-pal blocks by gender, and replaces the intro and title outright.
- Crystal-only manifest keys: engineFlagOrder (162 flags to Gold's 93, so the
  badge block sits one higher) and unownCharmap (the main charmap parser stops
  at the first newcharmap so the two cannot contaminate each other).

Extractor
- RomExtractorGen2 becomes three-edition. Crystal corrections: PAL_MAP_BANK
  0x13, a flat PICS_FIX pic bank, audio bank 0x5e, the mapSongs id-100 hole,
  seven NPC trades, a TradeTexts stride of 8, the five Crystal tileset anim
  steps with per-row degrade, and the column-major trainer card portraits.
- New: animated front sprites (frames, bitmasks, play and idle scripts), the
  Battle Tower roster, Kris assets, Mobile System GB art, and the Crystal
  intro and title via src/import/CrystalMovie.lua.

Engine
- GameVersion gains engine(id) and fixes(id). Gold and Silver keep their
  original bugs where the bug is not hardware dependent; Crystal gets the fixes
  Crystal shipped: Lucky Number boxes 10-14, surfing onto an NPC, and the
  Reflect and Light Screen defence overflow.
- Crystal story: Suicune and Eusine, Celebi behind the GS Ball flag, the Ruins
  of Alph chambers, Buena, the Move Tutor, the Poke Seer, and the Battle Tower
  including the wInBattleTowerBattle badge-boost guard.
- Kris and the gender flag, animated fronts in battle and the summary screen,
  and mon caught data.

Verification
- Every extracted asset is pixel-compared against pret's own source PNGs.
- Gold caches are byte-identical before and after, file for file.
- New Crystal suites plus a T2 Gen 2 tier; the full suite passes.
2026-08-23 12:10:28 -04:00
1jamie 5807b8d836 Refactor session management and resource cleanup
- Replaced `teardownMountedSession` and `flushEditorPackageLoaded` with a unified `SessionLifecycle` approach for managing session transitions and resource cleanup.
- Implemented `SessionLifecycle.endEditorSession` and `SessionLifecycle.endGameSession` to streamline the teardown process for editor and game sessions.
- Introduced `Assets.releaseSession` to handle GPU resource release at session end, ensuring efficient memory management.
- Updated `Game` and `Game2` reset methods to include world and canvas resource releases.
- Enhanced `MapLoader` with a new `releaseAll` method for eager GPU cache cleanup.
- Added tests to verify the new session lifecycle functionality and resource management.

This commit improves the stability and performance of in-process transitions, particularly during editor and game session changes.

further improves and addresses #1662 specifically around android gc pressure.
2026-08-23 10:46:19 -05:00
DESKTOP-8SRFDDM\cam95 b550db3abb rfc: guard the new seams and write RFC 0014
Route B in CONTRIBUTING-mods.md asks an event/hook change for five things.
This adds the two that were missing and fixes what the third turned up.

link.battle_ended built its payload unconditionally. Route B is explicit
that a new event must not allocate when nothing wants it, and every other
emit in the engine already guards -- Runtime.wants now gates this one too,
so an unsubscribed build runs the branch exactly as it did.

world.talk was handing Runtime.call a closure built fresh on every A press,
purely to have a fallthrough to pass. It is a file-local now, so an unhooked
press allocates nothing it did not allocate before.

The RFC covers motivation, the API delta with call sites, migration (nothing
changes for existing mods), and verification. The backward-compatibility
statement is in it: every item is a new name or a new optional argument, and
example_mew_starter -- api 1, category = "GAMEPLAY", whole-species copy --
still loads, which run_modkit proves on every run.

No registry or schema field is added, so gen_registry_docs has nothing to
emit for this change. Running it does show pre-existing drift in
docs/modding/reference/registries.md (timeFishGroups, an objects refinement)
from earlier Schemas.lua edits that were never regenerated; that is not this
branch's to carry, so it is left alone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-23 10:35:12 -05:00