Wasteland Survival Guide Mojave Edition

Fallout: New Vegas77 views1 favorites33 min readby prone2damageUpdated 26 JanView on Steam ↗

Foreward

Before You Open This Book and Blame Me

VAULT-TEC CORPORATION
Public Information Division
Approved Educational Material

This publication was produced in accordance with Vault-Tec standards
for clarity, reassurance, and public confidence.
All information contained herein reflects system behavior as
designed, anticipated, and approved. Variations in outcome do not
indicate malfunction and should not be interpreted as such.
Unauthorized duplication, annotation, revision, or contextual
reinterpretation of this material is discouraged.
Vault-Tec assumes no responsibility for independent conclusions drawn
from this publication.
Printed in advance of need.
Distributed in good faith.
Archived for continuity.
Vault-Tec remains committed to preparedness
ARCHIVAL ADDENDUM
Filed Separately, For Context

— Scribe Devin Stoffers
Followers of the Apocalypse, Mojave Chapter

This document was not discovered because we were looking for it.
It was found because a door that should not have opened did.
The location was a Vault-Tec archival sublevel beneath an installation
whose surface structures no longer exist. Power was intermittent. Air
circulation was nominal. The terminal logs ended mid-sentence and did not
resume. None of this was unusual.
What was unusual was that the records were intact.
The document you are about to read was stored as approved public material,
redundantly archived, and marked complete. No revision notices were
attached. No errata were filed. It was filed as finished long before the
world had any opportunity to disagree with it.
Most Vault-Tec publications degrade quickly once exposed to reality. This
one did not. It was confident enough to survive unchanged.
The Followers debated whether to discard it.
In the end, we chose to preserve it exactly as written. Altering the
original text would have made it easier to read and harder to understand.
Vault-Tec documents are not valuable because they explain how things work.
They are valuable because they explain how things were assumed to work, and
how those assumptions were defended long after evidence accumulated to the
contrary.
Additions to this document are minimal and clearly separated. They exist
only to describe mechanisms the original text treats as outcomes, and to
record consequences the original text considers acceptable.
No attempt has been made to correct the tone. That tone is part of the
record.
If you find sections where the assurances feel detached from your
experience, that is not a failure of preservation. That is the document
functioning as intended.
This guide is presented as it was found, with only enough context added to
make it survivable to read.
The rest is up to you.
- Devin Stoffers
Senior Scribe
Followers of the Apocalypse
Mojave Chapter

Table of Contents

WASTELAND SURVIVAL GUIDE
MOJAVE EDITION


TABLE OF CONTENTS

FOREWORD
Before You Open This Book and Blame Me

INTRODUCTION
How to Survive the Mojave When the World Is Held Together by Assumptions

PART I
THE ENGINE DOES NOT LOVE YOU

Why Don’t You Do Right
Memory management, fragmentation, and heap behavior

Ain’t That a Kick in the Head
Script VM scheduling, execution order, and starvation

Big Iron
NVSE plugin architecture, native hooks, and interoperability patterns

PART II
WHEN THINGS MOVE AND EVERYTHING STOPS

Johnny Guitar
Animation graph execution, state machines, and deadlock conditions

Gun Crazy
Weapon script execution paths, firing logic, and combat timing

Blue Moon
UI pipeline behavior, menu initialization, and input deadlocks

PART III
THE PAST NEVER STAYS BURIED

Heartaches by the Number
Save serialization internals and record persistence

Something’s Gotta Give
Quest system execution, alias binding, and irreversible state

Crazy He Calls Me
AI package corruption and behavioral collapse

PART IV
THE WORLD IS STREAMING AND IT KNOWS IT


I Got Spurs (That Jingle Jangle Jingle)
Cell transitions, world streaming, and load phase failure

In the Shadow of the Valley
World state accumulation and long-term degradation

PART V
HOW TO FIGURE OUT WHAT YOU BROKE


Let’s Ride into the Sunset Together
Diagnostic decision trees and failure classification

It’s a Sin
Forensic workflows and controlled isolation

Hangover Heart
Save hygiene strategies for long playthroughs

PART VI
DOING THIS ON PURPOSE



You Let the Blues In
Mod interaction taxonomy and overlap risk

Love Me as Though There Were No Tomorrow
Building a stable mod stack intentionally

Where Have You Been All My Life?
Why New Vegas degrades over time even without mods

