Slay the Spire

Slay the Spire

686 ratings
Optimize the Spire
2
2
   
Award
Favorite
Favorited
Unfavorite
Qol
File Size
Posted
Updated
39.319 KB
11 Apr, 2021 @ 11:42am
6 Feb @ 3:47am
6 Change Notes ( view )

Subscribe to download
Optimize the Spire

Description
Essentially, this mod's goal is to make Slay the Spire run smoother when you're running it with mods. These changes affect vanilla spire as well, but their effect will be negligible in that case

For that, I've implemented a few somewhat invasive changes, which I'll explain below.

These changes don't affect RAM usage, so if you're having problems because of that, this mod will do nothing for you.
The (currently) newly released RAM Saver mod can help you with that!
https://sp.zhabite.com/sharedfiles/filedetails/?id=3002563327

Boring techinical stuff:
1) I've optimized hasRelic and getRelic to be O(1) from the theoretical worst-case of O(n). I did this by creating a hashmap that stores information on which relics are where in the relics arraylist and making those methods use the hasmap to skip list iteration.

In practice, this change has saved me 3 billion unneeded list-iterations during a heavily modded playthrough. The majority of which happen when booting up the game.

2) A more noticeable change, is that I intercept the standard, non-essential loggers and skip their outputs. Crash information is retained and this can be toggled in the mod config menu.

Printing to the console is a very wasteful process, skipping most of the bloat makes things like starting a new run or the game smoother and on lower-end PCs, maybe even the combat.
However, my approach isn't perfect, using sysout or registering your logger in a non-standard way will circumvent this measure but the majority is enough in this case.

3) When looking at the master deck and using the sort function, the game orders the cards every frame (30-60 times a second). I've changed this so that it only sorts the cards when needed.

In practice, this change will most likely never matter unless you're running a 1000+ card deck but every little bit helps.

4) If you look at upgraded cards in the compendium, all the cards you're seeing are duplicated and their copies upgraded every frame. Instead I save all the upgraded variants whenever they become relevant and make the compendium just render those instead. I also clean the Hashmap i store them in so that there's no unneccessary RAM usage going on.

This change may actually be quite impactful for people with issues in the compendium.

5) Filtering of unloaded characters for the run history save loading. When opening the run history the game normally goes through all your save files one by one and checks whether it can load them. This is very wasteful as it's possible to check the folder names against the currently available characters.

In practice this change makes a very noticeable difference if you have a lot of run history with modded characters you don't have active. It completely removes the lag when opening my run history when I only have a few characters loaded.

It's debatable how much these changes help, but it doesn't hurt to give it a try.
45 Comments
(Gk) Erasels  [author] 6 Feb @ 3:52am 
New update with an optimization from cany0udance! This optimization helps with the lag some of you might experience when opening your run history screen.
glennvtx 6 Jan @ 6:15pm 
THANK YOU.
(Gk) Erasels  [author] 14 Jun, 2024 @ 3:27am 
Hmm, your steps for repdouction make wrong assumptions.
> 4. Add MyCustomRelic to relic array.
This would trigger the doRecieveRelic method via the RelicGetSubscriber in the main mod file. That method would change the -1 to its actual location.
s.Claw 4 Jun, 2024 @ 4:09pm 
Hello, for the Relic patch, I am running into a bug where the hashmap has a stale -1 entry after relics are added to the relic array. I think that the code to check for array size difference needs to come before the first call to relicLocs.get(key).

int size = __instance.relics.size();
if (size != RelicOptimizationPatches.relicsSize) {
RelicOptimizationPatches.relicsSize = size;
RelicOptimizationPatches.relicLocs.values().removeIf(val -> (val.intValue() == -1));
}


The issue can occur like so:

1. Start with empty relics array
2. Call getRelic("MyCustomRelic")
3. Hashmap entry added for "MyCustomRelic" -> Integer(-1)
4. Add MyCustomRelic to relic array.
5. Call getRelic("MyCustomRelic")
6. Hashmap returns Integer(-1), so it enters into i != null logic.
7. relicSize check sees that relics.size() != 0, so it removes all -1
8. However since it has already found i = Interger(-1), it skips to the rIterSkipped case and returns null.
裂开logy 18 May, 2024 @ 8:16am 
Enable/disable this mode is the only thing I change. Could it conflict with any of "Relic filter mod", "Colored Map", "Shop Mod", "TrulyRandomMOd" or "BaseMod"?
(Gk) Erasels  [author] 18 May, 2024 @ 6:46am 
I don't see a way for this mod to cause that.
裂开logy 18 May, 2024 @ 6:05am 
Found a bug associated with retrieving the game after leaving in background for a few minutes. The game gets frozen and GPU hang at 100% usage for around 10 s before returning to normal.
(Gk) Erasels  [author] 13 Jul, 2023 @ 12:44am 
Alchyr released his great RAM Saver mod https://sp.zhabite.com/sharedfiles/filedetails/?id=3002563327
that will help with that for those struggling with missing letters in their text or RAM related crashes.
voov 29 Jun, 2023 @ 1:10am 
兼容,优化尖塔mod
bkerns2 10 Apr, 2023 @ 3:35pm 
Thank you for making this.