Skip to content

Releases: Lorsieab2/Virtual-Families-2-Restoration-Addition-Patcher

VF2 Patcher B171

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 17 Aug 13:20
ac64de5

B171

Adoption Services is base-game again. Otherwise identical to B170.

The crash

Purchasing Adoption Services crashed:

Exception code:       0xC0000005   (access violation)
Faulting module name: unknown
Fault offset:         0x000001d7

"Unknown" module at 0x1D7 means execution left every loaded module and
jumped to a near-null address — a corrupted return address or function
pointer, not a bad data read.

Cause

patch_vf3_style_child_adoption_chooser replaced the stock spawn route at
CScrollingStoreScene::HandleUpgrade+0x57A with a helper that put up a
"baby or older child" message box and spawned the adoptee itself. Two
things in it were wrong against the native code, and either could produce
this crash:

  • It did not reproduce the stock call. Native is
    SpawnSpecificPeep(age=1, gender=-1, body=0x3C); the helper passed
    body=-1 with an explicit gender.
  • It constructed a theMessageBoxDlg in a 0x300-byte stack buffer,
    standing in for a class whose real size is not pinned anywhere. If the
    real object is larger, its constructor writes past that buffer and
    corrupts the return address — exactly an "unknown module" jump to a tiny
    address.

Fix

Rather than guess which was fatal and ship another maybe-fix, the whole
route is reverted. HandleUpgrade is byte-identical to the stock object,
verified by diffing the patched object against work/desktop_obj_files:

HandleUpgrade changed bytes: NONE - byte-identical to stock
+0x57A: 6a 3c 6a ff 6a   stock: 6a 3c 6a ff 6a

Adoption Services behaves exactly as the base game does. No baby/older-child
prompt exists in any B171 executable.

Nothing else is disabled — one hook removed, every other patch intact.

Also carried forward

Everything from B170, including the Family Tree fix (Bathroom 1's curtain id
no longer points at familytree_bg.jpg) and the bundle fixes that make the
installed game complete.

VF2 Patcher B170

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 17 Aug 08:20
5a7ee2b

B170

Fixes the Family Tree screen. Otherwise identical to B169.

The bug

Bathroom 1's closed-curtain image id was set to 615, taken from a live
read of the running game's image table. The read was accurate but the id
was not transferable: the running game is the patched build, whose table
is shifted by the ~800 images the patcher appends, so runtime ids do not
correspond to the stock ids the patcher indexes.

Against the stock table, 615 is familytree_bg.jpg. Bathroom 1's
curtain colour was therefore applied to the Family Tree background, which
then failed to draw — and with nothing repainting that region, every sprite
on the screen smeared across an uncleared frame.

The fix

Ids restored to the values data/vf2/image-descriptors.json gives:

539 = curtain_closed_southb.png  ->  Bathroom 1 (south, workshop-side)
538 = curtain_closed.png         ->  Bathroom 2 (north)

The room mix-up that prompted the original change was never about these
ids. It was fixed by routing each bathroom to its own decal slot in
RefreshProps (+0x53A and +0x570), which is untouched, so both curtains
keep working independently.

Guards added

A wrong image id is invisible by nature: it patches something real, just
not the intended thing.

  • validate_stock_image_ids() runs before every build and checks all three
    hard-coded stock ids against the descriptor table. Given 615 it fails
    with image id 615 is 'familytree_bg.jpg' ... expected 'curtain_closed_southb.png'.
  • work/audit_image_table.py reads the descriptor table out of every built
    variant and verifies no stock slot is repointed and no added image reuses
    a stock id. B170: 19 variants, stock 0–636 intact, 751–814 added each,
    zero collisions.

Bundle

The B169 packaging fixes are included: additive export now carries every
addition (7526 asset patches, was 1263), base-game classification uses a
recorded clean install rather than the working payload, and the release
gate simulates the install — 8193 of 8193 files reproduced byte-for-byte.

