Optimising Large Scenes - 2.3 Launch Week - Day 2
In day 2 of Owlbear Rodeo 2.3 launch week we explore how we can now support much larger Scenes.
Owlbear Rodeo 2.3 is coming October 9th and to celebrate the release we’ll be posting a new blog post everyday until release. Each post will cover a brand new feature made possible by our new rendering engine we’re calling Warp Core. Warp Core is built from the ground up to provide outstanding speed, cross-platform compatibility and beautiful visuals for a modern VTT experience.
In the previous post we showcased enhanced support for larger maps and in this second blog post we’re going to explore how we’ve improved the support for larger scenes.
Each item in an Owlbear Rodeo scene is composed of multiple smaller components. For example each dragon shown below stores where it is, how big it is, what video it should load and more. In order to actually show the animated video there are other things we need to store as well. Things like the actual video asset being played, the current frame of that video in GPU memory and the material used to show that video on screen. These things can take up a bit of memory but since they are all the same between each dragon we can have one copy and share them between all instances.
In programming the idea of sharing common properties between multiple items is called the Flyweight Pattern and we use it all over Warp Core to keep the memory footprint low.
For example this is how we can render over 100 of these dragons at once but still only take up 130MB of CPU memory and 64MB of GPU memory.
While using this pattern will keep our memory usage low if we were to keep adding more items to our Scene we would run into issues with CPU usage. To dive into this let’s break down a possible scenario. Scenes in Owlbear Rodeo support multiple maps side-by-side so in a multi-layered dungeon you might have five full encounters or more in a single Scene. If each encounter had 200 items (this could be characters but also props, heal bars, dynamic lighting, etc) then you would have 1,000 items in the one scene.
If every frame we had to process each of those items then we would quickly run into issues with our CPU performance. To solve this we will make use of the fact that we’re only likely to focus on a small part of the Scene at once (like one of our five maps). This means the majority of our items will be outside of our viewport so there’s no point in processing them. To do this programmatically we will make use of something called a spatial index.
Below you can see how we’ve split our dragons into a bunch of rectangles, we then store those rectangles in a tree structure so we can quickly find just the items that are visible.
This allows us to scale to more and more dragons as we only have to draw the dragons we can currently see. So we can continue adding more and more dragons…
Alongside this Warp Core also uses a technology called WebAssembly which allows us to run complex code in a much more efficient way. Using WebAssembly also allows us to make sure Warp Core is a lot more consistent between all the desktop and mobile browsers. This is great for us as it allows us to ensure a great experience no matter the platform or browser.
With all these improvements Warp Core can support much larger Scenes which is critical for not only those big dungeon delves but also your sprawling hand drawn maps.
While both this post and the previous one have been very technical the next few posts will focus on some big new features. So stay tuned because we have a lot more left for Warp Core launch week!