APPENDICES
Appendix A
Things You Can Remove Mid-Save Without Immediately Ruining Your Life
Appendix B
Things You Absolutely Cannot Remove Mid-Save No Matter What Reddit Says
Appendix C
Glossary of Terms You Learned the Hard Way
Appendix D
Known Lies the Engine Tells You Repeatedly
AFTERWORD
You Survived the Mojave. The Save Might Not Have

Introduction

How to Survive the Mojave When the World is Held Together by Assumptions

Authored by
Senior Scribe Devin Stoffers
Followers of the Apocalypse, Mojave Chapter

If you are reading this, one of three things has happened.
First possibility: you are new to the Mojave and still believe the world
operates according to rules, logic, and good intentions. If this is the
case, I envy you. That feeling will not last.
Second possibility: you have been here a while and have noticed that
sometimes reality pauses. Not dramatically. Not explosively. Just… stops.
The wind keeps blowing. The radio keeps playing. But the world itself seems
to stare into the middle distance and forget what it was doing. You have
begun to suspect that this is not your fault.
Third possibility: you already know exactly why you’re here, and you’re
hoping this book will confirm what you’ve been muttering under your breath
for hours: that the Mojave is held together by assumptions, and those
assumptions are fragile.
This document exists for the second and third group.
Despite what the Vault-Tec pamphlets say, survival in the Mojave is not
primarily about radiation, raiders, or even cazadores. It is about
understanding how the world decides to function, how it remembers what has
happened, and how it reacts when too many things demand attention at once.
Most people call this “bad luck.” Engineers call it “systems under load.”
The Followers spent years cataloging old-world technical manuals,
simulation notes, and half-burned documentation recovered from places no
one sensible would crawl into. What we found was not a master plan. It was
a pile of interdependent systems that were never meant to be pushed this
hard, this long, or this creatively.
This book is not a training manual. It will not teach you how to be clever.
It will not teach you how to be safe. It will, however, explain why certain
choices eventually result in the Mojave freezing mid-thought, why the past
has a habit of coming back corrupted, and why removing “just one thing”
often makes everything worse.
Contained within these pages are field notes on how the world allocates its
attention, how it schedules thought, how it remembers the dead, and how it
reacts when you cross invisible lines at inconvenient times. You will learn
why weapons sometimes forget how to fire, why people forget how to move,
why doors remember things you wish they wouldn’t, and why restarting your
day often fixes problems that no amount of arguing ever will.
Each chapter is framed as a song because the Mojave has a sense of humor,
and because repetition helps memory. The titles are jokes. The contents are
not. If something in this book sounds fatalistic, that is because optimism
does not survive prolonged exposure to reality.
This guide assumes you are already alive. It assumes you will continue
making choices. It assumes you will occasionally push the world harder than
it wants to be pushed. What it offers is an explanation of the consequences
before you meet them in the worst possible way.
If you are looking for comfort, close this book now.
If you are looking to understand why the Mojave behaves the way it does,
continue onward.
And if the world stops responding halfway through, do not panic.
That just means you’ve learned something.
— Scribe Devin Stoffers
Followers of the Apocalypse
Mojave Chapter, what’s left of it

Part One

PART ONE | THE ENGINE DOES NOT LOVE YOU

VAULT-TEC PUBLIC ASSURANCE NOTICE

Vault-Tec confirms that the systems described in the following
section are operating normally.
Reports of memory loss, hesitation, confusion, or sudden immobility
are anecdotal and may be the result of user expectations exceeding
system intent.
Vault-Tec reminds residents that confidence improves outcomes.

ANNOTATION – D. STOFFERS
Vault-Tec uses the word “normal” the way doctors use “stable.”
It means the condition is understood, not that it is improving.
What follows describes systems that function exactly as designed, provided
they are never stressed, questioned, or used creatively.
None of those conditions are realistic.

Why Don't You Do Right? -Memory Management, Fragmentation and Heap Behavior

Fallout New Vegas memory behavior is dominated by three constraints: a 32 bit address space, legacy allocator design, and long lived runtime state that was never intended to be continuously mutated by external code. Memory related instability in New Vegas is rarely a single out of memory event. It is almost always fragmentation, allocator exhaustion, or invalid lifetime assumptions that manifest as freezes, stutter, or delayed crashes.

As a 32 bit process, New Vegas is limited to a finite virtual address space. The four gigabyte patch
marks the executable as large address aware, allowing access to a larger portion of that space, but it does not change how the engine allocates or frees memory internally. The engine still uses allocation strategies designed for much smaller working sets. This mismatch is the root of most modern memory problems.

