Making Web Tools for Games with Unity & WebAssembly
Participating in game jams, we sometimes did a bit of practice, coming up with random ideas before the actual game jam, before the theme was revealed. We just took themes from previous jams, from one place or another, and did brainstorming sessions.
And so I thought about making a tool that would generate random themes from a bunch of options, I considered how I would structure the code and it looked fun and simple enough to just try making it.
Speaking of the code design, the idea was to use Composite, Decorator & Strategy patterns together in a way where generators could be built in a very modular way.
I wanted to make it as a web tool and put on my blog, I haven’t really written in js before, but had experience with Unity and C#, and knowing about Unity WebGL decided to try it. I knew it wasn’t fast, but because I wanted to make a small tool, I thought it will load fast enough.
Going into WebGL I didn’t know what things will not work out of the box. But the main hope was that I wouldn’t need to touch js or html, the same way I don’t often go to Java or Objective-C for Android, iOS games made in Unity.
Turns out I needed to change the html, the default one isn’t fullscreen, which isn’t ideal for a tool that should look good on mobile as well.
By default Unity also shows an annoying dialog each time, but it can be removed by adding a bit of js to the index.html file.
To avoid doing these modifications each time after Unity generates the index.html, they allow making your own template index.xml with needed modifications that Unity will use on each build.
Here is the link to the final index.html I’ve used: https://gist.github.com/Stals/ad0c2a4a62d3e7ea4acf4a53b0c0d0f7
I’ve tried to allow the copy of the generated text, but after spending too much time trying to modify the generated html and js, I just gave up.
Unity generates an HTML that doesn’t have anything aside from the Unity app itself in it, so to display the generator on the page on my blog, I thought I would just add it inside the iframe. This went pretty smoothly. On the website it looks like this:
During development I was opening the html locally – it was quite fast, but when I’ve put it on the website, I got the dreaded long loading times, especially on mobile devices, it took over 10 seconds. And the sad thing is – I didn’t consider the loading times would differ from local ones, and already spent time polishing. But I wouldn’t stop now, right?
I’ve searched if the loading speed could be improved, and found that newer Unity versions had the WebAssembly option.
Thanks to Unity – switching from asm.js to WebAssemblies version is super simple, just by changing one setting.
Actually not all browser versions supported WebAssemblies, so I needed to build to both targets: WebAssemly and asm.js.
Even though I have just a few scripts and text files – build times for WebAssemblier take a while (seems like it rebuilds everything from scratch every time, even if nothing changed), but it did actually shave quite a lot from loading times.
WebAssembly uses less memory on disk, so that also may be the reason it loads faster, but for a few scripts and small text files, 6 MB seems too much, and the mobile version of the generator still isn’t fast to load.
Already having the framework, I thought I would try adding the game title generator.
Where theme generator just took predefined lists and did a weighted random, this one needed to support different ways of combining strings together.
The code design proved to be very extensible, even though initially I didn’t expect features I would require, it handled them pretty well.
The result was pretty fun to play with, it both generated the good sounding titles you could actually use and as is the nature of randomness – some silly options like “Galactic Chicken of the Blood”.
Here are the generators so far, check them out for yourself:
In the end, even though I was familiar with Unity and C#, looking back on it – I think it would be faster (in both the development time and the actual loading time) to use something like TypeScript, that hopefully wouldn’t have all of the above problems, and still allow to try the Object-Oriented design I wanted. And if in the future I would want to add any functionality to the generators, I think I would rewrite them first.
And after learning about WebAssemblies, if for some other tool I will need faster computation than js could provide, I will try the moving computations to pure WebAssembly,
If you liked this article and would like to see more like this one, or just catch the next article in this series – you can subscribe to Let’s Make a Game.