Flax Facts #6 – Persistent Data

Flax Facts #6 – Persistent Data

Game saved.

Another Friday Flax Facts!

Today we have a bold topic. How many times were you in need of writing your own system for handling persistent data between restarts: game states, configurations, local runtime asset storage and everything that needs to be held for the user until next session? Flax has an answer for this, you would write none of that in the future.

Persistent Data

Since we know what you really need, while game development, we had tried to thought the best way to put this specific topic (as many others) into the engine so you would just use it and make it work! This week we have something we call persistent data. It’s all data that you want to keep between games, or maybe this data should be present when user launch your game for the first time and then you want to update it while the game is running and save it for future uses.Flax’s persistent data has the more “Data” approach than “Game” approach. But we believe that whole data should be presented is data like structures. Whole hard work of persistent data will be done by the c++ engine, so worry not about performance. But we should get to the most interesting part, which is API.
  • Attributes
Every game engine I have seen with C# backend has no attributes approach the holding save data. In Flax, we present you this:

    private string _name;

    [PersisitentData("Player", "PlayerName")]
    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            //Optional
            BasePersistentData.File("Player").Flush();
        }
    }

    public void Start()
    {
        Debug.Log("Player name is " + Name);
    }
Depending on whether your data save is large or small, you can choose different approaches. You can flush all data to a file every method call. We will handle to make it performant! Or you can make one big flush every few minutes or in checkpoints! But attribute will keep track when to include this value into file.
  • Layer of Abstraction
Have you ever consider why there are no abstract classes in every any engine, that lets you override its base behavior and forces you to write your own classes? It’s because of performance potential issues. If you use abstract class and derived class has no sealed counterpart you will add a few IL calls to the stack. It’s not many, but for sure will hurt your performance if you would call this method few hundreds of times in one frame (at least in mono). So why we give you this power? We believe that game programmer should have all the performance optimization tools and customizations in his/her hands. So we came up with this:

    // Customized data container
    public sealed class MyGameSettings : BasePersistentData
    {
        public float Setting1 { get; set; }
        public bool Setting2 { get; set; }
        public Bar Setting3 { get; set; }

        public override object Get(string a)
        {
            Debug.Log($"Access setting: {a}");
            var result = base.Get(a);
            // Do Cool stuff
            return result;
        }
    }
    // Usage
    public void Foo()
    {
        var myValue = BasePersistentData.File("file1").Get("PlayerName");
        MyGameSettings.File("file1").Setting1 = 25f;
    }
  • Rich configurations
Next thing we had noticed that there is literally no configuration settings in every engine. Add this up with no customization of core engine methods and we have every developer creates his system for every part of the game, so in the end creating his own game engine on top of another one adding overhead! We cannot let this happen in Flax.PersistentDataConfig
  • On demand initialization
To launch your game we would need a few configurations files loaded, like prefabs, scenes, shaders, different settings. But the best part of the Flax is that we wouldn’t do that if you require so! Be default for all basic users we will have the engine “Game Ready” with a no-brainer, where you can create the new project, and launch your game and we will handle everything for you, including initialization of the PersistentData,  searching for its config, and loads everything. But you might not need this! We will have API to make you able to create your own calls to load prefabs, scenes, shaders and so on in you own fully customizable pipeline (this will be expanded other Friday), this includes PersistentData. If you don’t need it, we won’t add any overhead for you!StripModePeak
  • Built-in network config
This might not be suited for everybody since network architectures might get complicated and cumbersome, but if you would need only basic download from your SFTP service a default configuration, we provide this for you! Remember you will always have the option to override those methods with your own backend communication 🙂

    new PersistentData.SFTP("sftp://flaxengine.com/my-awsome-game/setting.json");
    new PersistentData.HTTP("https://flaxengine.com/my-awsome-game/setting.json");
  • Small size and secure
Last big feature that will be provided out of the box is compression and encryption. By default, all you get is plain text JSON file, since both compression and encryption increases the time required to load a file. But we expect all kinds of scenarios. Like, Cloud saves uploads. This stuff has to be lightweight, and other engines will force you to do this on your own. But in the Flax, you only need to change one setting in configuration to have this feature! From the other side, you might want to secure your saved data, to prevent players from cheating. There is no 100% secure way to do this, but we provide you with embedded into C++ engine encoding method that will prevent 99.9% of the users from even trying!

I cannot wait!

So you might be wondering when this all necessary feature will be released? For now, let’s say, we need to wait for another Friday Flax Facts 🙂Have a nice day!
Tomasz Juszczak

Lead Tools Programmer

Leave a Reply

Your email address will not be published. Required fields are marked *