Dated source reference. Current release status: handoff state. Full original relative paths are in the developer archive.
External mode: first-launch onboarding removal
Current combined source is0.2.0.dev37, snapshotABI15/eventABI4, collegeprofile4/courtdefinition3; see current internal state and API verification. The standalone external-mode versions, installer behavior and historical tests below retain their original identities. Current documentation updates do not migrate/overwrite saves, install a DLL or publish a package.
Current scope (October13,2026): Windows-first deep editing and a public extension API; Mac/Linux compatibility follows later. Earlier native-port goals and next-step proposals in this evidence history are superseded. Technical observations and verification limits remain as recorded.
Historical v0.1 milestone. Current v0.2 redirects user data beside the executable and changes the early bootstrap; see PORTABLE-SAVES.md. The mechanisms, AppData paths and tests below describe v0.1. Its exact source is archived in analysis/portable-saves/source-v0.1.
OpenHoops v0.1 replaces the supplied game's startup registration transition and initializes missing generic player saves automatically. A completely absent NBA 2K14 AppData directory reaches the main menu without a date of birth, online enrollment, under-age notice or MyPLAYER creation. This is a source-built adapter for the original x86 game, not the native reconstructed engine.
Supported scope
- Supported executable SHA-256:
7cb5fdaa30586558a3146dcf9023880b1cceeaabfe0f92f967f461c4644f3704, suppliedrld-nba2k14.iso, memberCrack/nba2k14.exe. Original CD build is unsupported. Runtime byte guards are mandatory even for this hash because protected code differs from disk. - Tested host: Windows 11 x64 OptiPlex, original x86 game and x86 adapter. macOS/Wine and Linux/Wine/Proton adapter loading are untested. It does not turn the game into a native x64 or ARM program.
- First launch means the whole
%APPDATA%\2K Sports\NBA 2K14directory is absent, including Config.cfg and Saves. No manual save setup or date entry is required. Generic seeds are shipped inside the package and copied to the current user's AppData on demand. - Existing USR/STG files are retained. Corrupt or incomplete pre-existing profiles have not been tested. The patch does not delete or disable the MyCAREER menu; it removes forced startup creation. External season management, direct-to-match launch and live-stat APIs remain future work.
- No online account was created or terms accepted. The observed offline state is not proof that all unrelated game network activity has been disabled.
Implementation
Source: dinput8.cpp, exports, build, installer.
The game calls our app-local DirectInput8Create. Initialization runs synchronously outside DllMain, verifies the executable hash, image base and three runtime byte sequences, then creates missing saves and installs a five-byte jump. It forwards DirectInput to the full system DLL path. This build exports only the function imported by the supported game; it is not a general ASI loader or a drop-in chain for existing mod loaders.
At the registration transition, the stub sets the two observed offline flags, calls the game's offline helper and closes the registration root using the original game routine. It executes on the caller's game thread. No polling loop, debugger, remote thread, input automation or guessed date is required by the adapter. The executable file is unchanged.
Generic My Profile.USR and Settings.STG were generated through the original game's local player editor, with default appearance and name openhoops player. Their full save format has not been independently reconstructed. They contain no MyCareer save or online account. Seed provenance and hashes. Each seed is validated before copying and the destination verified after copying; existing files are never overwritten. Machine Config.cfg is not bundled.
On an unsupported version or guard failure, the adapter reports the error and terminates rather than writing to an unverified address. Read-only/unwritable save paths similarly fail explicitly. These failure messages are not onboarding prompts.
Exact recovered boundary
Addresses apply only to the pinned executable's captured runtime. Disassembly, registration dispatch, under-age popup trace.
| Address | Evidence / role |
|---|---|
0xB558D0 |
Date submission handler. Validates date fields, compares packed date against current year minus 13 in this build. Do not call it an 18-year threshold. |
[0x1FF7FFC] |
Date-state pointer. Selected date at +4 packs year into low 16 bits, month/day into the upper bytes. Initial raw 32-bit year scans missed it. |
0xB55932 |
Under-age path: sets [0x1FF7FF4]=1, calls 0x54A9E0, then 0x5B1820. |
0x5B1820 |
Sets [0x10D76F4]=1, opens the informational notice. Adapter reproduces the flag without opening the notice. |
0x4AFA90 |
Obtains profile; subsequent +0x2410 check controls player-creation path. Semantics supported by control-flow and empty-profile experiment, not a full profile layout. |
0xB58310 |
Registration root initialization and mode dispatch. Adapter preserves initialization. |
0xB58501 |
Five-byte mov edx,0xF97128 (DOB page descriptor) replaced with relative jump to adapter. |
0x56C2E0 |
Original root-close routine. Adapter restores the intercepted epilogue's stack/register contract and tail-jumps here. |
The guarded 19-byte window at 0xB584FC is 5f5e8bcd5dba2871f9005b83c404e9e173a2ff. At the patch location, EDI/ESI/EBP have been restored, ECX contains GUI context, and EBX plus one local DWORD remain on the stack. The stub preserves ECX across its calls, pops EBX and releases the local before closing the root. Callee starts are also guarded. Captured bytes and the exact guards are in source; never apply these addresses directly to the encrypted disk image.
Experiments and evidence
All evidence is under analysis/offline-bootstrap. Failed attempts are retained and should not be mistaken for successful runs.
| Test | Outcome |
|---|---|
| USR only / paired USR+STG | DOB still appeared. A prepared profile alone is insufficient. |
STARTUP_ACCOUNT_REGISTRATION=0 |
DOB still appeared; the string was read but the setting did not accomplish the requirement. |
| Under-age submission / traced popup | Identified handler and offline path. Initial broad heap scans and calendar breakpoints were inconclusive; one bounded debugger test timed out and stopped that test process. |
| Run 06, prototype runtime patch + generic seed | Main menu, no DOB/notice/creator. Manual research patch, not the deliverable. |
| Run 07, prototype patch + absent AppData, no seed | DOB skipped, MyPLAYER creation still appeared. This is why missing-profile initialization is required. |
| Run 08, automatic DLL + absent AppData | Both seeds initialized automatically; onboarding skipped and main menu reached. No debugger/manual memory patch. First DLL build; Quick Game reached first quarter 5:35, 2–0, pause working. |
| Run 10, final DLL + absent AppData | Main menu without onboarding or creation; final packaged DLL. |
| Run 11, existing saves | Main menu; both saves retained, Config/USR/STG startup hashes unchanged. |
| Installer fixtures | Fresh install and identical reinstall pass; conflicting loader and unsupported EXE refused without replacement. |
Final build/restart/installer results are recorded in validation.json beside the evidence. adapter-08-menu.png is the first automatic clean-launch menu capture. Source-build logs preserve compiler output and DLL hash. Initial installer invocations were blocked by script policy; inadvertent unmodified run09 is excluded from success claims. Retry used a process-only policy override. install-adapter.json proves absence of the save directory before that launch; adapter-08.log records initialization and branch execution.
Packaging and use
Package: build/external-mode-v0.1. On Windows, close the game and run powershell.exe -NoProfile -ExecutionPolicy Bypass -File .\Install-OpenHoops.ps1 -GameDirectory <working-game-folder> from PowerShell. Installer validates package contents and executable, refuses a different existing dinput8.dll, copies seeds first and loader last, and permits an identical reinstall. The execution-policy override applies only to this installer process; machine policy stays unchanged. It does not install into AppData; initialization occurs separately for the user launching the game.
Disable with the game closed by renaming this package's dinput8.dll to dinput8.dll.disabled. Generated local saves are retained. Do not overwrite BodyHook/Blaze/other dinput8 loaders: chaining remains unimplemented and untested. Do not install into the preserved NBA2K14-extracted corpus.
The original per-user reference profile is preserved on the Dell at OpenHoops\profile-backups\before-offline-bootstrap; subsequent test profiles have separate backups. No archived community mod binary was executed. The adapter contains our source-built code; generic saves originate from the supplied game. No assets or package were published.
Next boundary
Establish an external launch contract for roster, teams and game settings, with game-thread execution and explicit success/failure state. Reuse the read-only stats candidates already identified, verify team identity and lifecycle across transitions, then expose them through a companion API. This milestone demonstrates targeted control of startup, not arbitrary rules replacement or whole-engine recovery.