NeonRewind is an unofficial, open-source project for Retro Rewind: Video Store Simulator. It currently reads data from an installed Steam copy of the game, converts the film tables into a consistent JSON catalog, and compiles normalized rental, fee, and return mechanics. The public guide, calculators, and website have not been built yet.
The repository contains source code, JSON Schemas, normalization logic, and instructions. Users provide their own licensed game installation and run the acquisition commands locally.
Do not commit or publish:
- Compiled extractor binaries
- Game binaries, package files, mappings, or saves
- Build manifests or static censuses produced from a game installation
- Structured values, rental evidence, Blueprint pseudocode, or Blueprint function traces
- Compiled film catalogs, mechanic artifacts, runtime observations, validation reports, or extracted game text
- Extracted or modified game assets
The documented output directories are ignored by Git.
The commands form one pipeline, and each command uses the file produced by the previous command.
| Step | Result | Meaning |
|---|---|---|
| Build manifest | build-manifest.json |
Identifies the exact Steam build and package hashes |
| Static census | static-census.json |
Lists files, Unreal packages, and exported classes |
| Structured index | structured-asset-index.json |
Locates DataTables and StringTables using a matching Unreal mapping |
| Structured values | structured-values.json |
Extracts table rows and strings into deterministic JSON |
| Rental evidence | rental-evidence.json |
Extracts the rental subsystem's fields, functions, explicit defaults, and default-value object references |
| Rental Blueprint bodies | rental-blueprint-bodies.json |
Decompiles the rental subsystem's cooked Blueprint bytecode into reviewable pseudocode |
| Blueprint call sites | blueprint-call-sites.movie-return.json |
Searches parsed Blueprint bytecode for calls to the movie-return selector |
| Blueprint caller bodies | blueprint-caller-bodies.movie-return.json |
Decompiles the exact functions found by the movie-return call-site scan |
| Customer entry call sites | blueprint-call-sites.movie-customer-entry.json |
Searches parsed Blueprint bytecode for calls into the discovered movie-customer function |
| Customer event-graph body | blueprint-caller-bodies.movie-customer-entry.json |
Decompiles the event-graph function that invokes the movie-customer function |
| AI client ubergraph call sites | blueprint-call-sites.ai-client-ubergraph.json |
Finds Blueprint wrappers that enter the AI client event graph |
| AI client wrapper bodies | blueprint-caller-bodies.ai-client-ubergraph.json |
Decompiles those wrappers to recover their numeric event-graph entry points |
| Blueprint function trace | blueprint-function-trace.movie-customer.json |
Converts the linked caller functions into typed Kismet nodes with branch-variable identities |
| Rental function trace | rental-function-trace.movie-return.json |
Converts selected rental functions into typed Kismet nodes tied to the rental-body artifact |
| Console return mechanics | console-return-mechanics.json |
Normalizes console-return eligibility and queue movement with source locators |
| Membership fee mechanics | membership-fee-mechanics.json |
Normalizes membership fee storage, accumulation, and removal with source locators |
| Movie return mechanics | movie-return-mechanics.json |
Normalizes movie readiness, weighted selection, and customer flow from typed traces |
| Movie return validation | movie-return-validation.json |
Verifies a private runtime observation against its exact movie-return mechanics artifact |
| Film catalog | film-catalog.json |
Converts the film rows into stable NeonRewind records |
An artifact is a JSON file produced by one of these commands.
Package files such as .pak contain the installed game's Unreal assets.
An Unreal DataTable stores many records with the same fields, and a StringTable stores named text entries.
A JSON Schema is a rule file used to check a JSON artifact's required fields and value types.
Acquisition artifacts contain extracted game data, so the examples store them in ignored .local directories.
You need the following items:
- Windows and a licensed Steam installation of Retro Rewind: Video Store Simulator.
- The .NET 10 SDK for the acquisition commands.
- Node.js
24.19.0and pnpm11.xfor the normalized-data compilers. - An internet connection for the first dependency installation unless the packages are already cached.
- A
.usmapmapping generated for the exact game executable when running the structured-index, structured-values, rental-evidence, rental-blueprint-bodies, blueprint-call-sites, blueprint-caller-bodies, blueprint-function-trace, and rental-function-trace steps.
The recommended setup uses portable tool archives extracted into ignored local directories.
Follow Portable local tool setup to install nothing system-wide and change PATH only for the current shell process.
The repository does not currently generate the .usmap mapping.
If you do not already have a matching mapping, you can complete the probe, build-manifest, and static-census steps, then stop.
Do not reuse a mapping from a different game build.
Open PowerShell or Git Bash in the repository root and verify the installed tools.
dotnet --version
node --version
pnpm --versiondotnet --version
node --version
pnpm --versionThe expected major versions are .NET 10, Node.js 24, and pnpm 11.
If a command is unavailable, use the official .NET installation guide, Node.js download page, or pnpm installation guide.
The following example uses Steam's default Windows location.
Change only $steamRoot if your Steam library is on another drive or in another folder.
$steamRoot = "C:\Program Files (x86)\Steam"
$gameRoot = Join-Path $steamRoot "steamapps\common\RetroRewind"
$steamManifest = Join-Path $steamRoot "steamapps\appmanifest_3552140.acf"
$packageDirectory = Join-Path $gameRoot "RetroRewind\Content\Paks"
$packageFile = Join-Path $packageDirectory "RetroRewind-Windows.pak"
$executable = Join-Path $gameRoot "RetroRewind\Binaries\Win64\RetroRewind-Win64-Shipping.exe"
$extractor = "projects/game-data-exporter/static-extractor/NeonRewind.StaticExtractor.csproj"
$generationId = (Get-Date).ToUniversalTime().ToString("yyyyMMddTHHmmssZ")
$buildDirectory = Join-Path (Get-Location) "projects/game-data-exporter/.local/acquisition/runs/$generationId"
$domainDirectory = Join-Path (Get-Location) "projects/typescript/.local/domain/runs/$generationId"
New-Item -ItemType Directory -Force -Path $buildDirectory, $domainDirectory | Out-NullsteamRoot="C:\Program Files (x86)\Steam"
gameRoot="$steamRoot/steamapps\common\RetroRewind"
steamManifest="$steamRoot/steamapps\appmanifest_3552140.acf"
packageDirectory="$gameRoot/RetroRewind\Content\Paks"
packageFile="$packageDirectory/RetroRewind-Windows.pak"
executable="$gameRoot/RetroRewind\Binaries\Win64\RetroRewind-Win64-Shipping.exe"
extractor="projects/game-data-exporter/static-extractor/NeonRewind.StaticExtractor.csproj"
generationId="$(date -u +%Y%m%dT%H%M%SZ)"
buildDirectory="$PWD/projects/game-data-exporter/.local/acquisition/runs/$generationId"
domainDirectory="$PWD/projects/typescript/.local/domain/runs/$generationId"
mkdir -p "$buildDirectory" "$domainDirectory"Each run uses a new generation directory so immutable artifacts can keep stable, unversioned filenames.
Close the game before reading its package files. The game does not need to be running for any command in this README.
Restore the locked .NET dependencies once.
dotnet restore $extractor --locked-modedotnet restore "$extractor" --locked-modeThe probe opens the package directory and reports how many containers, files, and Unreal packages it can see. It does not extract game values or create an output file.
dotnet run --project $extractor -- $packageDirectorydotnet run --project "$extractor" -- "$packageDirectory"Continue when the command reports at least one mounted container and a nonzero file and package count.
The build manifest records the Steam application, build number, executable hash, package hash, engine profile, and extractor version. Later steps use these hashes to make sure their inputs still belong to the same build.
dotnet run --project $extractor -- manifest `
--steam-manifest $steamManifest `
--executable $executable `
--package $packageFile `
--output (Join-Path $buildDirectory "build-manifest.json")dotnet run --project "$extractor" -- manifest \
--steam-manifest "$steamManifest" \
--executable "$executable" \
--package "$packageFile" \
--output "$buildDirectory/build-manifest.json"Repeat --package <path> if a future build uses more than one package-container file.
The command accepts an identical existing output and refuses to overwrite different content.
The census inventories the package without needing an Unreal mapping. It records files, package headers, imports, exports, exported classes, and parse failures.
dotnet run --project $extractor -- census `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "static-census.json")dotnet run --project "$extractor" -- census \
--build-manifest "$buildDirectory/build-manifest.json" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/static-census.json"The command verifies the package hashes before and after scanning.
A .usmap file describes the Unreal properties needed to read DataTable rows and similar structured assets.
Set $mappings to a mapping produced for the same executable recorded in the build manifest.
$mappings = "C:\path\to\the\matching-build.usmap"mappings="C:\path\to\the\matching-build.usmap"The mapped acquisition commands cannot run reliably without this file.
The structured index fully reads candidate DataTables, StringTables, and direct data assets without copying their row values. It records the table locations, structures, row counts, property counts, and failures.
dotnet run --project $extractor -- structured-index `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--static-census (Join-Path $buildDirectory "static-census.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "structured-asset-index.json")dotnet run --project "$extractor" -- structured-index \
--build-manifest "$buildDirectory/build-manifest.json" \
--static-census "$buildDirectory/static-census.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/structured-asset-index.json"The command validates the manifest, census, mapping, and package identities before and after parsing.
This step copies the indexed DataTable rows and StringTable entries into deterministic JSON. The output contains game text and must remain in the ignored local acquisition directory.
dotnet run --project $extractor -- structured-values `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--structured-index (Join-Path $buildDirectory "structured-asset-index.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "structured-values.json")dotnet run --project "$extractor" -- structured-values \
--build-manifest "$buildDirectory/build-manifest.json" \
--structured-index "$buildDirectory/structured-asset-index.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/structured-values.json"The command verifies every input again after extraction and refuses to overwrite different output.
This step reads six packages that define the rental manager, its two structs, and three related AI tasks. It records generated-class fields, function names, class-default values, struct defaults, and object references contained in those mapped defaults. The command stops if the exact package cluster is absent from the census.
dotnet run --project $extractor -- rental-evidence `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--static-census (Join-Path $buildDirectory "static-census.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "rental-evidence.json")dotnet run --project "$extractor" -- rental-evidence \
--build-manifest "$buildDirectory/build-manifest.json" \
--static-census "$buildDirectory/static-census.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/rental-evidence.json"The output contains extracted game values and must remain in the ignored local acquisition directory.
This step loads the cooked script bytecode for the four generated classes recorded in the rental-evidence artifact. It records each function's flags and bytecode-expression count, then uses CUE4Parse to produce deterministic pseudocode for review. The pseudocode is a decompiler interpretation and must be checked against the underlying function metadata before it becomes a mechanic fact.
dotnet run --project $extractor -- rental-blueprint-bodies `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--rental-evidence (Join-Path $buildDirectory "rental-evidence.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "rental-blueprint-bodies.json")dotnet run --project "$extractor" -- rental-blueprint-bodies \
--build-manifest "$buildDirectory/build-manifest.json" \
--rental-evidence "$buildDirectory/rental-evidence.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/rental-blueprint-bodies.json"The output contains extracted game logic and must remain in the ignored local acquisition directory.
This step uses the static census to select parsed packages that export Blueprint functions. It reads their Kismet expressions and records calls to one exact function name without copying the surrounding Blueprint bodies. The artifact reports complete or partial coverage, scan totals, call-site metadata, and package failure types.
dotnet run --project $extractor -- blueprint-call-sites `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--static-census (Join-Path $buildDirectory "static-census.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--target-function "Get Random List Of Cartridges From Rent List" `
--output (Join-Path $buildDirectory "blueprint-call-sites.movie-return.json")dotnet run --project "$extractor" -- blueprint-call-sites \
--build-manifest "$buildDirectory/build-manifest.json" \
--static-census "$buildDirectory/static-census.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--target-function "Get Random List Of Cartridges From Rent List" \
--output "$buildDirectory/blueprint-call-sites.movie-return.json"The output contains game-specific caller locations and must remain in the ignored local acquisition directory.
This step accepts only a complete call-site artifact for the same build and mappings. It rechecks every recorded call and decompiles only the functions that contain them.
dotnet run --project $extractor -- blueprint-caller-bodies `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--call-sites (Join-Path $buildDirectory "blueprint-call-sites.movie-return.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "blueprint-caller-bodies.movie-return.json")dotnet run --project "$extractor" -- blueprint-caller-bodies \
--build-manifest "$buildDirectory/build-manifest.json" \
--call-sites "$buildDirectory/blueprint-call-sites.movie-return.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/blueprint-caller-bodies.movie-return.json"The output contains game-specific function bodies and must remain in the ignored local acquisition directory.
This step searches the same complete Blueprint package set for calls to the customer function discovered by the movie-return scan. It determines whether another Blueprint function invokes that customer function before any broader event or native-boundary investigation.
dotnet run --project $extractor -- blueprint-call-sites `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--static-census (Join-Path $buildDirectory "static-census.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--target-function "Initial creation - Get if I have Product to return" `
--output (Join-Path $buildDirectory "blueprint-call-sites.movie-customer-entry.json")dotnet run --project "$extractor" -- blueprint-call-sites \
--build-manifest "$buildDirectory/build-manifest.json" \
--static-census "$buildDirectory/static-census.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--target-function "Initial creation - Get if I have Product to return" \
--output "$buildDirectory/blueprint-call-sites.movie-customer-entry.json"The output contains game-specific caller locations and must remain in the ignored local acquisition directory.
This step verifies the complete customer-entry call-site artifact and decompiles only the event-graph function that contains its call. The result exposes the entry label and control flow immediately surrounding the movie-customer function.
dotnet run --project $extractor -- blueprint-caller-bodies `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--call-sites (Join-Path $buildDirectory "blueprint-call-sites.movie-customer-entry.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "blueprint-caller-bodies.movie-customer-entry.json")dotnet run --project "$extractor" -- blueprint-caller-bodies \
--build-manifest "$buildDirectory/build-manifest.json" \
--call-sites "$buildDirectory/blueprint-call-sites.movie-customer-entry.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/blueprint-caller-bodies.movie-customer-entry.json"The output contains game-specific event-graph pseudocode and must remain in the ignored local acquisition directory.
This step searches the complete Blueprint package set for wrapper functions that call the AI client ubergraph. The resulting wrapper list can then be decompiled to identify which numeric entry point each wrapper supplies.
dotnet run --project $extractor -- blueprint-call-sites `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--static-census (Join-Path $buildDirectory "static-census.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--target-function "ExecuteUbergraph_AI_Client_Character" `
--output (Join-Path $buildDirectory "blueprint-call-sites.ai-client-ubergraph.json")dotnet run --project "$extractor" -- blueprint-call-sites \
--build-manifest "$buildDirectory/build-manifest.json" \
--static-census "$buildDirectory/static-census.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--target-function "ExecuteUbergraph_AI_Client_Character" \
--output "$buildDirectory/blueprint-call-sites.ai-client-ubergraph.json"The output contains game-specific wrapper locations and must remain in the ignored local acquisition directory.
This step verifies the preceding call-site artifact and decompiles the exact wrapper functions it found. The result maps each wrapper to the numeric entry point it passes into the AI client event graph.
dotnet run --project $extractor -- blueprint-caller-bodies `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--call-sites (Join-Path $buildDirectory "blueprint-call-sites.ai-client-ubergraph.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "blueprint-caller-bodies.ai-client-ubergraph.json")dotnet run --project "$extractor" -- blueprint-caller-bodies \
--build-manifest "$buildDirectory/build-manifest.json" \
--call-sites "$buildDirectory/blueprint-call-sites.ai-client-ubergraph.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/blueprint-caller-bodies.ai-client-ubergraph.json"The output contains game-specific wrapper pseudocode and must remain in the ignored local acquisition directory.
This step rereads the exact functions in the three caller-body artifacts from cooked Kismet bytecode. It writes typed nodes for calls, call arguments, branches, jumps, assignments, variables, symbols, literals, contexts, and returns. Each input file is recorded by hash, and the command confirms that its functions and target calls still match the game package.
dotnet run --project $extractor -- blueprint-function-trace `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--caller-bodies (Join-Path $buildDirectory "blueprint-caller-bodies.ai-client-ubergraph.json") `
--caller-bodies (Join-Path $buildDirectory "blueprint-caller-bodies.movie-customer-entry.json") `
--caller-bodies (Join-Path $buildDirectory "blueprint-caller-bodies.movie-return.json") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "blueprint-function-trace.movie-customer.json")dotnet run --project "$extractor" -- blueprint-function-trace \
--build-manifest "$buildDirectory/build-manifest.json" \
--caller-bodies "$buildDirectory/blueprint-caller-bodies.ai-client-ubergraph.json" \
--caller-bodies "$buildDirectory/blueprint-caller-bodies.movie-customer-entry.json" \
--caller-bodies "$buildDirectory/blueprint-caller-bodies.movie-return.json" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/blueprint-function-trace.movie-customer.json"The output contains game-specific bytecode structure and must remain in the ignored local acquisition directory.
This step rereads four exact RentSystem functions from cooked Kismet bytecode.
The rental Blueprint-body artifact supplies the expected package, class, function paths, flags, and bytecode-expression counts.
The command verifies that source artifact, the build, the mappings, and the game packages before and after extraction.
$rentSystemClass = "RetroRewind/Content/VideoStore/core/blueprint/RentSystem/RentSystem.RentSystem_C:"
dotnet run --project $extractor -- rental-function-trace `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--rental-blueprint-bodies (Join-Path $buildDirectory "rental-blueprint-bodies.json") `
--function-path ($rentSystemClass + "Weather - New Day Event") `
--function-path ($rentSystemClass + "Get Movie ready for return") `
--function-path ($rentSystemClass + "ExecuteUbergraph_RentSystem") `
--function-path ($rentSystemClass + "Get Random List Of Cartridges From Rent List") `
--mappings $mappings `
--package-directory $packageDirectory `
--output (Join-Path $buildDirectory "rental-function-trace.movie-return.json")rentSystemClass="RetroRewind/Content/VideoStore/core/blueprint/RentSystem/RentSystem.RentSystem_C:"
dotnet run --project "$extractor" -- rental-function-trace \
--build-manifest "$buildDirectory/build-manifest.json" \
--rental-blueprint-bodies "$buildDirectory/rental-blueprint-bodies.json" \
--function-path "${rentSystemClass}Weather - New Day Event" \
--function-path "${rentSystemClass}Get Movie ready for return" \
--function-path "${rentSystemClass}ExecuteUbergraph_RentSystem" \
--function-path "${rentSystemClass}Get Random List Of Cartridges From Rent List" \
--mappings "$mappings" \
--package-directory "$packageDirectory" \
--output "$buildDirectory/rental-function-trace.movie-return.json"The output contains game-specific bytecode structure and must remain in the ignored local acquisition directory.
This step validates both rental artifacts and confirms the expected class, fields, defaults, functions, and decompiled expressions before writing normalized facts.
The artifact records the configured rental duration, the eligibility comparison, the missing-weather result, and movement from the rented queue to the ready-to-return queue.
Each fact points back to its source class, property, or function.
The evidence level remains decompiled-blueprint, and runtime validation remains not-run.
Move into the TypeScript workspace if you are not already there.
Push-Location projects/typescript
pnpm install --frozen-lockfilepushd projects/typescript >/dev/null
pnpm install --frozen-lockfileCompile the private mechanic artifact.
pnpm console-return-mechanics `
--rental-evidence (Join-Path $buildDirectory "rental-evidence.json") `
--rental-evidence-schema "../game-data-exporter/schemas/acquisition/rental-evidence.schema.json" `
--blueprint-bodies (Join-Path $buildDirectory "rental-blueprint-bodies.json") `
--blueprint-bodies-schema "../game-data-exporter/schemas/acquisition/rental-blueprint-bodies.schema.json" `
--output (Join-Path $domainDirectory "console-return-mechanics.json")pnpm console-return-mechanics \
--rental-evidence "$buildDirectory/rental-evidence.json" \
--rental-evidence-schema "../game-data-exporter/schemas/acquisition/rental-evidence.schema.json" \
--blueprint-bodies "$buildDirectory/rental-blueprint-bodies.json" \
--blueprint-bodies-schema "../game-data-exporter/schemas/acquisition/rental-blueprint-bodies.schema.json" \
--output "$domainDirectory/console-return-mechanics.json"Return to the repository root when the command finishes.
Pop-Locationpopd >/dev/nullThe output contains normalized game rules and remains private and uncommitted.
This step uses the same two private rental artifacts as the console-return compiler.
It confirms the membership fee map, the five-field fee record, both mutation functions, and their decompiled expressions.
The result records how membership ID zero is handled, which fee counters accumulate, which counters are cleared, and how a fee record is removed.
Each fact points back to its source class field, struct field, or function.
The evidence level remains decompiled-blueprint, and runtime validation remains not-run.
Move into the TypeScript workspace if you are not already there.
Push-Location projects/typescript
pnpm install --frozen-lockfilepushd projects/typescript >/dev/null
pnpm install --frozen-lockfileCompile the private mechanic artifact.
pnpm membership-fee-mechanics `
--rental-evidence (Join-Path $buildDirectory "rental-evidence.json") `
--rental-evidence-schema "../game-data-exporter/schemas/acquisition/rental-evidence.schema.json" `
--blueprint-bodies (Join-Path $buildDirectory "rental-blueprint-bodies.json") `
--blueprint-bodies-schema "../game-data-exporter/schemas/acquisition/rental-blueprint-bodies.schema.json" `
--output (Join-Path $domainDirectory "membership-fee-mechanics.json")pnpm membership-fee-mechanics \
--rental-evidence "$buildDirectory/rental-evidence.json" \
--rental-evidence-schema "../game-data-exporter/schemas/acquisition/rental-evidence.schema.json" \
--blueprint-bodies "$buildDirectory/rental-blueprint-bodies.json" \
--blueprint-bodies-schema "../game-data-exporter/schemas/acquisition/rental-blueprint-bodies.schema.json" \
--output "$domainDirectory/membership-fee-mechanics.json"Return to the repository root when the command finishes.
Pop-Locationpopd >/dev/nullThe output contains normalized game rules and remains private and uncommitted.
This step uses the two private rental artifacts, the complete movie-selector call-site artifact, the extracted caller-body artifact, and both typed function traces.
It traces the new-day event through its Blueprint dispatcher and confirms that all rented movies move into the ready-to-return queue before the rented queue is cleared.
It separately records the weighted selector's configured probabilities, override condition, four-item limit, candidate queue, and result behavior.
It records complete caller-search coverage, the BeginPlay entry path, the console-first customer branch, both selector calls, and movement of selected cartridges from the ready queue into customer inventory.
The compiler validates calls, arguments, branch targets, branch symbols, queue operations, selection outcomes, loop structure, and input hashes from the typed traces.
It does not parse rental or customer-flow pseudocode.
The evidence level remains decompiled-blueprint, and runtime validation remains not-run.
Move into the TypeScript workspace if you are not already there.
Push-Location projects/typescript
pnpm install --frozen-lockfilepushd projects/typescript >/dev/null
pnpm install --frozen-lockfileCompile the private mechanic artifact.
pnpm movie-return-mechanics `
--rental-evidence (Join-Path $buildDirectory "rental-evidence.json") `
--rental-evidence-schema "../game-data-exporter/schemas/acquisition/rental-evidence.schema.json" `
--blueprint-bodies (Join-Path $buildDirectory "rental-blueprint-bodies.json") `
--blueprint-bodies-schema "../game-data-exporter/schemas/acquisition/rental-blueprint-bodies.schema.json" `
--call-sites (Join-Path $buildDirectory "blueprint-call-sites.movie-return.json") `
--call-sites-schema "../game-data-exporter/schemas/acquisition/blueprint-call-sites.schema.json" `
--caller-bodies (Join-Path $buildDirectory "blueprint-caller-bodies.movie-return.json") `
--caller-bodies-schema "../game-data-exporter/schemas/acquisition/blueprint-caller-bodies.schema.json" `
--function-trace (Join-Path $buildDirectory "blueprint-function-trace.movie-customer.json") `
--function-trace-schema "../game-data-exporter/schemas/acquisition/blueprint-function-trace.schema.json" `
--rental-function-trace (Join-Path $buildDirectory "rental-function-trace.movie-return.json") `
--rental-function-trace-schema "../game-data-exporter/schemas/acquisition/rental-function-trace.schema.json" `
--output (Join-Path $domainDirectory "movie-return-mechanics.json")pnpm movie-return-mechanics \
--rental-evidence "$buildDirectory/rental-evidence.json" \
--rental-evidence-schema "../game-data-exporter/schemas/acquisition/rental-evidence.schema.json" \
--blueprint-bodies "$buildDirectory/rental-blueprint-bodies.json" \
--blueprint-bodies-schema "../game-data-exporter/schemas/acquisition/rental-blueprint-bodies.schema.json" \
--call-sites "$buildDirectory/blueprint-call-sites.movie-return.json" \
--call-sites-schema "../game-data-exporter/schemas/acquisition/blueprint-call-sites.schema.json" \
--caller-bodies "$buildDirectory/blueprint-caller-bodies.movie-return.json" \
--caller-bodies-schema "../game-data-exporter/schemas/acquisition/blueprint-caller-bodies.schema.json" \
--function-trace "$buildDirectory/blueprint-function-trace.movie-customer.json" \
--function-trace-schema "../game-data-exporter/schemas/acquisition/blueprint-function-trace.schema.json" \
--rental-function-trace "$buildDirectory/rental-function-trace.movie-return.json" \
--rental-function-trace-schema "../game-data-exporter/schemas/acquisition/rental-function-trace.schema.json" \
--output "$domainDirectory/movie-return-mechanics.json"Return to the repository root when the command finishes.
Pop-Locationpopd >/dev/nullThe output contains normalized game rules and remains private and uncommitted.
The TypeScript compiler validates the structured-values artifact against its JSON Schema. It maps the 13 catalog DataTables into film records and retains the source table path and row key for each record. The game's numeric SKU is the unique film key, and records are written in ascending SKU order. Two auxiliary tables reuse the same Unreal row structure and are explicitly excluded from the film catalog.
Move into the TypeScript workspace and install its locked dependencies.
Push-Location projects/typescript
pnpm install --frozen-lockfilepushd projects/typescript >/dev/null
pnpm install --frozen-lockfileCompile the catalog into the ignored local domain directory.
pnpm film-catalog `
--input (Join-Path $buildDirectory "structured-values.json") `
--input-schema "../game-data-exporter/schemas/acquisition/structured-values.schema.json" `
--output (Join-Path $domainDirectory "film-catalog.json")pnpm film-catalog \
--input "$buildDirectory/structured-values.json" \
--input-schema "../game-data-exporter/schemas/acquisition/structured-values.schema.json" \
--output "$domainDirectory/film-catalog.json"Return to the repository root when the command finishes.
Pop-Locationpopd >/dev/nullThe compiler creates missing output directories, accepts identical existing output, and refuses to overwrite different content. The film catalog still contains extracted game text and remains private and uncommitted.
This command verifies the game executable against the supplied private build manifest and checks the exact UE4SS archive before creating an ignored local staging directory. It checks that the game is closed and that neither proposed game-directory file already exists. It does not copy anything into the game directory.
Set the paths to the private inputs and choose a new staging directory.
$runtimeExporter = "projects/game-data-exporter/runtime-exporter/NeonRewind.RuntimeExporter.csproj"
$ue4ssArchive = "C:\path\to\zDEV-UE4SS_v3.0.1-1018-g662df915.zip"
$probeScript = "projects/game-data-exporter/runtime-exporter/Probe/NeonRewindMovieReturnProbe/Scripts/main.lua"
$runtimeStageId = (Get-Date).ToUniversalTime().ToString("yyyyMMddTHHmmssZ")
$runtimeStage = "projects/game-data-exporter/.local/runtime-host/runs/$runtimeStageId/probe"
New-Item -ItemType Directory -Force -Path (Split-Path $runtimeStage) | Out-NullruntimeExporter="projects/game-data-exporter/runtime-exporter/NeonRewind.RuntimeExporter.csproj"
ue4ssArchive="C:\path\to\zDEV-UE4SS_v3.0.1-1018-g662df915.zip"
probeScript="projects/game-data-exporter/runtime-exporter/Probe/NeonRewindMovieReturnProbe/Scripts/main.lua"
runtimeStageId="$(date -u +%Y%m%dT%H%M%SZ)"
runtimeStage="projects/game-data-exporter/.local/runtime-host/runs/$runtimeStageId/probe"
mkdir -p "$(dirname "$runtimeStage")"Run the staging command while the game is closed.
dotnet run --project $runtimeExporter -- stage-probe `
--ue4ss-archive $ue4ssArchive `
--build-manifest (Join-Path $buildDirectory "build-manifest.json") `
--game-executable $executable `
--probe-script $probeScript `
--output $runtimeStagedotnet run --project "$runtimeExporter" -- stage-probe \
--ue4ss-archive "$ue4ssArchive" \
--build-manifest "$buildDirectory/build-manifest.json" \
--game-executable "$executable" \
--probe-script "$probeScript" \
--output "$runtimeStage"Review runtime-host-staging.json in the new staging directory.
It identifies the private inputs and lists the exact size and SHA-256 hash of the proposed dwmapi.dll and override.txt files.
Preview installation while the game is closed.
$stagingManifest = Join-Path $runtimeStage "runtime-host-staging.json"
dotnet run --project $runtimeExporter -- install-probe `
--staging-manifest $stagingManifeststagingManifest="$runtimeStage/runtime-host-staging.json"
dotnet run --project "$runtimeExporter" -- install-probe \
--staging-manifest "$stagingManifest"The preview prints both source and destination paths, byte lengths, file hashes, and the staging-manifest hash.
It exits with code 5 because approval was not supplied, and it does not copy either file.
Review the output, copy the displayed staging-manifest hash into $approvedStagingSha256, and rerun only when you approve that exact list.
$approvedStagingSha256 = "paste-the-reviewed-staging-manifest-sha256"
dotnet run --project $runtimeExporter -- install-probe `
--staging-manifest $stagingManifest `
--approve-staging-sha256 $approvedStagingSha256approvedStagingSha256="paste-the-reviewed-staging-manifest-sha256"
dotnet run --project "$runtimeExporter" -- install-probe \
--staging-manifest "$stagingManifest" \
--approve-staging-sha256 "$approvedStagingSha256"The approved command creates runtime-host-installation.json in the staging directory before copying the two files.
It refuses existing targets unless it is resuming the same manifest after an interrupted installation.
The tooling does not launch the game or Steam.
After using the probe, close the game before previewing cleanup.
$installationManifest = Join-Path $runtimeStage "runtime-host-installation.json"
dotnet run --project $runtimeExporter -- cleanup-probe `
--installation-manifest $installationManifestinstallationManifest="$runtimeStage/runtime-host-installation.json"
dotnet run --project "$runtimeExporter" -- cleanup-probe \
--installation-manifest "$installationManifest"The cleanup preview recalculates both installed file hashes and exits with code 5 without removing anything.
Review the exact removal list, copy the displayed installation-manifest hash into $approvedInstallationSha256, and rerun only when you approve that exact list.
$approvedInstallationSha256 = "paste-the-reviewed-installation-manifest-sha256"
dotnet run --project $runtimeExporter -- cleanup-probe `
--installation-manifest $installationManifest `
--approve-installation-sha256 $approvedInstallationSha256approvedInstallationSha256="paste-the-reviewed-installation-manifest-sha256"
dotnet run --project "$runtimeExporter" -- cleanup-probe \
--installation-manifest "$installationManifest" \
--approve-installation-sha256 "$approvedInstallationSha256"Cleanup removes dwmapi.dll first and then removes override.txt.
It stops before removal if the game is running, either file is missing, or either path or hash differs from the installation manifest.
The ignored installation manifest remains as the local record of the approved copy.
Check $steamRoot, then run the path setup block again.
Paths containing spaces are safe when passed through the variables shown above.
The artifact commands never replace different existing content. Use a new build directory for a different game build or choose a new output filename.
Confirm that the .usmap file came from the same game executable as the build manifest.
The repository cannot repair or convert a mapping from another build.
Install pnpm 11.x, open a new PowerShell or Git Bash window, and run pnpm --version again.
projects/game-data-exporter/static-extractorcontains the .NET 10 acquisition commands.projects/game-data-exporter/schemas/acquisitioncontains the acquisition JSON Schemas.projects/game-data-exporter/schemas/runtimecontains the runtime observation JSON Schemas.projects/game-data-exporter/schemas/validationcontains the validation-report JSON Schemas.projects/game-data-exporter/runtime-exportercontains the offline runtime-host staging command and Lua compatibility probe source.projects/game-data-exporter/runtime-collectorcontains the load-only UE4SS C++ collector and its local Windows build entry points.- Movie-return runtime observation defines the first runtime test and the limits on its future collector.
projects/typescript/packages/coreowns the normalized domain types and schemas.projects/typescript/packages/data-compilervalidates acquisition data and compiles private domain artifacts.projects/typescript/packages/validatorchecks ordered runtime observations against deterministic mechanic relationships.
Original NeonRewind source code is licensed under the Apache License 2.0. NeonRewind is provided as is, without warranty of any kind, to the extent permitted by applicable law. The licence contains the complete warranty disclaimer and limitation of liability.
NeonRewind is an unofficial fan project and is not affiliated with or endorsed by the developers or publishers of Retro Rewind: Video Store Simulator. The game and its related names and assets belong to their respective owners.