754 Commits

Author SHA1 Message Date
bryanthaboi 943ba5dcbf Merge pull request #991 from AverageConsumer/codex/mod-world-map-tiles
Mod API: expose visual tile data in map overviews
2026-08-08 06:16:24 -04:00
AverageConsumer 371edd1a02 feat(mods): expose map tile shading 2026-08-08 11:59:57 +02:00
Jakub Lisicki 9fc6ba5b01 Add mod.world:startWildBattle
Starting a wild encounter had no supported entry point, so mods built a
BattleState and pushed it themselves -- silently losing onFinish (and
with it evolutions and blackout-on-loss) and pushBattle (entry wipe,
battle theme). Neither failure raises.

Also covers awardExp -> leveledUp -> afterBattle -> checkParty, which
parity_trainer_evolution_order stubs BattleState out of.
2026-08-08 11:58:10 +02:00
bryanthaboi 983bea61aa Merge pull request #986 from MaxTomahawk/feat/mod-battle-checkpoints
feat: add persistent battle safe-point checkpoints
2026-08-08 05:46:34 -04:00
bryanthaboi ab74f7adf7 Merge pull request #974 from hernan0078/mods/spanish-ui
mods: a Spanish translation of the app's own text
2026-08-08 05:45:29 -04:00
bryanthaboi bdd0bf45bd Merge pull request #973 from hernan0078/options/cancel-through-strings
OPTIONS: route CANCEL through Strings so a translation mod can reach it
2026-08-08 05:44:34 -04:00
bryanthaboi 4b950fc23d Merge pull request #972 from hernan0078/ios/stadium-picker-kind
iOS picker: a "stadium" kind, and a way to ask which kinds exist
2026-08-08 05:44:22 -04:00
bryanthaboi af183d95ad Merge pull request #962 from AverageConsumer/feature/mod-world-map-overview
Mod API: expose a read-only active map overview
2026-08-08 05:42:55 -04:00
bryanthaboi 1d4d5d2337 Merge pull request #940 from Yukitty/patch-title_player
Allow TitleState player overrides
2026-08-08 05:42:34 -04:00
bryanthaboi 653b72d86a Merge pull request #925 from Bortlesboat/multiplayer-session-foundation
Add a reusable multiplayer session layer
2026-08-08 05:42:23 -04:00
MaxTomahawk 12b6ef6350 test: prove complete overworld progress fidelity 2026-08-08 09:53:41 +02:00
MaxTomahawk c979685a1f test: cover switched battle party fidelity 2026-08-08 09:53:41 +02:00
MaxTomahawk 5b1d0261ff test: prove public battle checkpoint roundtrip 2026-08-08 09:53:41 +02:00
MaxTomahawk 5bffc89a2f docs: specify battle checkpoint extension 2026-08-08 09:53:41 +02:00
MaxTomahawk 2ce612d5b1 test: prove deterministic battle checkpoint fidelity 2026-08-08 09:53:41 +02:00
MaxTomahawk 6999e5aecf feat: preserve overworld checkpoint RNG 2026-08-08 09:53:41 +02:00
MaxTomahawk 44a7910c69 feat: reconstruct standard battle continuations 2026-08-08 09:53:41 +02:00
MaxTomahawk 85c6fde443 feat: reconstruct battle checkpoints from data 2026-08-08 09:53:41 +02:00
MaxTomahawk 67b6dcc293 feat: capture data-only battle checkpoints 2026-08-08 09:53:41 +02:00
MaxTomahawk 24d9f279ec feat: expose settled battle checkpoint boundary 2026-08-08 09:53:41 +02:00
hernan 83f93c27a1 mods: a Spanish translation of the app's own text
A LANGUAGE-profile mod filling the `strings` registry -- the seam #791 opened
up, used for the thing it was opened for. 566 keys: the launcher, OPTIONS,
the save-slot and profile screens, the mod manager, the naming screen, and
the battle menu.

WHAT IT DOES NOT TOUCH is the cartridge. Dialogue, species, items, moves and
places all come out of the player's ROM and stay exactly as they are, so an
English cartridge is still an English adventure with Spanish menus around
it. The lang/ tables for those ship empty on purpose rather than absent:
they are where a full translation would go, and an empty value falls through
to English, so anyone continuing this can fill one row at a time and the
game stays playable throughout.

