Options and Quit now route through main_menu.jsonc markers the same
way New Game does, with a new QUIT_GAME cutscene item type ending the
process directly once quit is confirmed via MODAL_OPTIONS_MARKERS
(whose "message" field is now optional, defaulting to "" like "title").
Fixes two crashes surfaced along the way:
- uiModalLocalize asserted on an empty locale key instead of treating
it as "nothing to show" - hit as soon as a modal omitted a title or
message.
- assetLocaleGetString's new empty-message-ID guard broke the PO
format's own header-read convention (messageId "") used internally
by assetLocaleLoaderAsync, crashing on every boot. Extracted the
shared lookup into assetLocaleGetStringLookup and added a dedicated
assetLocaleGetHeader for that internal read, leaving
assetLocaleGetString's validation untouched for every real caller.
Also replaced every raw assetLocaleGetString/WithVA call across the UI
with the locale/localemanager.h helpers (adding localeManagerGetString
for the plain, non-formatting case), so app code no longer bypasses
them.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Cutscenes now parse their authored .jsonc straight into the runtime
cutsceneitem_t/pool representation via yyjson, instead of going through a
separate Python-compiled DCTS binary format - removes the whole
build/compile step and the byte-format contract between the Python
encoder and the C decoder, at the cost of a (still tiny, one-time)
parse per cutscene load.
Also fixes dusk.dsk going stale after a build: the old custom_command
depended on a CMake-configure-time file glob, which only re-detects
added/removed assets on the next configure and could miss edits
entirely. tools.asset.pack now always runs and decides for itself
(via a small manifest) whether anything actually needs repacking, so
asset changes are never missed regardless of add/edit/remove.
Co-Authored-By: Claude Sonnet 5 <[email protected]>