Optimizations roadmap

Game performance in all aspects is an important area of our work. It was not left unnoticed by us that game simulation performance (tick rate) noticeably decreased lately due to the increase of the number of objects and growing complexity of players’ scripts. We understand it can lead to negative sentiment on the subscription-based model, and we won’t tolerate this situation. So in this post, we’ll talk about the three directions we plan to move so as to radically optimize performance.

Runtime: new virtual machine

Let’s begin with the most exciting things. As you perhaps already know, the Screeps server executes players’ scripts using the standard Node.js module vm. This is a relatively convenient environment for executing JavaScript code, but it has a serious disadvantage: scripts are not fully isolated from each other and the parent environment, but they share heap memory, garbage collection, and event loop. Because of this, running players’ scripts can’t be fully controlled by the engine, which adversely affects performance of both the game world and individual players’ scripts in particular.

And here we have terrific news. Marcel Laverdet whom we already well know, recently wrote a native library isolated-vm designed to solve this issue especially for Screeps. It allows to directly create and control V8 isolates to wrap players’ scripts into completely isolated their own environments, and runtime state of such isolates can be serialized and transferred. A runtime engine refactor using this library potentially allows for the following:

  • The heap memory accessible by your script will be only yours and nobody else’s. You can see the exact volume of heap memory your script uses.
  • Everything in the heap memory (not just compiled scripts) can be saved between ticks and moved to other physical nodes for resuming in the next tick.
  • The possibility of the transfer of serialized states makes it unnecessary to assign players to certain servers. It will seem to players that their scripts are always executed on the same physical server. This will not only improve caching time of newly-commited code, but will also remove the need to periodically calibrate runtime servers (popularly known as “reset storms”) which used to be required to optimally distribute players affinity across servers.
  • Garbage collection executed on your account CPU will depend solely on objects in your heap memory rather than objects of other players.

So far, we’re just exploring these possibilities and building the first prototype of the new virtual machine architecture, but the potential is seriously impressive.

Database: world shards

The performance of runtime servers is currently not the only one and perhaps not even the main performance bottleneck of the world in general. The Screeps game world has grown to such an extent that the most powerful machine available from our hoster currently runs our database at 100% of its capacity. We can’t merely add runtime servers anymore since the database can’t manage such amount of I/O requests. We experimented with different setups of database sharding and replication, but all of them incur unacceptable overhead. It looks like the most effective way to horizontally scale the database is to review the very architecture of the official servers cluster.

Currently, our cluster can be represented in a classic “star” layout with the database in the center and runtime servers on edges. The game world is consistent and synchronized as a whole. We plan to move from this architecture to a new layout of “multiple loosely coupled stars.” Our consistent game world will be divided into “shards” each with its own database of game objects, own game map, and own set of connected runtime servers. Creeps will be able to move between shards through special portals, but different shards will see time flowing independently without synchronization (i.e. Game.time in different shards will not match and tick rates will differ).

Your code will be executed in each shard separately. A special API will allow you to determine which shard runs your code at the current moment. The CPU limit for each shard can be set on a special page, and their total sum should match your account limit.

This vision still has some unresolved issues, but in general, the new system will lead us to an easily scalable horizontal system allowing for expanding the game world virtually without limitations and without increasing the main DB load. Right with the launch of this feature, we plan to launch a shard with a 2-second tick rate. You’ll be able to respawn and start playing in it, or direct your creeps there through portals to create an “inter-shard” colony. We expect that the flow of players on the new shard will unload the old (current) one which will favorably affect its tick rate as well.

Client: WebGL renderer

Currently our new developer Fedor works on a new graphics engine for the game using PixiJS. This is a 2D engine for games and complex graphics development that utilizes WebGL as the main rendering method, falling back to canvas if WebGL is unavailable. The graphics won’t radically change soon (though eventually we have redesign plans as well), but the way it’s displayed in the Steam browser/client will change. Currently all the game graphics is based on SVG/canvas, but SVG will be phased out completely, and canvas usage will be very rare. This will allow for the following:

  • WebGL uses GPU and is optimized much better than SVG. Your laptop won’t get hot and drain your battery as you’re just watching your room in Screeps.
  • Since all game objects will be stored as 2D sprites, we’ll be able to customize graphics and possibly even introduce customizable game themes.
  • We’ll obtain tools to create new beautiful animation and special effects. For example, we’ll be able to add lighting effects and create a special API to control glow color of your creeps. This graphics engine will also give us more possibilities in terms of room decoration.

When will all this happen?

We plan to start publishing early iterations of first prototypes across these 3 development tracks within coming weeks. For example, you’ll be able to activate the WebGL renderer with the help of a special experimental option in the client’s settings. New back-end features will be first run on PTR, and we’ll announce them separately. Stay tuned!

Have comments or feedback? You can discuss this post here.