Migrating from org.json to gson. This will greatly simplify serialisation/deserialisation in the long run, so that we don't have to manually specify how every single thing is serialised and deserialised - we can simply add the @Expose annotation to it. For more complex types, we will have to write JsonSerializers, JsonDeserializers or TypeAdapters.
This has come with significant changes to the serialisation format. The most notable changes are that stores/subsystems will no longer be flattened:
And that things such as entities, items, spells, etc now store an ID instead of their absolute class path:
// old
{
"class": "jr.dungeon.entities.monsters.canines.MonsterJackal",
"x": 5,
"y": 40
}
// new
{
"id": "monsterJackal",
"x": 5,
"y": 40
}
This is also a security improvement, as it prevents against injection attacks by whitelisting what can be used.
To allow this, a registry system has been added. Types such as Entities and Items can specify that they have a registry by annotating them with @HasRegistry, and optionally implementing Serialisable:
@HasRegistry
public class Entity implements Serialisable {
And everything that extends it has to add the @Registered annotation to specify its ID, for example:
@Registered(id="monsterJackal")
public class MonsterJackal extends MonsterCanine {
The rest is automatically handled.
As well as this, the old Persisting interface has been removed. Objects can no longer store raw persistent data in a JSONObject. We will have to find a new way to store animation data in the renderer; I think it would be better to store it renderer-side, rather than directly on the entity.
Due to the fact that gson TypeAdapters have no ability to pass in context, we can no longer resolve entity references by UUIDs at deserialisation time. To combat this, I have also created EntityReference. All references to entities will have to be replaced with this. It can be used similar to AtomicReferences:
private EntityReference<EntityLiving> targetEntity = new EntityReference<>(anEntity);
targetEntity.set(player);
targetEntity.get(dungeon); // returns player
The references store the UUID, and lazily get it and cache it when .get() is first called. Dungeon or Level can be passed in. If Dungeon is passed in, it will search all levels for the entity until it is found.
As a side note, I have only just realised that unserialise is grammatically incorrect, yet we use this term everywhere in the code. Considering most references to it are disappearing, I can probably fix that.
TODO
[x] Register all entities
[x] Register all items
[x] Register all AIs and AIStates
[x] Register all spells
[x] Register all aspects
[x] Register all status effects
[x] Find anything else that needs to be registered
[x] Convert everything to use EntityReferences
[x] Deal with container item references
[x] Deal with EntityLiving serialisation in ItemCorpse
Migrating from org.json to gson. This will greatly simplify serialisation/deserialisation in the long run, so that we don't have to manually specify how every single thing is serialised and deserialised - we can simply add the
@Expose
annotation to it. For more complex types, we will have to write JsonSerializers, JsonDeserializers or TypeAdapters.This has come with significant changes to the serialisation format. The most notable changes are that stores/subsystems will no longer be flattened:
And that things such as entities, items, spells, etc now store an ID instead of their absolute class path:
This is also a security improvement, as it prevents against injection attacks by whitelisting what can be used.
To allow this, a registry system has been added. Types such as Entities and Items can specify that they have a registry by annotating them with
@HasRegistry
, and optionally implementingSerialisable
:And everything that extends it has to add the
@Registered
annotation to specify its ID, for example:The rest is automatically handled.
As well as this, the old
Persisting
interface has been removed. Objects can no longer store raw persistent data in aJSONObject
. We will have to find a new way to store animation data in the renderer; I think it would be better to store it renderer-side, rather than directly on the entity.Due to the fact that gson TypeAdapters have no ability to pass in context, we can no longer resolve entity references by UUIDs at deserialisation time. To combat this, I have also created
EntityReference
. All references to entities will have to be replaced with this. It can be used similar to AtomicReferences:The references store the UUID, and lazily get it and cache it when
.get()
is first called.Dungeon
orLevel
can be passed in. IfDungeon
is passed in, it will search all levels for the entity until it is found.As a side note, I have only just realised that
unserialise
is grammatically incorrect, yet we use this term everywhere in the code. Considering most references to it are disappearing, I can probably fix that.TODO