THE FONT IS THE CONSTRAINT, and it decided the wording. The 8x8 charmap has
no N-tilde, no accented vowels and no inverted punctuation -- the sole
exception in the whole atlas is the small e-acute of POKeMON. So every value
on an 8x8 surface is plain A-Z: DISENO COMBATE, MESETA ANIL, SEGURO? OTRA
VEZ. Not a spelling preference; a glyph that is missing renders as a hole,
which is how the first cut of this shipped "ESPA OL" to a phone. The
launcher draws with a real font and keeps proper Spanish, inverted marks and
all -- the split is by surface, not by taste.

Adding the glyphs to the atlas would let the 8x8 side read properly too, and
lang/font.lua and lang/charmap.lua are already the place that would hook
into. I have not done it here: it is a separate change with its own taste
questions, and it should not ride in on a catalog.

Tested end to end on iOS and macOS.
2026-08-07 22:16:06 -04:00
hernan d756b7cd43 OPTIONS: route CANCEL through Strings so a translation mod can reach it
CANCEL is appended after the `ui.options.rows` hook, deliberately -- that is
what stops a mod from orphaning the exit. But it also means no translation
mod can ever see it: there is no row for one to rewrite, and the hook has
already run by the time it is added.

The result is that a fully translated OPTIONS menu has exactly one English
word left on it, and it is the way out. I hit this with a Spanish catalog
where every row translated and the exit did not.

One call, matching how every other label on this screen is already built.
Nothing changes without a catalog loaded: Strings is an identity function
until a mod supplies one.

Follows the same reasoning as #791.
2026-08-07 22:14:29 -04:00
hernan 1e6f504a84 iOS picker: a "stadium" kind, and a way to ask which kinds exist
Two things, the second of which is the reason the first is safe.

A NEW KIND. pickFile("stadium") opens the document picker for a Nintendo 64
cartridge and lands it as picked_stadium.z64. The caller I wrote it for is
the Dramatic Shape voxel mod, which builds Pokemon Stadium battle models out
of the player's own cartridge -- on desktop it opens a dialog for that, and
on iOS it could only print a sandbox path to a screen and ask the player to
put a file somewhere they cannot reach from a phone.

Its own filename, not picked_rom.gb, because that is the name the Game Boy
importer watches: a 32 MB N64 ROM landing there is deleted and then reported
to the player as a broken cartridge.

WHICH IS ALSO WHAT AN UNKNOWN KIND USED TO DO. The switch's default case
treated anything it did not recognise as a Game Boy ROM, so a caller asking
for a kind the build predates lost the player's file -- the worst available
answer to "I have not heard of that one". Unknown kinds are refused now.

That refusal is invisible on its own: pickFile returns false, which is also
what "the picker would not open" returns, and a mod cannot tell them apart.
So the host says what it knows -- love.system.pickFileKinds() returns
"rom,mod,sav,stadium", or nil where there is no bridge. A caller asks first
and keeps whatever fallback it had; the voxel mod shows its folder note
again, which is what it did before any picker existed.