The engine relies on several heaps rather than a single unified allocator. Different subsystems allocate from different pools, often with fixed size blocks or assumptions about allocation patterns. Rendering, scripting, AI, animation, and audio do not all share the same allocation behavior. Some pools are long lived. Others are churn heavy. The engine assumes predictable lifetimes. Modding breaks those assumptions by introducing unpredictable allocation and deallocation patterns.
Fragmentation occurs when memory is allocated and freed in patterns that leave unusable gaps. The engine may technically have free memory, but not in contiguous blocks large enough to satisfy new allocations. Many engine allocation requests require contiguous memory. When these requests fail, the engine does not always crash. Instead, it may retry, defer, or substitute fallback logic. This produces stutter, pauses, or freezes rather than immediate termination.

Texture mods are a primary fragmentation driver. High resolution textures allocate large contiguous blocks. When textures are streamed in and out during cell transitions, the engine allocates and frees these blocks repeatedly. If other systems allocate memory in between, the heap becomes fragmented.
Later, when a large texture or mesh needs to load, there may not be a contiguous block available even though total free memory appears sufficient. The engine may then stall while attempting to satisfy the request.
Scripts contribute indirectly to fragmentation. Script instances allocate small objects frequently.
Variables, arrays, strings, and temporary buffers are allocated and freed constantly. This churn increases fragmentation in small object heaps. Over time, script heavy saves accumulate fragmented memory even if total script count remains stable. This explains why long sessions degrade even without adding new mods.

NVSE plugins introduce native allocations that bypass engine assumptions. Plugins may use the C
runtime allocator or custom allocators. If plugin allocated memory is interleaved with engine allocated memory, fragmentation worsens. Worse, if plugins allocate memory and do not free it properly on revert or unload, memory leaks occur. In a long session, leaks compound fragmentation until allocation failures become frequent.
Animation systems also stress memory. Animation graphs, blend trees, and state machines allocate temporary structures during evaluation. If animation mods increase complexity or number of active animations, allocation frequency increases. Because animation evaluation occurs every frame, small inefficiencies multiply rapidly. When memory pressure rises, animation update time increases, contributing to frame stalls and eventual freezes.
Audio buffers behave differently. Audio is often buffered ahead of time and managed by separate
subsystems. This is why audio continues during freezes. Audio memory may still be serviced while the main loop stalls waiting on memory allocation or logic progression. The presence of looping audio is a symptom that audio allocation and playback are not the failing subsystem.

Cell transitions are peak memory events. When entering a new cell, the engine loads new meshes,
textures, scripts, AI data, and references while unloading others. This creates a burst of allocations and frees. If fragmentation is severe, the engine may not be able to allocate required structures. Instead of crashing, it may stall attempting to load assets or retry allocation. This produces freezes during loading screens or immediately after entering populated areas.
The heap behavior also interacts with timing. Allocation failures or slow allocations increase frame
time. Increased frame time reduces animation and script update frequency. Reduced update frequency can prevent time based conditions from advancing. This feeds back into animation and script deadlocks. Memory pressure therefore indirectly causes logic deadlocks that appear unrelated to memory.

Garbage collection in New Vegas is minimal. The engine does not aggressively reclaim memory or
compact heaps. Once fragmented, heaps remain fragmented for the lifetime of the process. Restarting the game clears fragmentation. This is why restarting often “fixes” instability temporarily. The underlying save or mod configuration may be unchanged. The heap state is reset.
This behavior explains why players report that stability degrades over time even in stable setups.
Fragmentation accumulates during gameplay. Long sessions, frequent fast travel, heavy combat, and menu usage all contribute. The engine does not self heal.
Timing fix plugins mitigate some symptoms by smoothing frame pacing and preventing runaway time deltas, but they do not fix fragmentation. In some cases they mask fragmentation by reducing allocation pressure. In others they exacerbate it by altering update frequency. This is why timing related plugins must be chosen carefully and not stacked.
Memory related freezes often lack logs because allocation failure is not always treated as an error. The engine may receive a null pointer or an error code and enter fallback logic. That fallback logic may loop, wait, or retry indefinitely. From the OS perspective, the process is responsive. From the engine perspective, it is stuck.
Diagnosing memory fragmentation relies on temporal and contextual clues. Freezes that occur after long sessions, during loading screens, or when entering new areas implicate memory.

