Use CUTSCENE/INSERT item names as full asset paths directly

cutsceneCutsceneResolve/cutsceneInsertResolveAndSplice no longer inject
a "cutscenes/%s.jsonc" prefix/suffix around an item's "name" field -
matching cutsceneSystemLoad, which already takes a full path. Fixes a
latent double-prefix bug in initial.jsonc's CUTSCENE reference (also had
a "jsonsc" typo) that this change would otherwise have exposed.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-09-19 21:38:09 -05:00
co-authored by Claude Sonnet 5
parent 5697f5c064
commit c1c8174b27
4 changed files with 27 additions and 36 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
"power": 12,
"mpCost": 4,
"target": "SINGLE_ENEMY",
"cutscene": "battle/fire"
"cutscene": "cutscenes/battle/fire.jsonc"
}
}
}
+1 -1
View File
@@ -62,7 +62,7 @@
},
{
"type": "CUTSCENE",
"name": "main_menu"
"name": "cutscenes/main_menu.jsonc"
}
]
}
+7 -13
View File
@@ -411,10 +411,7 @@ bool_t cutsceneCutsceneUpdate(
}
cutscene_t * cutsceneCutsceneResolve(const char_t *name) {
char_t path[ASSET_FILE_NAME_MAX];
stringFormat(path, sizeof(path), "cutscenes/%s.jsonc", name);
assetentry_t *entry = assetLock(path, ASSET_LOADER_TYPE_JSON, NULL);
assetentry_t *entry = assetLock(name, ASSET_LOADER_TYPE_JSON, NULL);
errorret_t result = assetRequireLoaded(entry);
if(errorIsNotOk(result)) {
assetUnlockEntry(entry);
@@ -459,11 +456,11 @@ errorret_t cutsceneCutsceneRefLoad(
errorThrow("Cutscene item (%s): missing 'name'", itemTypeLabel);
}
// Only validate that the eventual "cutscenes/<name>.jsonc" path would
// fit - the reference itself is not resolved/locked until this item
// actually runs (see cutsceneCutsceneStart/cutsceneCutsceneResolve).
int32_t pathLen = stringFormat(NULL, 0, "cutscenes/%s.jsonc", name);
if(pathLen < 0 || (size_t)pathLen >= ASSET_FILE_NAME_MAX) {
// Only validate that name itself would fit - the reference itself is
// not resolved/locked until this item actually runs (see
// cutsceneCutsceneStart/cutsceneCutsceneResolve).
int32_t nameLen = stringFormat(NULL, 0, "%s", name);
if(nameLen < 0 || (size_t)nameLen >= CUTSCENE_CUTSCENE_REF_NAME_MAX) {
errorThrow("Cutscene item (%s): 'name' too long", itemTypeLabel);
}
@@ -492,10 +489,7 @@ bool_t cutsceneInsertUpdate(
}
void cutsceneInsertResolveAndSplice(const char_t *name) {
char_t path[ASSET_FILE_NAME_MAX];
stringFormat(path, sizeof(path), "cutscenes/%s.jsonc", name);
assetentry_t *entry = assetLock(path, ASSET_LOADER_TYPE_JSON, NULL);
assetentry_t *entry = assetLock(name, ASSET_LOADER_TYPE_JSON, NULL);
errorret_t result = assetRequireLoaded(entry);
if(errorIsNotOk(result)) {
assetUnlockEntry(entry);
+18 -21
View File
@@ -60,9 +60,8 @@
typedef struct cutscene_s cutscene_t;
// Max length of a CUTSCENE/INSERT item's "name" field - bounded by what
// fits in the "cutscenes/<name>.jsonc" path built from it (see
// cutsceneCutsceneRefLoad), so this is never reached in practice.
// Max length of a CUTSCENE/INSERT item's "name" field - it's the full
// asset path to load, so this is bounded by ASSET_FILE_NAME_MAX directly.
#define CUTSCENE_CUTSCENE_REF_NAME_MAX ASSET_FILE_NAME_MAX
// A CUTSCENE (or INSERT) item's target. A C-authored cutscene_t* set
@@ -230,7 +229,7 @@ void cutsceneCutsceneStart(
/**
* Resolves a JSON-authored CUTSCENE item's referenced cutscene by name:
* locks+loads assets/cutscenes/<name>.jsonc, parses it into
* locks+loads name as a plain ASSET_LOADER_TYPE_JSON asset, parses it into
* CUTSCENE_SYSTEM.loadedItems/loadedScene, then unlocks the asset entry
* like any other asset - the parsed items don't reference the doc past
* that (see cutsceneInsertResolveAndSplice's matching comment for why).
@@ -240,8 +239,7 @@ void cutsceneCutsceneStart(
* error overlay (matching cutsceneSystemLoad's runtime-failure handling)
* and returns NULL.
*
* @param name Bare cutscene name (without "cutscenes/" prefix or
* ".jsonc" suffix).
* @param name Full asset path to the referenced cutscene's JSON file.
* @return The resolved cutscene, or NULL on failure.
*/
cutscene_t * cutsceneCutsceneResolve(const char_t *name);
@@ -265,10 +263,9 @@ bool_t cutsceneCutsceneUpdate(
* (rather than its own file) since it's tightly bound to the asset/loader
* system itself. Only stores the 'name' string (which points into the
* cutscene asset's still-alive yyjson doc, so no copy is needed) -
* resolving it to the referenced assets/cutscenes/<name>.jsonc asset is
* deferred to cutsceneCutsceneStart, the first time this item actually
* runs, so a cutscene referencing many others doesn't pay to load every
* one of them up front.
* resolving it to the referenced asset is deferred to cutsceneCutsceneStart,
* the first time this item actually runs, so a cutscene referencing many
* others doesn't pay to load every one of them up front.
*
* @param itemObj The item's JSON object.
* @param item Destination item, already zeroed by the caller.
@@ -281,9 +278,10 @@ errorret_t cutsceneCutsceneLoad(
/**
* Shared JSON parsing body for both CUTSCENE and INSERT items - both need
* exactly a 'name' string field, validated to fit the eventual
* "cutscenes/<name>.jsonc" asset path. Only stores the name (see
* cutsceneCutsceneLoad for why resolving is deferred).
* exactly a 'name' string field, the full asset path to the referenced
* cutscene's JSON file, validated to fit CUTSCENE_CUTSCENE_REF_NAME_MAX.
* Only stores the name (see cutsceneCutsceneLoad for why resolving is
* deferred).
*
* @param itemObj The item's JSON object.
* @param outRef Destination ref, already zeroed by the caller.
@@ -318,19 +316,18 @@ void cutsceneInsertStart(
/**
* Resolves a JSON-authored INSERT item's referenced cutscene by name and
* splices it into the running cutscene (CUTSCENE_SYSTEM.scene): locks+
* loads assets/cutscenes/<name>.jsonc as a plain ASSET_LOADER_TYPE_JSON
* asset, parses it into a small scratch buffer local to this call
* (capacity CUTSCENE_INSERT_ITEMS_MAX) straight out of the asset entry's
* own doc, then unlocks the entry like any other asset - nothing needs
* to keep the doc itself resident past the parse: every cutscene item
* field that could reference it owns its string data by value (see
* loads name as a plain ASSET_LOADER_TYPE_JSON asset, parses it into a
* small scratch buffer local to this call (capacity
* CUTSCENE_INSERT_ITEMS_MAX) straight out of the asset entry's own doc,
* then unlocks the entry like any other asset - nothing needs to keep the
* doc itself resident past the parse: every cutscene item field that could
* reference it owns its string data by value (see
* cutscenecutsceneref_t/cutscenemarker_t's doc comments), and
* cutsceneSystemInsertCutscene copies the scratch items into the running
* scene's own array right after. On failure, opens the fatal error
* overlay, matching cutsceneCutsceneResolve.
*
* @param name Bare cutscene name (without "cutscenes/" prefix or
* ".jsonc" suffix).
* @param name Full asset path to the referenced cutscene's JSON file.
*/
void cutsceneInsertResolveAndSplice(const char_t *name);