0

I'm writing a game saving function. When serializing the game world, areas has loop reference:

public class Area
{
    List<Area> pathArea;
    List<int> pathCost;
}

Before area1 is serialized and get an $id, the pathArea gets more area2, area3, that also have area1 as a neighbor.

How to work around this?
I use a Relink function to solve parent back-reference:

public class District
{
    private Area parent;  //pseudo// parent_Area::Relink { all children => parent = self }
}

Value pair to solve dictionaries:

public List<KeyValuePair<District, Building>> DistrictBasePair
{
    get => districtBase.ToList();
    set { districtBase = value.ToDictionary(x => x.Key, x => x.Value); }
}

But neighborhood loops... I wonder how to serialize them? Do I have to write a remapping function?

1: Remapping post process from name to obj

foreach(var n in pathAreaName)
{
    pathArea.Add(DictName2Area[n];
}

2: An indepedent Path Manager class design. I prefer not to use this in a small game.

What is the common way to solve this problem? Does Newtonsoft or .Net Json provide a function?
Like a ref id option can save you a lot of time writing you own ID mapping functions.

Question 2... The game world are serialized depth first way, to an ugly biased tree.
How can I change some setting or config, to get a breadth first balance tree?

When I simply serialize the world object, it turns into an biased tree, because of the complex class relations above.
If I serialize the world layer by layer, area, district, sector... I can't use the automatic object ref-id system in json.
How do you get a balanced tree? Can I control the json serialization, and make ref to an object that not yet appears?

area1:
  "pathArea":{"$ref":"5","$ref":"6"}

...

area2:"$id":"5"
...
area3:"$id":"6"

Or can I get these ID, and use them when I serialize the finer layer.

Areas.json
area:"$id":"123"

Districts.json
district:"parent":{"$ref":"123"}

Edit: I migrated the code from Newtonsoft.Json to System.Text.Json (.Net 6.0). I found that the later can handle this, in area1's neighbor, area2 show area1 as a $ref.

In System.Text.Json, there's no problem 1.

Still, the tree is biased. I want a World -> {area1...} -> {district1_1...} structure. What I got is a tree that put like everything into area1, and this tree is hard to read, may have some problem when I write more info.

I found that:

  • M1. A [JsonPropertyOrder(10)] decorator can delay some fields being serialized within the object.
  • M2. A speciel designed helper/manager class can delay the info serialization after the object.

I've already written lots of medium classes in XML serialization, to make moderable prototypes. But the M2. helper classes actually change the model logic.

Should I change the game logic, just to make a prettier object tree?
Or small hacks like M1, and many more, are sufficient to write a good saving function?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
zhaihouxi
  • 11
  • 5
  • What JSON serializer are you using? – ProgrammingLlama Oct 12 '22 at 06:58
  • You can create a seperate Poco for `Area` and use that. This `ChildArea` only has a string `Neighbour`. This will give you only 1 level deep of serialization. – klekmek Oct 12 '22 at 06:58
  • @ProgrammingLlama first Newtonsoft.Json, then System.Text.Json. – zhaihouxi Oct 12 '22 at 07:00
  • If you are using Json.NET, your question resembles [JSON.NET StackOverflowException while serialization](https://stackoverflow.com/q/41828014/3744182). Beyond that, might you please [edit] your question to share a [mcve]? Is your only problem that your JSON is serialized depth-first rather than breadth-first, leading to possible stack overflows? – dbc Oct 26 '22 at 20:32
  • Thank you! That custom converter is great. That is my only problem. And I used poco graph as a medium. – zhaihouxi Oct 27 '22 at 13:29

0 Answers0