Freezes that disappear after restarting the game without changing mods strongly implicate fragmentation. Freezes that correlate with adding high resolution textures or increasing draw distance further support this diagnosis. Mitigation strategies focus on reducing allocation churn and peak memory demand. This includes avoiding excessive texture resolution beyond what the engine can manage, minimizing script heavy mods that allocate frequently, limiting the number of concurrent animation frameworks, and restarting the game periodically. Stable mod stacks also minimize runtime allocation spikes by avoiding mods that dynamically spawn large numbers of objects.

From a professional standpoint, New Vegas memory behavior is deterministic given workload. It is not random. Fragmentation is a cumulative structural problem. Once understood, its symptoms become predictable.

Memory management, fragmentation, and heap behavior form the invisible substrate beneath all other instability. Many freezes blamed on scripts, AI, or animations are triggered by memory pressure that prevents those systems from progressing. Understanding this layer completes the picture of why New
Vegas behaves the way it does under modern modding loads.

Ain't That a Kick in the Head -Script VM Scheduling, Execution Order and Starvation

Fallout New Vegas scripting is executed by a virtual machine integrated into the main game loop. This
VM is cooperative, single threaded, and non preemptive. It does not time slice fairly across scripts in
the way a modern managed runtime would. Instead, scripts execute until they yield, terminate, or are
forcibly paused by engine state changes. This design decision is foundational to understanding script
starvation and long tail instability.
The VM executes script instructions during the main loop update. Each frame, the engine processes a
set of active scripts. These include quest scripts, object scripts, actor scripts, magic effect scripts, and
NVSE extended scripts. The engine assumes that scripts are short lived and well behaved. There is no
hard enforcement of execution quotas per script beyond basic yield semantics such as Wait or frame
based yielding. If scripts violate these assumptions, they can dominate execution time.
Script starvation occurs when one or more scripts consume a disproportionate share of VM execution
time, preventing other scripts and sometimes core engine systems from progressing. Because the VM is
part of the main loop, heavy script load directly reduces frame time available for AI, animation, and
input processing. Unlike crashes, starvation produces gradual degradation. The game may appear
functional while responsiveness, animation smoothness, and combat reliability deteriorate over time.
Polling loops are the most common cause of starvation. A polling loop is a script structure that
repeatedly checks a condition each frame or at very short intervals. Typical patterns include while loops
that check weapon state, animation state, actor distance, or menu state without a sufficiently long wait.
Even a small loop that yields every frame can become catastrophic when multiplied across many
instances. For example, a weapon script that polls reload state every frame may be fine for one weapon,
but disastrous when attached to dozens of NPCs.
Quest scripts are particularly dangerous because they persist for the lifetime of the save. A quest script
that polls continuously will run forever. If such a script is added mid playthrough, its load accumulates.
If multiple quest mods introduce similar behavior, the VM load increases non linearly. The engine does
not prioritize or throttle scripts. All active scripts compete equally, and heavy ones crowd out lighter
ones.
Magic effect scripts introduce another vector. These scripts are attached to effects that can apply to
many actors simultaneously. An effect script that runs per frame on every affected actor scales with
population density. In combat heavy scenarios, this can explode script load. Because effect scripts often
run during combat, starvation frequently coincides with combat freezes or severe lag rather than
immediate crashes.
NVSE extends scripting capabilities but also increases risk. NVSE exposes additional functions that
allow scripts to query engine state more frequently or with more detail. This encourages polling based
designs rather than event driven designs. Scripts that call expensive NVSE functions repeatedly can
significantly increase VM execution cost. Unlike native code, scripts do not have direct access to
performance counters, so authors may not realize how expensive their logic is.
Event driven scripting is safer but still hazardous if misused. Scripts that register for frequent events,
such as OnUpdate or animation related callbacks, can flood the VM with work. If event handlers
perform heavy logic or chain into additional script calls, the effective cost per frame increases
dramatically. The VM does not collapse or coalesce events intelligently. Each event is processed
independently.
Script execution order is not guaranteed to be fair. The engine iterates through active scripts in an
internal order that is stable but opaque. A script earlier in the list that consumes too much time can
starve scripts later in the list. This produces non obvious behavior where some scripts appear to stop
working entirely while others continue. From the player perspective, features randomly break. From the
engine perspective, they are simply never scheduled.
Starvation interacts strongly with animation and weapon systems. Scripts that wait on animation
completion may poll for animation state each frame. If animation completion is delayed or never
occurs, the script continues polling forever. This not only blocks the script’s own progression but also
consumes VM time indefinitely. In extreme cases, the polling script itself prevents animation from
advancing by consuming too much frame time, creating a self reinforcing stall.
Another starvation mechanism is script accumulation. Scripts are often instantiated dynamically and
not destroyed correctly. For example, an OnEquip script that spawns a helper script instance and never
cleans it up. Over time, thousands of script instances may accumulate. Each instance may do very little,
but the aggregate cost overwhelms the VM. This produces saves that run fine initially but degrade
steadily, eventually freezing under load.
Save serialization exacerbates this. Active scripts and their variables are serialized. If a script spawns
instances incorrectly, those instances persist across saves and loads. Removing the mod does not
remove the serialized instances. On load, the VM attempts to resume or manage scripts that no longer
have valid code. This can lead to script errors, silent failures, or runaway behavior that consumes VM
time without obvious output.
Revert handling is critical here. When a save is unloaded or a new game is started, scripts should clean
up. Many scripts do not implement proper cleanup logic. This leads to cross save contamination, where
script instances from one save influence another. Symptoms include behavior that only occurs after
loading multiple saves in one session, or behavior that persists across new games until the process is
restarted.
Starvation rarely produces crash logs because it does not violate memory safety. The VM is executing
valid instructions. It is simply executing too many of them. The OS sees a responsive process that is
busy. The engine sees a main loop that cannot meet real time constraints. The result is freezing, severe
stutter, or apparent input loss.
Diagnosing script starvation requires indirect evidence. Increasing lag over time, freezes during combat
heavy scenes, responsiveness improving after restarting the game process, and stability returning when
certain scripted mods are disabled are all indicators. Script logs can show repeated execution of the
same blocks. NVSE debug output can reveal excessive event handling.
Mitigation strategies focus on containment and discipline. Prefer event driven designs over polling.
Enforce minimum wait times. Avoid per frame logic unless absolutely necessary. Limit the number of
scripts attached to actors or weapons. Avoid scripts that scale with population unless optimized.
Finalize scripted mods before starting a long term save.
From a mod stack perspective, the most dangerous configuration is many small scripted mods that each
seem harmless in isolation. Script starvation is additive and often multiplicative. Each mod assumes it
is the only one doing work. The VM does not share that assumption.
Understanding VM scheduling reframes many “random” freezes as predictable overload. The engine is
not broken. It is overwhelmed. Script starvation is the slowest, quietest, and most common way to kill a
New Vegas save

