From 16b39a21b4af673e894f0d06e54f2fe95c1dd1b5 Mon Sep 17 00:00:00 2001 From: maj00r Date: Wed, 24 Jun 2026 18:31:39 +0200 Subject: [PATCH] Skip text (un-baked) includes on the visual load pass Pass filtering (infrastructure eager / visual deferred) relies on the per-node markers that only a binary twin carries. An un-baked text include has no markers, so it can't be split: it loads in full during the infrastructure pass. Reopening it on the visual pass reprocessed every node a second time and, for parameterized text includes, re-ran their models against a parser whose parameters no longer applied, leaking a literal "(pN)" into TAnimModel::Load -> std::stoi throw -> crash while streaming visuals. Drop the text include on the visual pass; its content already loaded on the first pass. Fully-baked include trees are unaffected (their children replay as twins and defer normally). --- utilities/parser.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/utilities/parser.cpp b/utilities/parser.cpp index 56c7efb7..5589a6f8 100644 --- a/utilities/parser.cpp +++ b/utilities/parser.cpp @@ -645,6 +645,18 @@ void cParser::startIncludeDirect(std::string includefile, std::vectorsetReplayPass(m_replaypass); + // pass filtering (infra eager / visual deferred) relies on the per-node markers that + // only a binary twin carries. an un-baked (text) include has no markers, so it can't + // be split: it is loaded in full during the infrastructure pass. on the visual pass we + // must therefore NOT reopen it -- doing so would reprocess every node a second time + // (duplicates) and, for parameterized text includes, re-run their models against a + // parser whose parameters no longer apply, leaking a literal "(pN)" into the model + // loader (which then throws). drop it; its content already loaded on the first pass. + if ((m_replaypass == scene::scenery_load_pass::visual) && (false == mIncludeParser->m_replay)) { + mIncludeParser = nullptr; + return; + } + // a binary-twin replay child reports mSize 0 but is still valid if (mIncludeParser->mSize <= 0 && (false == mIncludeParser->m_replay)) { ErrorLog("Bad include: can't open file \"" + includefile + "\"");