Verified by installing onto a clean base game with every patch enabled:
7305 images, 888 assets, matching a known-good install exactly.

VF2 Patcher B169

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 17 Aug 06:35
5526514

B169

Seventeen pull requests since B168: #15#30 and #33.

B168 already contains #12 (toggle persistence), #13 (villager-details
Married status) and #14 — its release config was added by #14 — so none of
those are upgrade changes for an existing B168 user.

Same-sex marriage

Marrying already worked in B168; the finalization hook predates it. What
was broken was everything the game asks after the wedding.

  • Spouses are now spouses everywhere. GetMatriarch and GetPatriarch
    back-fill a couple's missing half regardless of gender, which covers all
    66 native call sites in one change rather than hooking nineteen functions
    individually (#22).
  • Unrelated adults are no longer treated as a couple. VF2MarriagePair
    used to pair up any two qualifying resident adults, which also blocked
    Force Marriage Email for a player with no spouse at all (#16).
  • Private adult romantic time. A same-sex couple, or an opposite-sex
    couple already at six children, takes the ordinary baby-making path and
    is simply labelled differently. Pregnancy is suppressed for both, and it
    holds even against the Force Successful Pregnancy upgrade (#33).
  • Same-sex partners split the sequence. Behaviour 358 chooses which half
    a villager performs from the gender field alone, so a same-sex pair
    performed the identical half twice. The halves are now handed out by
    partner slot, so one spins and one produces the roses (#33).

An earlier form of the romantic drop (#28, #29) swapped behaviour 358 for
the native 357/356 pair and skipped refusals. That approach was reverted in
#33 and rebuilt as a label variation on 358, so what ships here is #33's
design, not #28/#29's.

Toggles

  • Marriage Candidate Reroll works. It used to reroll the candidate and
    then immediately close the proposal it had just rerolled (#23).

Bathrooms

  • Each bathroom's curtain goes to its own decal slot. A Bathroom 1
    renovation used to change Bathroom 2's curtain, and one slot turned out
    to be the kitchen's garbage sprite (#19, #21).
  • Bathroom 2 fixtures work with a remodel active. The remodel rows were
    written into the native owned-items array, which native code reads to
    decide the room's state; they now have their own storage, with migration
    so existing saves self-heal (#27).
  • The native Bathroom 2 renovation survives and gates the remodel rows, so
    the remodels cannot be bought without it (#24).
  • The five Bathroom 1 rows are renamed "Bathroom 1 Remodel in colour"
    (#20).

Correctness

  • Arbitrary memory corruption fixed. A 5-byte hook over a 2-byte branch
    in HandleDropOnVillager clobbered the following two pushes, and the
    fall-through then executed its own jump displacement as code before
    writing through a garbage address. Reachable by dropping any two
    different-gender adults who were not the couple while the house was full,
    so it affected opposite-sex households on a stock Behavior Patches build
    (#25).

Build system

  • The VF3 TVs are built from checked-in sources. They had survived only
    inside each release: the matrix seeds every build from the previous one,
    and the generator keeps a target it finds already present when the source
    is gone. Every retained manifest from B164 through B168 records exactly
    that, so the real sources had been missing for weeks without anything
    noticing, and an unseeded build could not produce the TVs at all. The
    sprites are now checked in, stock donor fmaps resolve from the vanilla
    payload, and a test asserts every VF3 TV has a checked-in source (#30).
  • A missing Bathroom 1 renovation asset hard-fails the build instead of
    silently shipping (#17).
  • work\build_playtest.ps1 produces a single playtest build in one command,
    and dead legacy same-sex marriage code is gone (#18).
  • Stale manifest-shape assertions in the release parity test fixed (#15).
  • Root causes for the Bathroom 2 fixture and same-sex private-time bugs
    documented (#26).

Notes

  • CVillager::StartEmbrace changes by exactly five bytes and
    theMainScene::HandleDropOnVillager by five. Every refusal in
    StartEmbrace — illness, hunger, age, pregnancy state, both random rolls
    — is base-game, as are its entry animation and its sound call.
  • Known base-game behaviour, not introduced here: the kiss animation is
    played at StartEmbrace+0x3A, before any check runs, so it can be audible
    on a refusal. Where that sound is emitted was never established; every
    attempt to suppress it downstream failed, and one crashed the game with a
    1124-frame stack overflow, because the pending animation is what stops the
    refusal tail's behaviour-137 handoff from re-entering StartEmbrace.

VF2 Patcher B168

VF2 Patcher B168 Pre-release
Pre-release

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 16 Aug 04:06
Immutable release. Only release title and notes can be modified.
b308c60

VF2 Patcher B168

Release built from main at 0929109 (PR #15, merged right after packaging,
is a test-only fix and doesn't affect any of the binaries in this release).
Covers PR #11 (same-sex marriage finalization on Accept), PR #12 (persist
Same-Sex Marriage / Marriage Candidate Reroll toggles across a relaunch),
PR #13 (same-sex "Married" status on the villager details screen), and
PR #14 (exporter fix needed to package this release at all) -- none of
which were in a published release before this one (B164 predates all four).

What's new since B164

  • Same-sex marriage now actually finalizes. Pressing Marry on a
    same-sex couple now runs the real native finalization: money,
    achievements, the family tree record, and the "Announcing the marriage
    of X and Y" life-event announcement -- previously silently skipped
    because the native code that grants those only fires when it can find
    one female adult and one male adult, which a same-sex couple can never
    provide.
  • Same-sex "Married" status on the details screen. The villager
    details screen ran the identical hard gender-filtered check as the
    finalization gate above, independently, to decide which status string to
    show -- so even a correctly-recorded same-sex marriage never displayed
    "Married". Fixed the same way: a scoped fallback for the specific
    villager being viewed.
  • Same-Sex Marriage and Marriage Candidate Reroll now persist correctly.
    Both toggles used to live in a free-standing custom PE section that the
    game's native save system never reads or writes, so buying either one
    only "stuck" for the rest of that play session -- a fresh launch or a
    reloaded save silently reset it to off, even though the store still
    showed it as purchased. This is what made Marriage Candidate Reroll look
    completely non-functional. Both toggles now live at the same
    proven, actually-persisted location already used by the Bathroom 1/2
    curtain colors and other renovations (inside CInventoryManager, part
    of the real save payload).
  • All 19 feature-toggle executable variants rebuilt from current main
    and verified byte-distinct.

What's inside

  • Apply_B168_Patcher.bat / Launch_GUI.bat -- run either to patch your own
    Virtual Families 2.exe.
  • offline_vf2_patcher.py / offline_vf2_patcher_gui.py -- the patcher.
  • payload/ -- all 19 modded EXE variants (one per feature-toggle
    combination) and their supporting assets/images.
  • manifest.json, Transparency Log.txt, How to Use.txt.

Validation performed

  • Diagnosed the Marriage Candidate Reroll bug down to the exact root cause
    via a linker .map file and raw disassembly of the linked exe -- not
    just source review -- before writing the fix.
  • Full work/ test suite: 471 passed, 238 subtests passed; the small
    number of remaining failures are all pre-existing, environment-only gaps
    (missing local icon source assets, an old release zip, IDA analysis
    output, and mobile .ogg assets) unrelated to anything in this release.
  • All 19 executable variants compiled and linked cleanly; confirmed
    byte-distinct (SHA-256).
  • Post-link raw exe disassembly confirmed both new marriage-related hooks
    (finalization guard and details-screen married-status guard) resolve to
    the exact addresses the generator intended.
  • work/package_patcher_zip.py's validate_executable_inventory() ran
    automatically during packaging and passed.

Known limitation

  • The persisted-byte storage change for Same-Sex Marriage means this
    release's external offline-patcher tool can no longer flip that one
    setting without an in-game purchase (it previously could, via a direct
    byte patch to a now-removed custom PE section). The in-game purchase
    toggle is unaffected and, unlike before, now actually persists.

Not yet fully validated

  • Divorce Spouse for an existing same-sex couple married before this
    build's finalization fix may still not work -- that couple's family tree
    record was never populated in the first place, and this release can't
    retroactively repair already-saved data. A same-sex marriage formed
    under this build should not have that problem.

Package

  • VF2-B168-Release.zip
  • SHA-256: C3022AE1E81D541BE4F9B46E7A990DA888EC23FF5B60A09411C877C733FAB7F0
  • Size: 93,671,474 bytes (~89.3 MB)

A passion project by Lorsieab2 in collaboration with Codex AI/Claude. No
copyright infringement intended -- please support the original game
creators!

Safe Base VF2 Patcher with all Patches ACTUALLY Enabled

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 15 Aug 02:28
0fd8097

Safe Base VF2 Patcher with all Patches ACTUALLY Enabled

A clean base build of the offline Virtual Families 2 Restoration/Addition Patcher (B159) that ships with every patch actually enabled — no toggles left off by mistake.

What's inside

  • Apply_B159_Patcher.bat — drag/drop or enter your original Virtual Families 2.exe to patch
  • Launch_GUI.bat — GUI front-end (Enable/Disable Patches, Dry Run / Validate Only)
  • offline_vf2_patcher.py + offline_vf2_patcher_gui.py — the patcher
  • payload/ — modded EXE variants and all supporting assets/images
  • manifest.json, transparency log, and usage docs

How to use

  1. Run Apply_B159_Patcher.bat and point it at your official Virtual Families 2.exe, or run Launch_GUI.bat for the GUI.
  2. The patcher validates the install is genuine, backs up under .vf2_patch_backups, and writes a clearly labeled modded folder next to the vanilla one.
  3. Vanilla VF2 saves are compatible with the modded version.

Local machine paths (patcher_local_settings.json) and Python caches are intentionally excluded from the download.

A passion project by Lorsieab2 in collaboration with Codex AI. No copyright infringement intended — please support the original game creators!

Redesigned

Redesigned Pre-release
Pre-release

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 15 Aug 05:21
Immutable release. Only release title and notes can be modified.
109b4e3

Purpose

Same test pre-release as Last Matrix Build -- built from the same main commit (109b4e3), same 19 feature-toggle variants, same seed directories -- but produced through a new, data-driven build engine (work/build_matrix.ps1) instead of the old pattern of hand-copying a whole build_bNNN_matrix.ps1 script per release. Published side-by-side with Last Matrix Build so the two can be compared directly.

What's different about how this one was built

  • One reusable engine script plus two small JSON files (the stable 19-variant toggle matrix, and this release's exe name/output prefix/seed paths) replace what used to be a ~124-line script copied and hand-edited per release.
  • The engine cross-checks each variant's generator manifest against whether a seed was actually configured for it, and fails closed if the two disagree -- catching exactly the kind of silent seed-state drift that has caused packaging surprises in past releases.
  • Spot-validated before the full run: the engine's core variant output was byte-diffed against the legacy script's core output. Every code/data byte was identical; the only differences were the linker's TimeDateStamp field and its mirrored debug-directory copy (ordinary non-determinism from re-linking at a different moment, not a functional difference). See work/build_matrix_engine_validation.md in the repo.

Validation performed

  • All 19 executable variants built successfully; each passed its generator's manifest gate checks before linking.
  • All 19 executables are byte-distinct (SHA-256), same as Last Matrix Build.
  • work/package_patcher_zip.py's validate_executable_inventory() ran automatically during packaging and passed cleanly (exactly one manifest record per executable, correctly gated, no path collisions, no missing payloads).
  • Same payload file count (6,842) as Last Matrix Build.

Not yet validated

  • No live/in-game playtesting. Same outstanding QA as every other pre-release.

Package

  • Redesigned.zip
  • SHA-256: 7BCFA52A23CC39C77903D22CE2EEFEB5C3FB14DBE73880CCA79896FC13CE9DB3
  • Size: 119,690,905 bytes (~114 MB)

A passion project by Lorsieab2 in collaboration with Codex AI/Claude. No copyright infringement intended -- please support the original game creators!

Last Matrix Build

Last Matrix Build Pre-release
Pre-release

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 15 Aug 04:59
Immutable release. Only release title and notes can be modified.
109b4e3

Purpose

Test pre-release built directly from main (commit 109b4e3) using the existing per-release matrix build script pattern (same approach as B162/B162.1). Not yet playtested -- this is for QA/testing purposes, not a certified stable release.

What changed since the last numbered release (B162)

  • src/offline_vf2_patcher.py and src/offline_vf2_patcher_gui.py synced from work/'s copies and substantially expanded; src/export_offline_patch_bundle.py (a stale, untested fork) removed.
  • work/patch_mobile_furniture_pack.py generator logic updated (+233/-63 lines).
  • How to Use.txt content restored (had been lost on main).
  • No native/compiled-code inputs changed beyond the generator script above -- confirmed by diffing every file touched since B162's tag.

What's inside

  • Apply_B163_Patcher.bat / Launch_GUI.bat -- drag/drop or enter your original Virtual Families 2.exe to patch, or run the GUI.
  • offline_vf2_patcher.py + offline_vf2_patcher_gui.py -- the patcher.
  • payload/ -- all 19 executable-toggle-combination overlays and supporting assets/images.
  • manifest.json, transparency log, and usage docs.

Validation performed

  • All 19 executable variants (core, cheat upgrades, mobile renovations, island events, holiday ornaments, behavior patches, and their combinations) built successfully; each variant's generated manifest passed its own gate checks (correct feature flags, correct row/asset counts) before linking.
  • All 19 executables are byte-distinct -- confirmed via SHA-256, ruling out the duplicate-executable defect class that affected a prior B162 release.
  • work/package_patcher_zip.py's validate_executable_inventory() check (the same check that would have caught that prior defect: "Payload executable must have exactly one manifest asset record") ran automatically during packaging and passed cleanly.
  • Full Python unit test suite (142 tests) passes.

Not yet validated

  • No live/in-game playtesting has been performed on this build. Purchase, save/reload, curtain, behavior, and native feature verification are still outstanding, same as every other pre-release pending manual QA.

Package

  • Last-Matrix-Build.zip
  • SHA-256: 54DF77DDEC51BBFDE9CF750215C6A720206E68415D93EDC94775ADF18C3CC6A6
  • Size: 119,786,684 bytes (~114 MB)

A passion project by Lorsieab2 in collaboration with Codex AI/Claude. No copyright infringement intended -- please support the original game creators!

VF2 Patcher B164

VF2 Patcher B164 Pre-release
Pre-release

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 15 Aug 23:03
Immutable release. Only release title and notes can be modified.
3536b8a

VF2 Patcher B164

Release built from main at 3536b8a, covering PR #9 (Bathroom 1/2 curtain
hook verification and comment fix, plus a new Bathroom 2 native-renovation
purchase gate) and PR #10 (recreated the build_matrix.ps1 release engine,
fixed a real compile-ordering bug found while standing up this build, and
a P1 seed-identity verification fix).

What's new since the last published release

  • Bathroom 1 & 2 curtain colors: verified the live curtain-color hooks
    for both bathrooms against the real game disassembly (not just source
    review) -- both ECX-preservation fixes check out correctly.
  • Bathroom 2 purchase gate (new): the five Bathroom 2 curtain-color rows
    are no longer purchasable until the native second-bathroom renovation is
    actually owned. Attempting to buy one now refunds the price in full
    (including under an active Cheat Upgrades price multiplier) and shows
    "Bathroom 2 must be renovated first before this can be bought."
  • All 19 feature-toggle executable variants rebuilt from current main and
    verified byte-distinct.

What's inside

  • Apply_B164_Patcher.bat / Launch_GUI.bat -- run either to patch your own
    Virtual Families 2.exe.
  • offline_vf2_patcher.py / offline_vf2_patcher_gui.py -- the patcher.
  • payload/ -- all 19 modded EXE variants (one per feature-toggle
    combination) and their supporting assets/images.
  • manifest.json, Transparency Log.txt, How to Use.txt.

Validation performed

  • Full work/ test suite: 266 passed; 2 pre-existing failures confirmed
    present on unmodified main too (missing local .obj artifact for an
    unrelated, untouched island-events feature -- not a regression).
  • All 19 executable variants compiled and linked cleanly; confirmed
    byte-distinct (SHA-256).
  • work/package_patcher_zip.py's validate_executable_inventory() ran
    automatically during packaging and passed (one manifest record per
    executable, correctly gated, no path collisions, no missing payloads).
  • Retroactively verified every one of the 19 variants was built from
    exactly its intended seed, no cross-variant asset contamination.
  • Full build-environment and validation write-up in
    docs/B164-release-notes.md.

Not yet validated

  • No live/in-game playtesting. Same outstanding QA as every prior release:
    purchase/remove each Bathroom 1/2 curtain color, the new Bathroom 2
    blocked-purchase message, save/reload, and the rest of this build's
    carried-forward feature set.

Package

  • VF2-B164-Release.zip
  • SHA-256: 1A443C3DF4EA0D9CB91DA898CEC70F46E132C5075833C07C28392AA85AB694D4
  • Size: 93,668,875 bytes (~89.3 MB)

A passion project by Lorsieab2 in collaboration with Codex AI/Claude. No
copyright infringement intended -- please support the original game
creators!

VF2 Patcher B162 - Renovation and Special Upgrade Repair

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 13 Aug 04:25

B162 restores the native VF2 Home Renovation rows alongside the mobile renovation catalog.

Changes:

  • Preserves native Home Renovation rows 0xE1-0xEA and appends the mobile renovation rows.
  • Removes live Bathroom 1/Bathroom 2 curtain refresh calls from store clicks. Curtain colors are applied on normal game load/restart, and the Bathroom 2 click-crash route is removed.
  • Keeps six stock Special Upgrades, adds four mobile Special Upgrade rows, and adds 36 Cheat Upgrade rows when Cheat Upgrades is enabled. The final all-enabled overlay has 46 Special Upgrade rows.
  • Keeps Anti-Spam Software and Rockhound Certificate independently repurchaseable.

Verification:

  • 19 generated overlay combinations; 19 unique executable SHA-256 hashes.
  • Focused source regression tests: 5 passed.
  • Repository tests: 35 passed.
  • Special-upgrade/package tests: 22 passed.
  • Exporter overlay tests: 5 passed.
  • Bundle payload audit: 6,829 referenced payload paths, 0 missing.

Runtime/player launch, purchase, restart, save/reload, and Bathroom 2 crash-reproduction verification remains required.

ZIP SHA-256: 59FEB04EC375761E9973AFAE7522EEE1C8428DAF2CCD0670125C3C5D4BF2006E

B161 - Anti-Spam and Rockhound Repurchaseable

Choose a tag to compare

@Lorsieab2 Lorsieab2 released this 13 Aug 03:33

B161 makes Anti-Spam Software (0x33) and Rockhound Certificate (0x10A) independently repurchaseable in every patched executable, including saves where the persisted effect flag has already been cleared. Active rows use the zero-price removal route; inactive rows use the native purchase price/effect path.\n\nStatic/source/package validation passed. Live purchase, effect, save/reload, and player QA remain required.