Skip to content

Research Report R3 Mapselfcontained

LopeKinz edited this page Oct 1, 2026 · 1 revision

A Custom TNC Map That Needs No DLC at All

This research asked two questions about building a TNC custom map that needs no DLC ownership at all: which of the side files a DLC-style map folder normally carries (sound banks, intro video, virtual-texture pages, texture cache) are actually required, and whether a brand-new map name can be reached from the chapter-select menu without triggering a Steam ownership check. The side-file question is now settled for three of four files — texture cache and the intro video are provably avoidable or reroutable through existing patchable fields, while sound is the one file that's genuinely mandatory, though its content can likely be minimized. The entitlement question got real new evidence this pass: a full call-graph trace shows the one Steam-ownership check function in the executable is wired into the chapter-select menu's own UI code, nowhere near the map-mounting engine code — but this is static analysis, not yet confirmed by starting the game, and is flagged as such throughout.

Side files, ranked by how avoidable they are

  1. textures.cache — already runtime-proven unnecessary. A DLC-style folder was run in-game with it absent and produced no error. It's a pure in-memory texture-streaming performance shortcut: the loader checks only an 8-byte magic, and if the file is missing, every texture mip simply loads from the ordinary .texdb path instead.
  2. Intro/loading video (.bk2) — not a special DLC asset at all. It's the value of one ordinary decl field, mapInfo.edit.layerLoadingVideos. A corpus check of every real, playable map's mapInfo decl found the field present with 1–16 entries in all 47 of them and explicitly num=0 in none — only non-gameplay stub/dev decls omit it. Recommendation: omit the field entirely (the retail stub-decl shape) rather than setting num=0, or point it at any of the 100+ .bk2 files the base game already ships.
  3. Virtual-texture pages (.pages) — avoidable by design choice, not by a smaller file. A .pages file is only needed if a material actually sets usevirtualmapping/megatexturedModel=true. A direct count of the target map's own retail entity data found 7,308 of 7,309 static-instance entities use it — almost no real retail art avoids virtual texturing, so building entirely from ordinary (non-VT) materials means authoring your own materials for every surface, not reusing retail content. The cvar that could make a missing .pages file harmless if a material still references it (vt_genMissingPages) is off by default and cannot be turned on in a retail build — there is no safety net, so avoiding VT materials entirely is the only safe route.
  4. Sound (prodspec.json + sound packs) — the one side file that is not optional. Disassembly of the DLC sound-mount function shows its prodspec.json validation failure path is an unconditional engine fatal error (a crash), not a silent skip. What is minimizable is the content: retail itself ships a working, near-empty precedent (a 132-byte, structurally valid, empty sound pack as a patch-layer file) — building a prodspec.json with an empty bank list plus a matching empty pack is the untested-but-structurally-plausible minimal setup. A DLC's sound path fully replaces the base game's for the duration of its own map; the base game's existing banks cannot be used as a fallback.

Simplest answer overall: editing an existing base map's own archive chunk in place (no DLC folder at all) sidesteps every one of these four concerns, because there's no second copy of anything to maintain — at the cost of adding content to an existing map name rather than a genuinely new one.

A new map name and the entitlement check

A brand-new chaptervariation decl entry can be added to the chapter-select data with no special trick (retail itself ships one such patch-only entry). The open question was always whether the Steam ownership check for the DLC chapters would also apply to it. New static evidence this pass: the one function in the executable that logs the DLC-ownership check (idEntitlements::Get) has exactly one direct call site, reached through a thunk with exactly two callers. One of those two is fully traced back to the function that builds the chapter-select/main-menu shell screen — nowhere near the map-mounting code, a completely different part of the binary. The call site itself is additionally gated by two nested "is this object of a specific type" checks whose exact type constants could not be resolved from static analysis, but are consistent with "only Chronicle-DLC-type chapter entries are ever checked" — meaning a variation appended under an already-shown, ordinary campaign chapter (not a new DLC-style chapter) would plausibly never reach the entitlement check at all. The second of the two call sites is reached only through an indirect (vtable) call whose actual caller could not be traced by any static method used here — a genuine blind spot, though it doesn't change the recommendation below.

Recommended route, in order:

  1. Edit an existing base map's own chunk (no DLC folder, no side-file questions).
  2. If a genuinely new map name is wanted, build the DLC-style folder with no .pages, no textures.cache, an omitted layerLoadingVideos field, and a minimal prodspec.json/empty sound pack.
  3. To make that new name reachable from the menu without ownership: append the entry under an already-shown, ordinary campaign chapter, not a new Chronicle-style chapter.

What's proven vs. what needs a game launch

Runtime-proven already: textures.cache can be absent with no error; an unowned DLC folder's reference to an existing base map name was accepted by the file-mounting code with no ownership-rejection log line.

New this pass, static only: the sound-mount crash-on-failure path; the mapInfo.layerLoadingVideos corpus numbers; the full entitlement call-graph trace and its two-type-constant gate.

Still needs an in-game test: whether the minimal empty sound-pack shape is actually accepted at load; whether an appended chaptervariation entry under an ordinary chapter is both shown by the chapter-select UI and skips the entitlement check in practice.

Clone this wiki locally