Live data from Hacker News

Serialization for C# Games

chickensoft.games

1–10 of 51 posts

Re: Serialization for C# Games

#3
Sometimes, when battling these issues, I wish the Smalltalk-style approach[1][2] was more popular/feasible. Basically, saving the entire state of the VM is a fundamental operation supported by the language. Only truly transient things like network connections require special effort.

There are some echoes of this with things like Lua's Pluto/Eris, or serializable continuations in other languages (eg: Perl's Continuity).

It's just such a pain to thoroughly handle that sort of stuff without language-level support. And doing a "good enough" approach with some rough edges is usually shippable, so it's hard to build a critical mass of demand for such support. And even if there was, it's very hard to add it to a language/framework/etc that wasn't designed for it to begin with.

I've had a decent experience with 'struct string' style approaches, like Lua's string.pack() or Perl's pack()[3]. It's a little brittle, but extremely straightforward and "not framework-y," which suits me. But it leaves out things like program execution state; it's just for plain data.

[1] https://en.wikipedia.org/wiki/Smalltalk#Image-based_persiste...

[2] example of using this serializable statefulness for serving web apps: https://en.wikipedia.org/wiki/Seaside_(software)

[3] https://perldoc.perl.org/functions/pack

Re: Serialization for C# Games

#4
This seems to cover many common pain points, but I’ve written my fair share of .NET serializers and for anything I build now I’d just use protocol buffers. Robust support, handles versioning pretty well, and works cross platform.

I’d like to know their reasons for making yet another serializer vs just using pb or thrift.

Re: Serialization for C# Games

#5
In my personal projects I’ve been using variations on the same simple code for saving/loadings objects for a decade or so, and have very few problems. The heart of the code is this interface -

    public interface IStashy
    {
        void Save(T t, K id);
        T Load(K id);
        IEnumerable LoadAll();
        void Delete(K id);
        K GetNewId();
    }
And implementations of that are very stable over time. Objects get serialized as json and stored in a folder named after their type.

There’s a small number of gotchas, for which I have well known work arounds:

- I generally won’t remove a property, but mark it as obsolete and stop using it.

- If I’ve added a new Boolean property, I’d tend to name it such that it defaults to false, or if it must default to true, have it stored in a nullable boolean, and if it loads as null (from an older instance of the type), set it to the default.

- some convenient types I want to use (as properties) are not serializable, so before saving I’ll copy their data into a serializable type, like an array of key values, then on loading rehydrate that to a dictionary. (I guess this is a harsh performance penalty if you’re doing a lot of it in a game)

Re: Serialization for C# Games

#6

RunUO has an implementation of this and it's like 25 years old but still worked really well

Wow clicked into the thread to see if anyone might mention RunUO :) it’s the only exposure I’ve had to serialization in C# I always wondered how it ranked compared to other approaches.

Re: Serialization for C# Games

#8
post #5

In my personal projects I’ve been using variations on the same simple code for saving/loadings objects for a decade or so, and have very few problems. The heart of the code is this interface - public interface IStashy { void Save (T t, K id); T Load (K id); IEnumerable LoadAll (); void Delete (K id); K GetNewId (); } And implementations of that are very stable over time. Objects get serialized as json and stored in a…

> I generally won’t remove a property, but mark it as obsolete and stop using it.

Presumably because loading will break?

> - If I’ve added a new Boolean property, I’d tend to name it such that it defaults to false, or if it must default to true, have it stored in a nullable boolean, and if it loads as null (from an older instance of the type), set it to the default.

Why?

Re: Serialization for C# Games

#9

Naive question: is there a reason why SQLite wouldn’t work for something like this?

I wonder the same thing. Perhaps less portable? IE can't package that up in a binary (I have absolutely no idea just spitballing)?

And very cursory search suggests maybe there is nothing to that guess: https://www.reddit.com/r/golang/comments/tqffv2/packaging_an...

It's an interesting question because I've run into some datascientists that were so used to working in memory with dataframes and similar that they moved mountains to do things like de-duplicate csv's in memory (that they couldn't all fit in at once) where-as they could have done so trivially with sqlite.

Re: Serialization for C# Games

#10

Naive question: is there a reason why SQLite wouldn’t work for something like this?

Well you still need to solve for what happens when a new version of your app (maybe with a new embedded version of SQLite) loads up an old data file saved by an old version of your app.

The old version might not contain all the tables you need, and the ones it has may not have the columns you expect. So you need to run some data migrations on the database. Now you no longer have a serialization problem but instead you have a schema versioning problem.

Post reply on HN