Big Iron Part 01 -NVSE Plugin Architecture

NVSE plugin architecture is a native code extension system layered on top of the game process. The
NVSE loader injects itself into the FalloutNV process early in startup, establishes trampolines and
import resolution for its own code, and then loads plugin DLLs from the NVSE plugins directory. From
that point on you have multiple independently compiled native modules executing inside a single
address space with no sandbox, no versioned ABI boundary beyond what NVSE exposes, and no
centralized exception handling. Hook safety is therefore mostly about minimizing undefined behavior
in a hostile environment: unknown code from other plugins, uncertain engine state, and an engine that
was not built for reentrancy or concurrency.
A practical mental model is that the engine has “safe” phases and “unsafe” phases. NVSE and plugins
can run during initialization, menu, world load, cell transition, and in game loop. Many engine
functions are only valid after certain singletons exist. Hooking too early means you call into
uninitialized subsystems. Hooking too late means the subsystem already ran and you missed the chance
to change behavior. Most stability issues trace to phase mistakes, invalid assumptions about call order,
or two plugins patching the same bytes with incompatible detours.
NVSE plugin loading sequence is roughly: NVSE initializes, scans plugins directory, loads DLLs with
LoadLibrary, resolves the plugin query and load entry points, and then invokes them in a deterministic
order. That order is usually directory enumeration order or alphabetical depending on loader behavior
and OS, so you should never rely on a specific inter plugin initialization order unless your plugin
explicitly checks for dependencies and hard fails if absent. A safe plugin should treat other plugins as
optional and detect them via exported API queries or known NVSE interfaces, not via implicit load
timing.
The core interfaces are provided by NVSE at plugin load time: an NVSE interface struct and
sometimes additional interfaces for messaging, serialization, and command registration. The plugin
Query phase is for version checks and capability declarations. It should not allocate heavy resources or
hook engine functions because the runtime environment may not be stable yet. The Load phase is
where registration typically occurs: registering script commands, registering message listeners,
registering serialization callbacks, registering papyrus equivalent hooks (New Vegas does not have
Papyrus, but NVSE provides script extender events and messaging), and setting up deferred
initialization.
Deferred initialization is a major safety technique. Instead of patching bytes or calling into engine
singletons during Load, you register for a known safe message that indicates the engine has reached a
stable point, such as “post load” or “post post load” messages in NVSE style messaging systems. Some
plugins also delay until the main menu is active, or until a save is loaded, depending on what they
modify. This avoids crashes caused by dereferencing global pointers that do not exist yet.
Hooking itself is usually done via one of three patterns: inline detours, virtual function table
replacement, and call site patching. Inline detours overwrite the first bytes of a target function with a
jump to your code, then execute the stolen bytes in a trampoline and jump back. Vtable replacement
swaps a function pointer in a class vtable to your replacement. Call site patching edits a specific call
instruction at some address to call your function instead.
Inline detours are the most common and the most dangerous because they depend on exact byte
sequences at fixed addresses. Fallout New Vegas builds differ by Steam, GOG, and sometimes
language or patch state. Address stability is not guaranteed. A safe plugin uses version detection and
address databases keyed by runtime version. Hardcoding addresses without validation is a primary
cause of instant crashes on other installs. Validation means checking that the bytes at the target address
match the expected prologue before patching. If they do not match, you do not patch and you either
disable that feature or refuse to load.
Hook conflicts occur when two plugins hook the same function or patch the same instruction bytes. If
both use inline detours and neither is designed to chain, the last plugin to write wins and the first
plugin’s detour is broken. Worse, partial overwrites create malformed instruction streams, causing
crashes in unrelated code paths. Safe hooking requires either cooperative chaining or selecting hook
points that are unlikely to be shared. Cooperative chaining means your plugin detects if the function is
already detoured and then hooks the trampoline or uses an established hook framework that supports
multiple subscribers.
Hook frameworks exist in the New Vegas ecosystem to reduce conflict risk. The principle is the same:
provide one stable detour and then allow multiple callbacks. If you are writing a plugin intended to
coexist, prefer using an existing framework or exposing your own callback interface rather than doing
multiple independent inline detours.
Reentrancy is a subtle killer. Many engine functions are not reentrant. If your hook calls back into the
engine in a way that triggers the same hooked function, you get recursion, stack overflow, or reentrancy
corruption. For example, hooking a UI render function and then calling UI update functions within the
hook can reenter rendering. Safe hooks use guards: thread local or static flags to prevent reentry, or
they schedule work for later rather than doing it inside the hook. Scheduling can mean queueing a task
to run on the next frame tick instead of inside the detoured call.
Threading is another landmine. The engine is largely single threaded for simulation, but some
subsystems use background threads or async IO in later patches or via driver behavior. If a plugin starts
its own threads and touches engine state from those threads, you will eventually corrupt memory. Hook
safety rule: treat the engine as single threaded unless you have explicit evidence and synchronization
that a particular API is thread safe. Most are not. If you must do background work, keep it isolated to
plugin owned data and marshal results back to the main thread using a safe scheduling mechanism.
Memory safety is the core issue. The engine uses custom allocators and expects ownership patterns. If
you allocate engine objects with CRT new and the engine frees them with its allocator, you crash. If
you store pointers to temporary engine buffers past their lifetime, you crash. Safe plugins avoid owning
engine memory unless they fully understand allocation and lifetime. When interacting with engine
strings, UI objects, or container types, you either use engine allocation routines or treat data as read
only and copy it into plugin owned memory.
Calling conventions and register preservation matter. Detoured functions have specific calling
conventions, often thiscall for member functions, sometimes stdcall or cdecl. If your hook signature is
wrong, you corrupt the stack. Even if it seems to work, it may only work until an optimizer layout
changes. A safe hook defines the exact signature, preserves registers the original function expects
preserved, and replicates side effects that the original prologue handled.

