Erenshor
Install

Details

Last Updated
First Uploaded
Downloads
215
Likes
1
Size
161KB
Dependency string
TeamSaltyBois-SimPassiveLevelingOverhaul-1.4.2
Dependants

Categories

Changelog

1.4.2

Fixed

  • The quarantine now blocks the game's own login time saves.
    During login the game saves every sim record back to disk right after reading it. For a sim quarantined by an unreadable (locked) file, that record is the mod's in memory substitute. the save normally fails against the same lock, but a lock released at exactly that instant could write the substitute over the real file. A new SaveSimData prefix skips those writes for quarantined sims until the login restore completes. Nothing legitimate is blocked. Every later save of a quarantined sim is derived from a successful read of the real file. Side benefit, a lock held through login now produces one clear mod log line instead of the game's Save FAILED error.

1.4.1

Fixed

  • Damaged sim files now repair themselves at login.
    The mod now validates sim files as the game reads them. damaged files are restored from their backup, and if both copies are unusable the sim is reset with the login guaranteed to survive. This is the same recovery ladder the game already uses for Reliquary and guild data.

  • A briefly locked sim file can no longer cause a permanent reset.
    If something (an antivirus scan, a sync tool) held a sim's file at the exact moment of login the game built placeholder data for that sim, and the mod's background writer, would later save that placeholder over the real file. Locked files are now retried, then served from backup in memory and quarantined. Nothing writes to that sim's file for the session, and the first successful read restores normal service automatically.

  • One unreadable sim file can no longer hang the login at the auction house pass.
    The auction house rereads every sim's save file while the game loads. With no error handling a single locked or unreadable file stranded the loading screen forever. The login now continues with partial auction data for that session and rebuilds it next time.

  • XP is no longer lost for sims that die or revive near you.
    The game stops saving a sim's body the moment it dies, and never resumes for sims that revive with their group. The mod now recognizes both cases and persists their XP through the background writer, so a death near the end of a session loses nothing.

Changed

  • TickIntervalSeconds minimum raised from 30 to 90 seconds.
    At very low intervals the background writer could still be working through the previous tick's changes when the next tick landed.

1.4.0

Added

  • The leveling curve is now configurable.
    [XPCurve] config section added. It exposes hours per level for levels 2 through 35. Each entry is the time that level takes to reach: HoursForLevel2 is the climb from 1 to 2, and so on.

Fixed

  • Login level bumps are reverted again.
    The game reads every premade sim's file twice while loading: once directly, and once more during its full save folder scan, after it has already applied and saved its vanilla login level bumps. Since the v1.3 rework, the mod's prelogin snapshot kept the second, already bumped read, so rival and slot tied premades quietly kept their vanilla login levels. The snapshot now keeps the first read of each login, so the revert sees the bumps again.

  • Login bump reverts are written to disk before you can disconnect.
    The reverts used to trickle out through the background writer while the character select screen sat idle. Disconnecting there performs no save pass, so a rapid login and disconnect could discard pending reverts and let bumped levels stick permanently. The reverts are now flushed to disk in the same instant the login restore finishes.

  • Total leveling time now matches the advertised ~110 hours.
    The old curve consumed its 35 entries one level early: each level was paced by its own row instead of the next one, so the final 7.5 hour entry never ran and a sim actually reached max in about 102 hours. The curve is now keyed to the level being reached, and the default table has been retuned to total 109.8 hours exactly. The first eight levels are unchanged, the odd speed dips at 10-11 and 30-32 are smoothed out, and the jump at level 20 is gentler.

  • Friending an offline sim no longer gets silently reverted.
    The social list's friend toggle writes a sim's file directly, bypassing the save path the mod watches. The mod's cached copy of that sim went stale, and the next background write would quietly restore the old FriendedBy and TiedToSlot values — the friendship would vanish on your next login. The cache is now invalidated on every game side sim save, no matter which path it comes through.

  • A login level bump into the level cap is now reverted like any other.
    Sims already at the cap were skipped entirely during the login check, so a bump from 34 to 35 in previous versions slipped through and stuck permanently.

  • Deleted sim files now stay deleted.
    When the game deletes a sim's save file (sim renames, single sim resets), the mod now forgets its cached copy and cancels any pending write for that name. Previously a queued background write could quietly recreate the file from memory.

