Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

[SugarCube 1] Massive slowdown and increase in page loading times.

Greetings

I was working on a game in Twine, and my goal is a very, very big one, with hundreds of thousands of text alone.
I was worried twine/html format of the game might not handle it, and just now something happened that makes me seriously doubt if I can really achieve what I want if this little thing is causing such a slowdown.

Best if I just attach my whole .html story project atm.
The problem shows up when you play, select the debug xp mode, go to character tab and start amping up the character attributes. At 100 of something and 30+ of something else there is a massively noticeable slowdown and increase in page loading times.

What's the cause of this? Is it the sheer amount of history? Because if getting 400 passages will cause that kind of slowdown everywhere it's really limiting to the possible size.
I'm really hoping it's some unknown to me bug I left over and not the engine limitation.

Best Regards

Comments

  • I'm not going to have time to really look at this for a while, however, from a cursory glance at the project I have some off-the-cuff commentary.
    • You seem to be keeping more or less immutable data within the story's variable store. Do not do that, if at all possible—doing so bloats each moment within the history for no good reason. You can store and reference your various details arrays/objects outside of the story variable store—within a sub-object of either the setup or window objects.
    • You also seem to be pregenerating large and, essentially, empty arrays. I'd rethink whatever it is that you're doing there.
    • Rewriting the character page so that it does not use passage navigation to function wouldn't hurt.
    • Disable the history via enabling the config.disableHistoryTracking setting. For more game-like stories, especially those which cause a lot of history generation, it helps.
    Switching to SugarCube 2, would probably also help. I don't know if that's an option for you.
  • edited June 2016
    I tried to have a look as I'm not getting any of these problems in my own large game but the forum uploader is not letting me open your story. I was also interested in what TheMadExile meant by his first point.

    Disabling history tracking is a good idea I hadn't thought of. I currently use it to check if a player has visited a passage to show some unique dialog, but I can probably replace that with a <<ift $armouryvisited is false>>hello! <<set $armouryvisited to true>> sequence to do the same thing for a performance gain. That way, the story is not trying to save history and does not examine the whole history when the armoury is opened again after the first time.

    Are there any effects on the save game feature without history tracking? I assume not, since save games would work if they just look at the save position and current variable states.
  • Claretta wrote: »
    ... the forum uploader is not letting me open your story.
    The attached file is a Twine 2 Archive, I right clicked on the file name as was able to download and import the contained Story Project using the Import From File option of Twine 2

    Claretta wrote: »
    I was also interested in what TheMadExile meant by his first point.
    The project sets up at least one array containing data that does not change during the life of the story, there-for there is no need to use a $variable to do this. It would make more sense using a property on a global object like setup to contain the data.

    eg.
    a. Replace the following <<set>> macro in a standard passage:
    <<set $ConsumableItemsDetails = [
    	{"name":"Water","hpbonus":1,"type":"drink"},
    	{"name":"Crystal Water","hpbonus":1,"type":"drink"},
    	{"name":"Orange Juice","hpbonus":3,"type":"drink"}
    	....
    ]
    
    b. With the following Javascript in a script passage:
    setup.consumables = [
    	{"name":"Water","hpbonus":1,"type":"drink"},
    	{"name":"Crystal Water","hpbonus":1,"type":"drink"},
    	{"name":"Orange Juice","hpbonus":3,"type":"drink"}
    	// ....
    ];
    
    c. You can still access the values in a standard passage like so:
    Items:
    1. <<print setup.consumables[0].name>>
    2. <<print setup.consumables[1].name>>
    3. <<print setup.consumables[2].name>>
    
    ... Now the contents of the array will not be stored in History or Saves.
  • edited June 2016
    Oh I don't use arrays so that won't be an issue in my game then. The only things in StoryInit are variables like:
    <<set $armoury to 0>>
    <<set $barracks to 0>>
    <<set $library to 0>>
    <<set $warroom to 0>>
    <<set $table to 0>>
    <<set $desk to 0>>
    

    And a whole heap of <<cacheaudio>> macros.
  • edited June 2016
    Claretta wrote: »
    Oh I don't use arrays...
    It does not need to be variables that contain arrays or datamaps, it can be any variable that contains a value that does not change during the life of the story then you don't need to track or save.

  • edited June 2016
    I hadn't began implementing most of the changes advised yet, other than checking the disableHistoryTracking which, indeed, completely eliminated the slowdown.
    Still doesn't change the fact that some things are ruining the optimization and I need to figure ways to counter it.

    Luckily the only usage of history was the <<return>> macro, which can be subsituted with just assigning a variable with the use of passage() function, that doesn't return empty unlike previous() when history is disabled.

    Also I'm curious what big of a change would switching to SugarCube 2 make.

    As for the arrays, while I didn't exactly know how to use the setup. thing before, I had determined that what I'd done to best attribute to my inventory system idea.
  • edited June 2016
    If you disable history tracking I'm not sure what value the other tweaks would have. Most of them seem to be focused on clearing unnecessary data from history. But if you completely remove history tracking there's nothing much in that data store to begin with...
    Rafael256 wrote: »
    Still doesn't change the fact that some things are ruining the optimization and I need to figure ways to counter it.

    Well it does, doesn't it? If the history state was the slowdown then the problem is effectively fixed.

    I haven't looked at the story so you might not do this, but the only other thing I can think of is try not to run Javascripts on every passage. If you must use multiple passages, keep the scripting for each one relatively light.
  • edited June 2016
    Hm, that so? What I was worried about was some optimization issues that would pop out further down the line, but if you say that's all to do with history and disabling history solves it all...
    I guess I'll have to see for myself then. For now, problem is solved and there is plenty advice here as it is.

    Thank you all for replies!
  • Rafael256 wrote: »
    Also I'm curious what big of a change would switching to SugarCube 2 make.
    If you meant what would you have to change, then based on your posted example, not much. From memory, you'd probably only have to make some CSS changes.

    If you meant what would you get out of doing so, then SugarCube 2 is a significant improvement pretty much across the board. In particular to your situation, SugarCube 2 has a variable sized story history—meaning that you don't have to completely disable it to manage its allowable size. Also, as of version 2.5.0, even if the story history is restricted to one moment—equivalent to disabling it in SugarCube 1—the <<return>> macro and the "visited" family of story functions (lastVisited, visited, visitedTags) continue to work as intended even over long playthroughs when expiring moments.
  • Claretta wrote: »
    ... But if you completely remove history tracking there's nothing much in that data store to begin with...
    (From memory)
    Even with history disabled each time the Reader navigates between passages the current state of all known variables is copied and that copy is what is made available to the new passage being shown. The coping process takes both time and memory, which is a waste for variables that will never change value.

  • greyelf wrote: »
    Claretta wrote: »
    ... But if you completely remove history tracking there's nothing much in that data store to begin with...
    (From memory)
    Even with history disabled each time the Reader navigates between passages the current state of all known variables is copied and that copy is what is made available to the new passage being shown. The coping process takes both time and memory, which is a waste for variables that will never change value.

    But, provided the history is disabled, the previous 'copies' get removed automatically, right?
  • Rafael256 wrote: »
    But, provided the history is disabled, the previous 'copies' get removed automatically, right?
    Yes, that is correct.

    greyelf's point still stands, however. Keeping effectively static data within the story variables does bloat the singular history moment unnecessarily. This includes not only the working in-memory copy, but also the serialized session copy and all saves.

    Disabling the history is a good idea for game-y stories of this, apparent, type and solves issues related to large histories. That said, not stuffing every little thing into the story variables is just as important. Ideally, story variables should only be used to track mutating data.
  • edited June 2016
    greyelf wrote: »
    Claretta wrote: »
    Oh I don't use arrays...
    It does not need to be variables that contain arrays or datamaps, it can be any variable that contains a value that does not change during the life of the story then you don't need to track or save.

    I don't use any of those either. :p I don't see the point of storing static data in "variables". Data in setup I can understand.

    My main issue with arrays has always been that they seem to introduce more points at which bugs can enter. I'd rather keep things as simple as possible, even if it is slightly less efficient, as long as the simpler approach does not introduce real-world performance losses.
Sign In or Register to comment.