Big Iron Part 02 -Native Hooks

Serialization is an NVSE plugin feature that allows plugins to store state in save files. This is a double
edged sword. Done correctly, it enables persistent mod behavior and compatibility. Done incorrectly, it
creates save bloat and corruption. A safe serialization design includes: versioned records, robust
handling when data is missing or from an older version, and strict validation when reading. You should
never assume your serialized data exists, is complete, or is from your current version. Additionally, you
must handle the case where the plugin is removed but the save still contains records. Ideally, your data
is self describing and can be ignored safely when the plugin is absent.
NVSE serialization callbacks typically include Save, Load, and Revert. Revert runs when a save is
unloaded or a new game starts. If you do not implement Revert correctly, you leak state across saves,
causing cross save contamination. This can manifest as phantom behaviors that players interpret as
random bugs. Safe plugins treat Revert as mandatory and clear all global state, caches, and pointers to
engine objects.
Messaging systems allow plugins to coordinate. This is the preferred alternative to direct symbol
coupling. If your plugin depends on another plugin, you should detect its presence and version, then
either use its published interface or subscribe to its messages. If it is absent, you degrade gracefully.
Hard dependencies should be explicit and should fail early with clear errors to avoid partial
functionality that corrupts state.
Address relocation and pattern scanning are key to hook portability. A robust approach is signature
scanning: search memory for an instruction pattern unique to the target function and derive addresses
dynamically. This reduces dependency on a single binary layout. However pattern scanning is only safe
if signatures are resilient and validated. Too broad signatures produce false matches and patch the
wrong code, leading to catastrophic instability. Safe scanning uses multiple constraints and verifies
surrounding bytes.
“Hook safety” for the end user is less about the concept and more about observed compatibility
behavior. Red flags for unsafe plugins include: old binaries that predate xNVSE evolution, plugins that
hook many core engine functions, plugins with no clear version support for multiple distributions, and
plugins that ship without crash handling or validation. Green flags include: active maintenance, explicit
supported game versions, defensive checks before patching, use of shared hook frameworks, and
careful serialization with versioning.
In practice, common failure patterns attributable to NVSE plugins include: menu hangs caused by UI
hooks that assume a menu exists; freezes with looping audio caused by animation or input hooks that
block the main loop; crashes on save load caused by bad serialization read paths; intermittent crashes
caused by race conditions from background threads; and crashes that occur only after hours due to stale
pointers to engine objects that were freed during cell transitions.
A safe integration approach for a modded setup is to minimize the number of NVSE plugins that hook
core loops unless necessary, prefer maintained libraries, avoid redundant plugins that patch the same
subsystem, and treat any plugin that replaces timing or heap behavior as mutually exclusive with
similar plugins.
If you want to go even deeper, the next layer is to enumerate specific hook surfaces that are commonly
patched in New Vegas: main loop tick, input handling, animation update, menu render, sound event
dispatch, save load pipeline, and memory allocation wrappers. Each surface has distinct failure modes
and distinct safe patterns for interception.
Vault-Tec is redundant, but this info is paramount for our survival
-D. STOFFERS
NVSE plugin interoperability is the problem of multiple native code modules executing inside the same
unprotected process while modifying overlapping engine behavior. There is no isolation boundary, no
enforced ABI stability beyond what NVSE exposes, and no centralized arbitration of hooks.
Interoperability therefore depends entirely on discipline, defensive programming, and shared
conventions. When those conventions are absent or violated, failures are emergent and often silent.
At load time, NVSE injects itself and then loads plugin DLLs. Each plugin executes its Query and
Load entry points. Beyond that moment, NVSE does not manage execution order, hook order, or
memory ownership for plugins. Once loaded, all plugins coexist in the same address space with equal
privilege. Any plugin can patch any code, allocate memory anywhere, and call engine functions at any
time. Interoperability is therefore not automatic. It is engineered.
The most fundamental interoperability pattern is capability detection rather than load order
reliance. Plugins must never assume another plugin has already initialized unless they explicitly detect
it. Detection is done via NVSE interfaces, exported symbols, or version queries. Relying on DLL load
order is unsafe because it is not guaranteed and may vary across systems. A plugin that silently assumes
another plugin is present and initialized creates undefined behavior when that assumption fails.
The second pattern is graceful degradation. Plugins that extend or enhance behavior should detect
missing dependencies and disable features cleanly. Hard failures are acceptable only when the plugin
cannot operate safely without the dependency. Partial operation without validation is the most
dangerous state because it introduces inconsistent assumptions into the runtime. Safe plugins either
fully operate or fully disengage.
Hook interoperability is the most complex area. The unsafe pattern is uncoordinated inline detouring of
the same function by multiple plugins. Each plugin overwrites the same instruction bytes with a jump.
The last writer wins, and previous hooks are bypassed or corrupted. Even worse, partial overwrites can
produce invalid instruction streams. This class of conflict produces crashes, freezes, or corrupted state
that appears unrelated to the original hook.
The safe pattern is hook centralization and chaining. A single hook detours the engine function and
then invokes registered callbacks in a controlled order. Plugins register with the hook owner rather than
detouring independently. This pattern requires cooperation and shared interfaces, but it dramatically
reduces conflict risk. Where possible, plugins should prefer existing hook frameworks rather than
rolling their own detours.
Another safe pattern is late binding hooks. Instead of detouring functions immediately at load time,
plugins wait for a known safe phase and then patch only after verifying engine state and existing hooks.
Late binding allows plugins to detect whether a function is already detoured and adjust accordingly. It
also reduces crashes caused by patching uninitialized code paths.
Hook validation is essential. Before patching, a plugin should verify that the bytes at the target address
match the expected pattern. If they do not, the plugin should refuse to patch that function. This prevents
patching incorrect addresses when another plugin has already modified the code or when the runtime
version differs. Plugins that skip validation are brittle and frequently incompatible.

