The native Ruby/Sapphire Pokédex printed the entry's two description
pages from the entries pack, and its labels (?????POKéMON, CRY OF,
REGISTRATION COMPLETE...) and search screen from the chrome packs'
English copies, so a translation never reached them: the Emerald path's
Strings() lookup does not cover the native one, and the search screen's
labels are Emerald's (gText_Dex*), which Ruby and Sapphire's cache does
not have.
The entries pack now keeps the pret label of each description pointer
(DexDescription_Treecko_1 and _2; each edition words its entries in its
own way under the same labels), and the Ruby/Sapphire Pokédex pack the
DexText_ label of each search title and description (DexText_ABC...);
the pack's version moves to 1 and the entries are ready on Ruby and
Sapphire only with their labels, so a cache imported without them is
imported again. The screen reads them from the script cache by those
labels, its own labels by their gDexText_* labels and the category
through Strings(), as Emerald's does, with the pack's copy as the
fallback.
The category is followed by what the unknown-category string has after
its question marks, as only the English cart does
(pokeruby/src/pokedex.c:4228): " POKéMON" in English, "ポケモン" in
Japanese, nothing in the European strings ("?????", "POKéMON ?????"),
whose carts print the category alone.
The Japanese size comparison row is a suffix ("の おおきさくらべ"), so
the screen prints the player's name before it.
The runtime expanded Ruby and Sapphire's {EVIL_TEAM}, {GOOD_LEADER},
{VERSION}, {RIVAL} and {KUN} (and the other version-dependent names)
from text/placeholders.lua, the values the extractor reads from the US
cart, so a translation never reached them: the team leaders stayed MAXIE
and ARCHIE, the rival MAY or BRENDAN, the version RUBY or SAPPHIRE, and
the Japanese honorific empty. Each value is a cart string the script
cache also holds under its pokeruby label (gExpandedPlaceholder_Maxie,
_May, _Ruby, _Kun...); the placeholders now read it from there, with the
extract's value as the fallback, the way Emerald's do.
The labels are defined once, in text_placeholders_extract.lua
(rsSymbols, the evil and good teams swapped by edition), and both the
Ruby/Sapphire import and the message box read them from there.
Ruby and Sapphire 1.0/1.1/1.2 import, play, save, convert and link. Gen 3 shaders, braille, weather and reflection parity, link room players, RS custom carts and launcher support, Gen 3 link fixes for Emerald and FireRed/LeafGreen.
_queueFindEnrichment allows two thumbnail starts per frame, but it counted a
row against that allowance even when _startFindThumb ignored it. A row already
resolved to "failed", or with no thumbnail at all, is ignored there, so two such
rows above a card spent the allowance every frame and the card never got a
download. It stayed on its MOD placeholder (no spinner) for the whole session.
Skip rows that have already resolved, so only a row that actually starts a
download is counted. Adds a regression test that fails without the change.
- Save Editor (Gen 3):
- Added full support for EV, IV, Nature, Ability, and Ribbons editing for Gen 3 Pokémon.
- Implemented stat calculations, personality-based nature derivation, and Gen 3 save data structures.
- Added comprehensive unit test suite in tests/save_editor_gen3_ev_iv_tests.lua.
- GBA Extraction & Graphics:
- Added zero-copy ARM-safe ROM accessor and fast LZ77 string decompression.
- Fixed bag chrome decompression string-buffer indexing preventing solid-color renders.
- Fixed TM Case HM badge tile offset and palette mapping.
- Added builtin moves fallback in src/core/game3/battle/builtin_moves.lua.
- Improved parallel extraction resilience, desktop fallback search paths, and prefix handling.
- Android & Launchers:
- Added dynamic high-res app launcher shortcuts and color palettes for all supported games.
- Updated Android icon generator and intent dispatch handlers.