Install Steam
login
|
language
简体中文 (Simplified Chinese)
繁體中文 (Traditional Chinese)
日本語 (Japanese)
한국어 (Korean)
ไทย (Thai)
Български (Bulgarian)
Čeština (Czech)
Dansk (Danish)
Deutsch (German)
Español - España (Spanish - Spain)
Español - Latinoamérica (Spanish - Latin America)
Ελληνικά (Greek)
Français (French)
Italiano (Italian)
Bahasa Indonesia (Indonesian)
Magyar (Hungarian)
Nederlands (Dutch)
Norsk (Norwegian)
Polski (Polish)
Português (Portuguese - Portugal)
Português - Brasil (Portuguese - Brazil)
Română (Romanian)
Русский (Russian)
Suomi (Finnish)
Svenska (Swedish)
Türkçe (Turkish)
Tiếng Việt (Vietnamese)
Українська (Ukrainian)
Report a translation problem
I can also be better about the caching I do: right now each individual light/bench/anything you build checks to see if it's a bench or light individually right when it spawns, and we cache the result of that check to use next time since that's better for performance than running all the checks again. Instead, I can run the checks the first time and cache it based on the building's def instead of the building itself. Since all buildings of the same type (e.x., Standing Lamp, Wooden Wall) all share the same def, we would never need to run the checks again for that def. This will help reduce some work being done every time something is built.
If you'd have some time soon, I'd be happy to work with you to see what other things we can do to help performance. I don't see any hitching in my testing, but I suspect that it's just my PC specs masking issues like this.
I'll mention that there was a IEnumerable loop being the root culprit of the long execution time on the patches.
To me, without digging much into the source or really knowing much about RimWorld mods, it seems like the patches are trying to disable/enable lights whenever something is built (really, spawned in), but briefly looking over the source it doesn't look like those patches check to see if the "room" something spawned in is the "outside map".
So they're spending a lot of time looping through the entire map looking for lights.
Personally, I don't think the mod should care about the lights on the entire map.. only lights in a proper "enclosed" room.
EDIT: Make sure you're testing this on the latest Harmony version, two weeks ago this wasn't an issue.. at all, but it suddenly became one after updating Harmony.
Ultimately, any time something is built in the game, the region they occupy is marked as dirty; regions are smaller than rooms, and you can enable the "Draw Region Dirties" debug display to see this in action. This happens in RegionDirtyer.DirtyRegionForThing. At some point in the near future, something requests the room that something is in and forces the game to evaluate the dirty regions to ensure that all rooms are up to date (RegionAndRoomUpdater.TryRebuildDirtyRegionsAndRooms and eventually RegionAndRoomUpdater.CombineNewAndReusedDistrictsIntoContiguousRooms).
After combining the regions into "region groups" (which appear to be temporary data structures analogous to rooms, RegionTraverser.FloodAndSetNewRegionIndex), the game then attempts to recalculate all rooms on the map using the new "region groups" that were affected by the dirty regions (RegionAndRoomUpdater.CreateOrAttachToExistingRooms). At this point the game inspects the rooms associated with the regions and considers a room change to have happened if: at least one region group contains regions that were previously part of two different rooms (e.g., a wall was removed); or, a region group has no current associated room (e.g., the last wall was placed, creating a new room whose regions are new and completely isolated from existing rooms). If a room change has happened, RegionAndRoomUpdater.FloodAndSetRooms is called on the room that changed (not all rooms).
The patches called out above postfix FloodAndSetRooms, which will only be called on the rooms that actually changed; notably, the "outdoors" of the map is a room and the code will run there. Running the code on the outdoor rooms is a requirement, since we want those lights to be on at all times -- and this behavior is why removing a wall will cause previously "on standby" lights to suddenly turn on. This does mean that the room changes force a full refresh of the lights in both affected rooms, which unfortunately requires looking through all contained and adjacent things in both rooms to see if any are lights. Fortunately, that information is cached from when the thing was first constructed, so the lookup isn't expensive and the O(n) search for lights shouldn't be that big of an issue.
One area to improve would be to check whether a light is already enabled/disabled before trying to enable/disable it. That would save some work in that we could prevent enabling/disabling glowers (which can be expensive). I saw a measurable performance gain in this case, but I'm uncertain that it's the normal case.
Probably unrelated, but I am noticing that removing a wall in a room (thus making it "outside") no longer re-enables the light, which isn't how it's supposed to work.
I've tested your most recent changes, and I definitely feel an improvement but there's still some pretty significant freezing & hitches when building long strings of walls not constrained in a room on a quick dev test world.
The longer the wall, the bigger the hitch. Hitching / freezing has been greatly reduced though and is very much playable again when playing normally.
https://i.imgur.com/LevXrk0.png
https://i.imgur.com/uDwK73b.png
https://i.imgur.com/qp5LsRW.png
It's possible you've hit a point where not much can be done, but I wanted to post anyway if you have any epiphanies on things to optimize further.
If you don't mind me asking what are tour specs? Are you using Windows?
Unfortunately it is pretty close to the end of the rope as far as tuning goes, I think. A lot of it comes down to the way I chose to structure the mod, which cant be helped without rewriting it. I've been slowly chipping away at trying to get a V2 of LightsOut running but progress has been a little stalled since I'm short on free time. It does look promising though from what I've been experimenting with.