Tested on an iPhone 17 Pro: a Stadium cartridge imports from the picker and
the models build.
2026-08-07 22:13:50 -04:00
Hanan Rodebaugh abb4f3f9f0 better mod item registry 2026-08-07 20:24:11 -04:00
Yukita Mayako 5b0209a7ce feat(TitleState): add field.title.player 2026-08-07 14:28:25 -04:00
AverageConsumer c1e0685e97 feat(mods): expose read-only map overview 2026-08-07 20:20:57 +02:00
Bortlesboat 3c57b28c6d ci: retrigger cancelled checks 2026-08-07 13:16:06 -04:00
bryanthaboi cab62ff7b3 Merge pull request #903 from martin2844/martin2844/fix-blue-rom-setup
Fix Blue ROM source setup
2026-08-07 12:50:26 -04:00
bryanthaboi 5b6dfed359 Merge pull request #959 from MaxTomahawk/feat/reproducible-mod-packages
fix: make modkit packages reproducible with SOURCE_DATE_EPOCH
2026-08-07 12:43:50 -04:00
bryanthaboi 91a85a065b Merge pull request #927 from AverageConsumer/feature/second-screen-touch
Mod API: expose Android second-screen touch input
2026-08-07 12:41:48 -04:00
bryanthaboi 32e2c51365 Merge pull request #957 from ShaneMcGovernIE/shanemcgovernie-issue-916-trainer-sprite-at-end-of-fly-animation-9e5f77
Hide trainer sprite through the Fly/Dig warp fade (#916)
2026-08-07 12:41:05 -04:00
bryanthaboi 1992fdf398 Merge pull request #955 from ShaneMcGovernIE/shanemcgovernie-issue-945-cannot-edit-trainer-class-s-battle-theme-ad701b
Honor trainer battleTheme override (fixes #945)
2026-08-07 12:40:55 -04:00
bryanthaboi 59ac27971a Merge pull request #953 from ShaneMcGovernIE/shanemcgovernie-fix-reset-settings-bugs
saveOptions three-way merge: stop partial writes dropping launcher keys (#932)
2026-08-07 12:39:56 -04:00
bryanthaboi cd0ace2a39 Merge pull request #952 from MaxTomahawk/feat/mod-state-checkpoints
Add playthrough-scoped storage and stable overworld checkpoints
2026-08-07 12:39:32 -04:00
bryanthaboi 274c728e77 Merge pull request #950 from jherediagu/fix/translation-readiness
Translation-readiness: route the last hardcoded labels through the Strings catalog.
2026-08-07 12:36:47 -04:00
bryanthaboi 8547127f54 Merge pull request #948 from ShaneMcGovernIE/shanemcgovernie-issue-915-wrong-sprite-used-in-opening-2f6ea5
Fix Yellow Oak speech showing Nidorino instead of Pikachu (#915)
2026-08-07 12:36:37 -04:00
bryanthaboi 45d799aa98 Merge pull request #946 from ShaneMcGovernIE/shanemcgovernie-issue-931-mod-update-checks-fail-594ba9
Fix mod update checks failing on non-JSON responses (#931)
2026-08-07 12:36:25 -04:00
bryanthaboi 660c90626d Merge pull request #937 from Yukitty/patch-oak_speech_shrink
feat(OakSpeech): use field.playerSprites.walk in shrink step
2026-08-07 12:36:14 -04:00
AverageConsumer d9dc42895f chore: retrigger CI 2026-08-07 18:10:22 +02:00
MaxTomahawk 02fd21bcdb fix: honor source date in mod packages 2026-08-07 17:54:06 +02:00
MaxTomahawk af00d6ad14 feat: expose storage engine compatibility context 2026-08-07 17:14:42 +02:00
Shane McGovern 0d4a518a08 saveOptions three-way merge: stop partial writes dropping launcher keys (#932)
options.lua is a whole-file rewrite, so a caller handing saveOptions a
partial table (only the keys it changed) silently dropped every key it did
not mention: launcher-only keys like lastVersion, and keys the launcher set
(battleBg, tilt) all fell back to defaults.

saveOptions now reads the on-disk file first and folds caller-absent
values underneath before mergeOptions backfills defaults.  A table holding
every defaultOptions key is a full snapshot and stays authoritative, so the
fold is inert for all in-repo writers (every one passes loadOptions-ed
tables) and cannot resurrect the bindings/activeProfile deletions the
RESET REBINDS and mod-manager paths make on full tables.

Adds a regression suite (options_partial_write_bug932.lua) pinning the
merge, and updates the #828 suite's partial-write assertion, which now
expects lastVersion to survive a delta write.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-07 14:55:55 +01:00
MaxTomahawk 05b43ca258 feat: include engine version in checkpoints 2026-08-07 15:21:16 +02:00
MaxTomahawk 9d6ea845d7 fix: reject invalid checkpoint content 2026-08-07 15:09:16 +02:00
MaxTomahawk bbca4e8e39 docs: specify mod storage and checkpoint APIs 2026-08-07 15:05:43 +02:00
MaxTomahawk 49954ec4ad fix: allocate playthrough identity only on demand 2026-08-07 15:01:18 +02:00
MaxTomahawk 6e94625f2a feat: expose stable overworld checkpoints to mods 2026-08-07 14:49:45 +02:00
MaxTomahawk 0399ad040f feat: add playthrough-scoped mod storage 2026-08-07 14:43:04 +02:00
MaxTomahawk 726ed1102e feat: add opaque playthrough identity 2026-08-07 14:43:04 +02:00
Juan Heredia 5bc7d203a5 Route the last hardcoded UI labels through the Strings catalog
Wrap the battle stat box, the PC quantity footer and the dex metric
labels in Strings() (SummaryMenu -- and MoveEffects since #811 --
already do this); give the battle menu a 'battle' lookup context so a
translation can shorten FIGHT/ITEM/RUN independently of the pause menu;
align the metric dex rows with the imperial ones and make the No.
prefix translatable; make the title menu's recolor zone follow Menu's
auto-grown width; honor the declared-but-unread boot.title seam,
drawing an explicit versionRibbon as one centered piece. With an empty
catalog every path is pixel-identical to vanilla.
2026-08-07 13:59:01 +02:00