Technical
Blog

0.12.4 includes a signficant rewrite of large parts of the core game engine. Bits that I didn’t like had started to build up, and some plans I have for new game modes looked to be quite difficult to implement because of decisions I made earlier that seemd like a good idea at the time.

The current state of the engine is now much better, however the process does make me nervous. The changes affect not just how the engine plays the game, but also how data is saved and loaded. And people generally don’t like their save games being corrupted.

So as part of the work for this version I also wrote a tool (that I have been intending to write for a while) that checks for save game compatibility. The idea is the tool creates games with various combinations of settings, plays them through (with the easy AI) and saves the result. As part of the normal automated tests I run with each version, these save games are then loaded, the moves replayed, and the result compared with the previous result. Any discrepancies are failures that I can investigate.

Importantly, the initial set of games is based on running the tool before the big engine changes. Unfortunately (or perhaps forrunately) it discovered a bug straight away. Loading a game with “free turn” set to true (i.e. any of the Chain game modes) would not always pick up the “free turn” setting (this was fixed in 0.12.3).

So the plan is every time I add a new game mode (or change the engine significantly), I generate a new set of save files, and during every release the current set of save files is checked for compatibility. Hopefully this should keep everyone happily saving and loading.

0.9.2 doesn’t contain any new features, but does contain a lot of optimizations. Here is more detail on some of them.

Tic-tac-toe Collection is built using Xamarin Forms. This post assumes familiarity with Xamarin, Xamarin Forms and .NET. I do have another post planned with more detail on these steps for those less familiar.

Firstly, I enabled Proguard, a toold for stripping out unused code at the Java byte code level. Doing this for Xamarin is a bit weird because the version of Proguard you get by default does not work if you are targeting Android 7.0 or newer. A Nuget package is recommended but that didn’t work for me either due to some path issues. So I just extracted the jar and specified the path manually.

I grabbed an example Proguard config file off the internet, added some extra bits I found elsewhere for Google Ads, and tried to run it. I worked through the errors about missing things, adding to the config file as I went. On the whole, actually straightforward.

The next step was to enable “link all” in the Xamarin linker settings, to remove unused code at the .NET level. This time however, instead of immediately excluding things from linking that caused problems, I realised I could actually reduce the number of things only referenced using reflection.

By default Xamarin Forms uses reflection heavily when data binding. This can be largely avoided by using compiled bindings. To use it you need to do two things: firstly, enable XAML compilation (which you should have been using already); secondly, add appropriate `x:DataType` properties to your XAML.

This underused feature allows the compiler to generate strongly typed bindings based on the type you specify.

After doing that, the only things left that the linker was breaking was types used in JSON serialization, which were easily fixed.

The final thing I did was to replace Autofac. Autofac was the first IoC container I was introduced to and has been my default choice, pretty much without any thought. However I came across this chart of IoC performance and realised I was not using any of the clever features that justified Autofac and so, switched to LightInject.

Enabling Proguard and the linker cut the APK size down from about 32MB to 22MB. The improvements from the compiled bindings and Autofac changes are harder to measure.

The most notable improvement is cutting in half the time to go from the main screen to the game screen directly, and all of the steps will have helped.