SimPassiveLevelingOverhaul
Overhauls Erenshor's Sim level progression with passive XP over time.
| Date uploaded | 2 weeks ago |
| Version | 1.0.0 |
| Download link | TeamSaltyBois-SimPassiveLevelingOverhaul-1.0.0.zip |
| Downloads | 18 |
| Dependency string | TeamSaltyBois-SimPassiveLevelingOverhaul-1.0.0 |
This mod requires the following mods to function
BepInEx-BepInExPack
BepInEx pack for Mono Unity games. Preconfigured and ready to use.
Preferred version: 5.4.2305README
Sim Passive Leveling Overhaul — v1.0
Description
This mod replaces the vanilla sim XP catchup system with a highly configurable passive XP drip that runs in the background while you play, and only while you play. No offline catch-up. This mod was made as I found the vanilla catchup system for simulated players (levels mostly granted in abrupt bursts each time you log in, depending on sims assigned slot) a bit too immersion breaking with my style of play (frequent logging out, able to play a couple times a week).
Many values are exposed and configurable to tweak the leveling to your liking. Mod can be added or deleted mid playthrough with no issues.
Recommended to pair with my companion mod, Sim Start At Level 1, if you are starting fresh and want a bit more of a "day 1" mmo experience.
Features
Passive XP for All Eligible Sims
- Unassigned generic sims gain XP on the standard curve.
- Rival sims level roughly 20% faster.
- Your own character-slot sims gain XP on the standard curve up to a cap of two levels above you, with a configurable catch-up multiplier when behind.
- Active party members and Sims tied to other character slots do not receive passive XP. They gain levels through combat or when you play those characters.
1–35 Leveling Curve (~110 Hours Total)
- Levels 1–5: 12–18 minutes per level
- Levels 6–10: 30 minutes to 1 hour 18 minutes per level
- Levels 11–15: 1 hour to 1 hour 36 minutes per level
- Levels 16–20: 1 hour 48 minutes to 3 hours 30 minutes per level
- Levels 21–25: 3 hours 48 minutes to 5 hours per level
- Levels 26–30: 5 hours 12 minutes to 6 hours 30 minutes per level
- Levels 31–35: 6 hours 12 minutes to 7 hours 30 minutes per level
Per-Sim Variance (Configurable, default 0.5× – 1.5×)
XP modifier from random seed, which re-rolls on zone changes. Produces organic variation across the roster.
Configuration
All settings are stored in BepInEx/config/erenshor.simxpovertime.cfg. Edit this file while the game is closed to adjust behavior.
-
TickIntervalSeconds— Default:120
Interval in seconds between XP grants. XP granted is scaled accordingly, so leveling speed will not change, only how often the XP is granted. Lower values will equate to slightly more CPU usage. -
MaxLevel— Default:35
Maximum level cap for Sims. Sims will not gain passive XP beyond this level. -
VarianceMin— Default:0.5
Minimum per-Sim speed variance. A value of0.5means the slowest Sim levels at half speed. -
VarianceMax— Default:1.5
Maximum per-Sim speed variance. A value of1.5means the fastest Sim levels at 1.5× speed. -
RivalSpeedMultiplier— Default:1.20
XP speed multiplier for rival Sims (Friends' Club). Set to1.0for no bonus. -
SlotCatchupPerLevel— Default:0.10
Catch-up boost applied per level behind. For example, if a Sim is 5 levels behind, they receive a0.5(50%) boost. -
SlotCatchupMax— Default:3.0
Upper limit for the catch-up multiplier. Prevents extreme catch-up boosts. -
SlotLevelCapOffset— Default:2
How many levels above the player a character tied sim can passively reach. Set to 35 to effectively disable this cap. -
DebugLogging— Default:false
Enables verbose logging for troubleshooting.
Requirements
- BepInEx 5.4.23.5
Installation
- Install BepInEx for Erenshor.
- Place
SimXPOverTime.dllin yourBepInEx/plugins/folder. - Launch the game. The configuration file generates in
BepInEx/config/automatically on the first run .
Compatibility
The mod is compatible with any other mod that doesn't also try to transpile SimPlayerMngr.Update or prefix SimPlayerCatchupCode.
Methods Patched
-
SimPlayerMngr.Update— Transpiler
Injects timer logic and redirectsTimeInZonewrites to our XP processor. -
SimPlayerMngr.LoadSimPlayersIntoGame— Prefix
Takes a snapshot of all sim levels before loading begins. -
SimPlayer.SaveSim— Prefix
Syncs cache with the sim's current XP before the game saves. -
SimPlayerMngr.CollectActiveSimData— Prefix
Syncs all active sim XP to cache and increments zone seed on zone change. -
SimPlayerDataManager.SaveAllSimData— Prefix
Syncs all sim XP to cache before full save (logout/shutdown). -
SimPlayerMngr.SimPlayerCatchupCode— Prefix (skips original)
Blocks the vanilla catchup mechanic entirely.
Performance
The mod is lightweight and has minimal CPU overhead. It performs a static boolean check every frame. On the single frame where XP is granted, it executes roughly 0.15ms of work.
The primary performance consideration is the save queue drain on zone changes, where ~168(default) save files are written sequentially, capped at 1 per frame. Players with slower mechanical hard drives (e.g., 5200 RPM) may experience a slight stutter in the first couple seconds after a zone change.
Notes
- This passive XP stops at level 35 by default. Reccommended to keep this, so it does not cause sims to become cracked gamer gods by getting too many ascension levels.
To-DO
- Expose direct leveling curve (1-35) for indiviual tweaking
- Scrubby specific multiplier of .2 to simulate his true leveling speed.
CHANGELOG
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 newSaveSimDataprefix 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'sSave FAILEDerror.
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
TickIntervalSecondsminimum 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:HoursForLevel2is 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 oldFriendedByandTiedToSlotvalues — 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
-
MaxLevelnow 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 callsSaveSim()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'sSaveSimpatch 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 newVerifyLoadCompleteguard 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 newSaveSimPostfix 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 (CheckLoadDataandLoadFromFilePostfixes). Gone are the double reads, the directory scans, and the edge case where a leftover.tmpfile 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.SaveSimpatch 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. -
TickIntervalSecondsnow 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
DrainCoroutineand the save queue.
These have been replaced by dirty sets and the background writer._coroutinesStartedflag.
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 fromSimPlayerMngr.Start():XpTickCoroutine— processes XP in batches of 5 sims per frameDrainCoroutine— drains the save queue one file per frameRebuildCacheCoroutine— 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
SaveSimpatch 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 ownSaveSim()body handles the actual persistence for spawned sims. -
Swallowed errors are no longer silent.
Five emptycatch { }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.StartPostfix.
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.PlayerStatsandGameData.CurrentCharacterSlotcan 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
_cachedictionary.
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 oldTryGetValueplus 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 theSimPlayerMngr.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.