Serialization - Quillraven/Fleks GitHub Wiki

Serialization and Deserialization in Fleks can be achieved via the snapshot functionality of the world. A Snapshot is a container for the components and tags of an entity.

data class Snapshot(
    val components: List<Component<*>>,
    val tags: List<UniqueId<*>>,
)

Kotlinx Serialization

Fleks uses Kotlinx Serialization which is the standard for Kotlin multiplatform applications. Fleks also uses the stable Json library.

Serializing an entity is straight forward:

val entity = Entity(id = 0, version = 0u)

// encode an entity
val jsonStr = Json.encodeToString(entity0) // {"id":0,"version":0}

// decode an entity
val decodedEntity: Entity = Json.decodeFromString(jsonStr)

Serializing a snapshot requires some minor setup work. First, you need to annotate your serializable components/tags with @Serializable. Second, you need to register your components/tags as a subclass of Component/UniqueId. Finally, you need to configure Json to allow structured map keys since an entity is a combination of its id and version. Here is an example:

@Serializable
data object VisibleTag : EntityTag()

@Serializable
data class Speed(val max:Int) : Component<Speed> {
    override fun type() = Speed

    companion object : ComponentType<Speed>()
}

@Serializable
data class Graphic(val texture:String) : Component<Graphic> {
    override fun type() = Graphic

    companion object : ComponentType<Graphic>()
}

fun main() {
    val world = configureWorld { }
    world.entity {
        it += Speed(3)
        it += Graphic("mySprite.png")
        it += VisibleTag
    }

    // configure Json's serializersModule and allow structured map keys
    val json = Json {
        serializersModule = SerializersModule {
            // register components
            polymorphic(Component::class) {
                subclass(Speed::class, Speed.serializer())
                subclass(Graphic::class, Graphic.serializer())
            }

            // register tags
            polymorphic(UniqueId::class) {
                subclass(VisibleTag::class, VisibleTag.serializer())
            }
        }

        allowStructuredMapKeys = true // to support entity id + version as a key in a map data structure
    }

    val snapshot: Map<Entity, Snapshot> = world.snapshot()
    val snapshotJson = json.encodeToString(snapshot) // [{"id":0,"version":0},{"components":[{"type":"com.github.quillraven.fleks.Graphic","texture":"mySprite.png"},{"type":"com.github.quillraven.fleks.Speed","max":3}],"tags":[{"type":"com.github.quillraven.fleks.VisibleTag"}]}]

    // clear world and load encoded snapshot from before
    world.removeAll(clearRecycled = true)
    world.loadSnapshot(json.decodeFromString(snapshotJson))
}
⚠️ **GitHub.com Fallback** ⚠️