What happened with Seedship in March

At the start of March I set out to write a new set of 10 random events for Seedship, release them along with a few minor improvements, and then move on to Beyond the Chiron Gate. I’d originally hoped to write the new events in a week; in the end I couldn’t spend as much time on them as I’d hoped, so it took two. I released them along with a few other improvements as version 1.2.0, and then turned my attention to my new game.

Then the bug reports started to come in, through email and Twitter and Reddit. The game was running more and more slowly, with delays of multiple seconds on loading new passages. For a while I was confused about what was causing this, until one of the bug reports mentioned the slow-down increasing when a lot of high scores were saved.

One of the minor improvements I’d made in version 1.2.0 was to increase the number of high scores that could be saved from 100 to 1000. I’d chosen the 100 figure arbitrarily in the first place so I didn’t see any harm in increasing it. But it turns out that a Twine story’s performance slows down with the total number of variables that are stored, even if it’s not using those variables in code. (For someone familiar with how Twine works this might be obvious, but it hadn’t occurred to me.) And the high scores are just a special kind of variable that persists across game restarts.

What’s more, the high scores were stored remarkably inefficiently. Each high score was a JavaScript object with two dozen properties representing every property of the planet and every line in the score calculation table. Some of the values, the planet attributes, were actually stored as strings. They were the work of a developer who wasn’t very experienced with Twine and JavaScript yet, and didn’t think he’d be maintaining the code a year later and making it run on mobile phones with limited processing power.

I could have just released an update that capped the number of high scores at 100 again, but I realised that even games with only 100 scores were running more slowly than I’d like. There must be a way to store the high scores more efficiently.

Luckily, I’d already made a system to encode individual high scores more efficiently: the share system. It encoded everything essential about a high score into a single string that can be used as the query part of a URL. If I encoded all the high scores like this before I saved them, I’d be reducing each one from dozens of variables to one variable.

So I converted the code that encodes and decodes high scores into JavaScript for efficiency, since I’d need to be running it on every high score in the list, and I wrote some code that would run when you load the game that would detect if the high scores were in the old format and convert them to the new one. I also went through and replaced a lot of constant values that I had been storing as Twine variables and converted them to JavaScript constants, which also reduces the amount of work the game has to do on each passage load. With all that done, I launched an update that not only fixed the slowness but also made the game a little faster than before.

There were a few bugs with the new high score system. The high scores weren’t being sorted properly, and some game endings would lead to high scores that caused error messages to display. I’ve since then released a fix for these issues. I don’t regret rushing out an update that replaced the slowness (a major bug that made the game unplayable) with a comparatively minor bug, and fixing the minor bug later.

It’s now been nearly 24 hours since I released the high score bug fix and no one has reported any more problems, so I think Seedship is finally stable again. (But if you find a bug, please do report it to contact@johnayliff.com.)

What I’ve learned:

  • Don’t release an update that increases the amount of data that can be stored without thoroughly testing what happens if lots of data is stored, you idiot.
  • Twine stories get slower with the total amount of data they’re storing, even if they’re not executing much code. (I had no idea, but in hindsight I should have guessed.)
  • Pure JavaScript code executes much more quickly than the equivalent code written in Twine macros. (I’d suspected this was the case but now I know.)
  • I’m a much more technically competent Twine and JavaScript developer than I was a year ago.
  • Enough people are playing Seedship that serious bugs get reported to me quickly, and the players who report bugs are generally helpful and supportive. (Thank you!)

This experience has made me more aware that I need to think about resources and code efficiency when writing Beyond the Chiron Gate, which is going to be a bigger game than Seedship and so has potential to be very inefficient if I’m not careful. I was already planning to write as much code as I could in JavaScript rather than SugarCube macros, but I’m now even more determined to do that, and will also be thinking about how to store data as efficiently as possible.

My plan for April is to focus solely on development of Beyond the Chiron Gate.

This entry was posted in Dev Diary, Seedship. Bookmark the permalink.