Big Iron Part 03 -Interoperability Patterns

Reentrancy awareness is another interoperability requirement. Many engine functions are not reentrant.
If a hook calls back into the same function or into a dependent function that assumes exclusive
execution, reentrancy deadlocks occur. Safe hooks include guards to prevent recursive entry. Plugins
that lack reentrancy protection may work in isolation but deadlock when combined with others that
extend the same subsystem.
Timing sensitivity is a subtle interaction vector. Plugins that hook per frame updates, animation
updates, or input processing compete for execution time. Each plugin may be correct individually but
collectively exceed the frame budget. Interoperability here is about restraint. Safe plugins minimize per
frame work, avoid polling where possible, and schedule deferred execution. Plugins that perform heavy
logic every frame amplify starvation risks when combined.
Memory ownership conventions matter. Plugins must clearly separate engine owned memory from
plugin owned memory. Passing plugin allocated memory into engine systems that expect engine
allocated memory is unsafe. Likewise, storing pointers to engine memory without tracking lifetime
leads to use after free errors when other plugins or engine code deallocate objects. Interoperable
plugins copy data when necessary and avoid sharing raw pointers across module boundaries.
Serialization interoperability is a major risk surface. NVSE allows plugins to serialize arbitrary data
into saves. Each plugin’s data is namespaced, but logical dependencies between plugins are not
enforced. If one plugin serializes state that another plugin assumes exists, removing either plugin
creates undefined behavior. Safe interoperability requires that serialized data be optional, versioned,
and validated on load. Plugins must handle missing or incompatible data gracefully and never assume
another plugin’s data is present.
Revert handling is mandatory for interoperability. When a save is unloaded or a new game starts,
plugins must clear global state, caches, and references. Failure to do so causes cross save contamination
that manifests only when multiple plugins interact. One plugin’s leaked state can poison another
plugin’s logic, producing failures that neither plugin exhibits alone.
Messaging systems are the preferred interoperability mechanism. Instead of calling into other plugins
directly, plugins broadcast messages and respond to messages. This decouples dependencies and allows
plugins to coexist without tight coupling. Messaging also allows plugins to detect presence and version
information dynamically and adjust behavior accordingly.
Versioning discipline is critical. Plugins must expose version information and enforce compatibility
checks. Silent version mismatches are a frequent source of instability. A plugin built against an older
NVSE interface or engine layout may appear to work until combined with newer plugins that rely on
updated behavior. Safe plugins fail early when version constraints are not met.
Pattern scanning and address resolution introduce another interoperability dimension. Plugins that
resolve addresses dynamically are more portable but must ensure that signatures are specific enough to
avoid collisions. Two plugins using broad signatures may resolve the same pattern differently or patch
unintended code. This creates nondeterministic failures. Safe scanning uses narrow, validated
signatures and fallback paths.
From a user perspective, unsafe interoperability often manifests as mods that are “fine alone but broken
together.” From a systems perspective, this is expected behavior when plugins violate any of the above
patterns. There is no arbitration layer to resolve conflicts. The engine executes whatever code is
present.
The highest risk plugins are those that hook core loops, timing, animation updates, input dispatch, or
memory allocation. These plugins touch subsystems that everything else depends on. Combining
multiple plugins in these categories requires explicit compatibility confirmation. Absence of a warning
is not evidence of safety.
The safest plugins are those that expose new script functions, perform read only inspection, or operate
at clear subsystem boundaries. These plugins tend to compose well because they do not alter execution
flow.
Interoperability in NVSE is therefore not about luck. It is about respecting shared space. Plugins that
are defensive, conservative, and explicit about their assumptions coexist. Plugins that are aggressive,
implicit, or opaque do not.
Understanding these patterns allows you to predict compatibility rather than discover it through failure.

This guide was created by its original author on the Steam Community. Are you the author and want it removed? Request removal.