bomberland
bomberland copied to clipboard
Simplifying Json deserialisation
TLDR In some statically typed languages you can deserialize json just by creating a class and calling a method. Unfortunately bomberman's types make it nearly impossible. Here I propose a small modification to your types that would make this easy to achieve.
For example, a ServerPacket has 5 different forms type ServerPacket = GameStatePacket | GameTickPacket | EndGameStatePacket | InfoPacket | NextGameStatePacket
.
This could be modeled using inheritance, but polymorphic deserialization of json is very often not supported by the json libraries in statically typed languages.
The alternative is to create a class with all of the possible properties, which can work unless those properties overlap in ways that cannot be expressed. Unfortunately four out of five of the game event types contain a payload
property and they are of different types. Again the payload
type could be modelled using inheritance, but again polymorphic deserialization is hard.
Suggestion Make each XxPacket
type contain only two properties, type
and xx_data
. That way your typescript code can stay mostly the same, and C# code can represent a server packet as a single class, and deserialization is easy
Typescript definition example
export interface GameTickPacket {
readonly type: PacketType.Tick;
readonly game_tick_data: IGameTick;
}
export interface GameStatePacket {
readonly type: PacketType.GameState;
readonly game_state_data: IGameState;
}
// etc
export type ServerPacket = GameStatePacket | GameTickPacket // | etc
C# definition example
class ServerPacket
{
public string Type { get; set; }
public GameTick GameTickData { get; set; }
public GameState GameStateData { get; set; }
// etc
}
Deserialization
var serverPacket = JsonSerializer.Deserialize<ServerPacket>(jsonString);
If you do the same with all your union types, that would greatly reduce the friction for starting with a language like C#.
Seems reasonable, how would it be done currently? I'm assuming you would have to discriminate on the type before being able to determine how to deserialize to a more specific class.
Would also have to lift and shift the other starters that are currently working
The idea is to avoid having to discriminate on the type before deserializing. I'll try to put together a PR this weekend.