Changed

  • MaxLevel now enforces a 1 to 35 range.
    35 is the game's own maximum. Past it, the base game's ascension system takes over, which this mod deliberately leaves alone.

  • Trimmed the startup log line.


1.3.0

Game Update Compatibility (2026-07-16 patch)

  • Adapted to the game's new spawn time save behavior.
    The July 16th patch introduced a subtle change. Every sim now calls SaveSim() right as they spawn, before the mod has a chance to link its tracking data. This meant passive XP could be quietly reverted to older file values.
    The mod's SaveSim patch now acts as both a Prefix and Postfix to recognize this early spawn save, keeping the tracked level authoritative throughout. It also ignores saves that the game's new VerifyLoadComplete guard rejects. Without this, sims wandering into your zone mid session could lose pending passive XP.

  • Everything else in the patch (guard AI rework, raid opinion bonus, input and options changes) doesn't touch anything this mod uses.

Fixed

  • Fixed an XP race condition on spawn.
    If a passive tick landed at the exact moment a sim spawned, the mod could mistakenly pull old data from disk. Now a sim is only treated as spawned once its tracking object is fully linked. Sims that are still spawning are handled as unspawned and reconciled a frame later.

  • Combat XP now triggers level ups properly.
    Sims earning XP from their own kills (solo hunters or group members) would bank it without triggering a level up check. The vanilla game relied on login catchups to fix this, which this mod disables. The tick now reads a spawned sim's live XP and converts any banked surplus into the correct levels.

  • Passive XP no longer overwrites combat earned XP.
    Previously the passive tick would wipe out any XP a spawned sim earned from its own kills. It now adds to that total instead. A new SaveSim Postfix also copies XP back into tracking whenever the game saves. The game already did this for Level, but never for XP, which is what let the stale value creep in.

  • Session resets properly on relog.
    Logging out used to destroy the mod's background processes while leaving a stale flag active. When you logged back in, nothing ran until you restarted the game. Now everything resets cleanly on each login.

  • Saves are flushed reliably at logout and quit.
    In v1.2, queued writes only processed during loading screens. If you quit without a load screen, pending changes could vanish. Now every session exit (logout, quit, zone change, manual save, respawn) guarantees everything is written to disk first.

  • Error handling for the XP tick is more robust.
    If one sim had an issue, the whole tick would fail. Now it catches and logs that specific sim's error and keeps processing the rest.

  • The slot 12 login bump is now handled.
    The game applies a specific level bump to slot 12's sim without saving it. The mod's previous file based checks missed it. This update catches and corrects that bump just like the others.

Changed

  • Smoother, faster background saving.
    Instead of a queue, the mod now tags dirty sims (those with Level or XP changes) and writes them out at a steady pace: one sim every 0.25 seconds, with level ups jumping the queue. It uses the game's native save pattern (temp file → replace → backup) but skips the hardware flush on each file, saving 10 to 30 milliseconds per save on slower drives. The tradeoff: a hard crash could lose up to one tick's worth of background XP. Quits and logouts lose nothing.

  • Zero extra file reads on login.
    The mod captures each sim's data directly as the game parses it during loading (CheckLoadData and LoadFromFile Postfixes). Gone are the double reads, the directory scans, and the edge case where a leftover .tmp file could poison the snapshot.

  • Level ups save in the background.
    In v1.2, leveling a sim triggered an immediate file write. Now it just marks the sim as dirty and lets the background writer handle it when ready.

  • Faster XP ticks.
    Since the math is lightweight, we've increased the batch size from 5 to 25 sims per frame. This makes the whole pass complete sooner without adding any noticeable overhead.

  • SimPlayer.SaveSim patch reworked.
    Previously a Prefix only patch, it now reacts to what the game actually wrote instead of trying to predict it. See the game update compatibility notes for how it handles spawn time saves.

  • TickIntervalSeconds now enforces a 30 to 3600 second range.
    Below 30 seconds, rounding on each tick starts inflating early level speed. There's no practical use for faster ticks anyway, since the background writer already refreshes files on its own cycle of roughly 60 seconds regardless.

Removed

  • DrainCoroutine and the save queue.
    These have been replaced by dirty sets and the background writer.
  • _coroutinesStarted flag.
    Now replaced by tracking the manager instance the coroutines run on.

1.2.0

Architecture Rewrite

  • No more IL manipulation.
    The mod used to inject code directly into the game's update loop via a transpiler. That's now completely gone. No Update() hooks, no low level IL patching. This means better compatibility with other mods and less risk of breaking on game updates.

  • Switched to coroutines.
    Instead of running work every frame, the mod now launches three coroutines from SimPlayerMngr.Start():

    • XpTickCoroutine — processes XP in batches of 5 sims per frame
    • DrainCoroutine — drains the save queue one file per frame
    • RebuildCacheCoroutine — rebuilds the in memory state in batches of 10 sims

Fixed

  • Prevented save file corruption.
    The old cache system took a snapshot of each sim at login and wrote that back later. This stripped out everything the sim gained during play: equipment, inventory, skills, guild membership, and appearance. Unspawned sims could lose all non XP progress on zone changes. The mod now uses a read-modify-write pattern. It reads the file from disk, updates only the level and XP fields, and writes it back, preserving everything else.

  • Stopped the SaveSim patch from overwriting fresh data.
    The Prefix patch used to enqueue a stale cached object after the game had already saved the correct version. This caused older data to win on a later frame. Now it only syncs the in memory state. The game's own SaveSim() body handles the actual persistence for spawned sims.

  • Swallowed errors are no longer silent.
    Five empty catch { } blocks were replaced with proper error logging. If something goes wrong, you'll see a warning in the log instead of the problem vanishing without a trace.

Added

  • SimPlayer.Start Postfix.
    When an unspawned sim spawns into your zone, its stats are initially pulled from a potentially stale disk file. This patch overwrites those values with the mod's authoritative in memory Level and CurXp, then recalculates derived stats. You no longer need the disk file to be perfectly up to date for spawned sims to have the right levels.

  • Null checks for scene transitions.
    GameData.PlayerStats and GameData.CurrentCharacterSlot can be null during loading screens. The XP tick now checks for both before processing, avoiding errors when you're swapping zones.

  • Safe handling for manual saves.
    Unspawned sim XP now gets persisted on every zone change behind the loading screen, so you never notice. For manual saves with no loading screen, writes are deferred to the drain coroutine (one per frame) to avoid hitching the game.

Removed

  • The write only _cache dictionary.
    This cache was never actually read. It just held data that was written out. Everything that needed sim data now reads directly from tracking fields or from disk, so the dictionary is gone.

  • Dead dictionary lookup in ProcessXpForSim.
    An old TryGetValue plus field write that nothing downstream ever consumed has been removed. This saves about 200 dictionary lookups on each XP tick.

  • The CheckCache() method.
    It used to poll every frame. It's now replaced by a one shot coroutine launch from the SimPlayerMngr.Start() Postfix.

Performance

  • Idle frames are now incredibly light.
    On frames where no XP tick runs (over 99% of gameplay), the mod uses roughly 20 CPU instructions. That's just the coroutine scheduler and one queue count check. Down from about 4,500 instructions per frame in v1.1.

  • XP ticks are faster and more even.
    The old transpiler processed all 257 sims in a single frame, adding up to 24 milliseconds to the update budget. Now they're batched across about 52 frames (5 sims per frame). Each frame takes under 0.02 milliseconds with debug logging off, well below any perceivable threshold.

  • Login reads cut in half.
    The snapshot and cache rebuild used to read each sim file twice. Now the mod reads each file only once. The cache rebuild is spread across roughly 26 frames, so no single frame hitch.

  • Zone changes stay smooth.
    Unspawned sims (about 237 of them) are persisted via read-modify-write behind the loading screen. If no loading screen is active (for example, a manual save), the drain coroutine handles them one per frame to avoid stuttering.

Thunderstore development is made possible with ads. Please consider making an exception to your adblock.