Documentation
¶
Overview ¶
Package arkserde provides JSON serialization and deserialization for the Ark ECS.
Example ¶
package main
import (
"fmt"
"math/rand"
arkserde "github.com/mlange-42/ark-serde"
"github.com/mlange-42/ark/ecs"
)
const (
width = 40
height = 12
)
type Coords struct {
X int
Y int
}
func main() {
rng := rand.New(rand.NewSource(42))
// Create a world.
world := ecs.NewWorld(1024)
// Populate the world with entities, components and resources.
builder := ecs.NewMap1[Coords](world)
builder.NewBatchFn(60, func(entity ecs.Entity, coord *Coords) {
coord.X = rng.Intn(width)
coord.Y = rng.Intn(height)
})
// Print the original world
fmt.Println("====== Original world ========")
printWorld(world)
// Serialize the world.
jsonData, err := arkserde.Serialize(world)
if err != nil {
fmt.Printf("could not serialize: %s\n", err)
return
}
// Print the resulting JSON.
//fmt.Println(string(jsonData))
// Create a new, empty world.
newWorld := ecs.NewWorld(1024)
// Register required components and resources
_ = ecs.ComponentID[Coords](newWorld)
// Deserialize into the new world.
err = arkserde.Deserialize(jsonData, newWorld)
if err != nil {
fmt.Printf("could not deserialize: %s\n", err)
return
}
// Print the deserialized world
fmt.Println("====== Deserialized world ========")
printWorld(newWorld)
}
func printWorld(world *ecs.World) {
grid := make([][]rune, height)
for i := range grid {
grid[i] = make([]rune, width)
for j := range grid[i] {
grid[i][j] = '-'
}
}
filter := ecs.NewFilter1[Coords](world)
query := filter.Query()
for query.Next() {
coords := query.Get()
grid[coords.Y][coords.X] = 'O'
}
for i := range grid {
fmt.Println(string(grid[i]))
}
}
Output: ====== Original world ======== --------------------------------O-O---O- -----------------------O---------------- -O-------------O------OO--------------O- ----O------------------------OOO-------- O--------------OO-O--------------------- ------------O-----------O--------------- --O-------------O-------O---O------O---- O-O-----O----OOO-O--O--------------OO--- -----------O---OO----O--O------------O-- ------------O-----O--------------------- ---O---------------O------O--O---------- ------O-OO--O---------OO-OOO-----------O ====== Deserialized world ======== --------------------------------O-O---O- -----------------------O---------------- -O-------------O------OO--------------O- ----O------------------------OOO-------- O--------------OO-O--------------------- ------------O-----------O--------------- --O-------------O-------O---O------O---- O-O-----O----OOO-O--O--------------OO--- -----------O---OO----O--O------------O-- ------------O-----O--------------------- ---O---------------O------O--O---------- ------O-OO--O---------OO-OOO-----------O
Example (Options) ¶
world := ecs.NewWorld(1024)
builder := ecs.NewMap2[Position, Velocity](world)
builder.NewBatch(10, &Position{}, &Velocity{})
// Serialize the world, skipping Velocity and compressing with gzip.
jsonData, err := arkserde.Serialize(
world,
arkserde.Opts.SkipComponents(ecs.C[Velocity]()),
arkserde.Opts.Compress(arkserde.BestCompression),
)
if err != nil {
fmt.Printf("could not serialize: %s\n", err)
return
}
newWorld := ecs.NewWorld(1024)
// Register required components and resources
_ = ecs.ComponentID[Position](newWorld)
err = arkserde.Deserialize(jsonData, newWorld,
arkserde.Opts.Compress())
if err != nil {
fmt.Printf("could not deserialize: %s\n", err)
return
}
Index ¶
Examples ¶
Constants ¶
const ( BestSpeed = flate.BestSpeed BestCompression = flate.BestCompression DefaultCompression = flate.DefaultCompression )
GZip compression level, re-exported from the flate package
Variables ¶
var Opts = Options{}
Opts is a helper to create Option instances.
Functions ¶
func Deserialize ¶
Deserialize an Ark ecs.World from JSON.
The world must be prepared the following way:
- The world must not contain any alive or dead entities (i.e. a new or ecs.World.Reset world)
- All required component types must be registered using ecs.ComponentID
- All required resources must be added as dummies using ecs.AddResource
The options can be used to skip some or all components, entities entirely, and/or some or all resources. It only some components or resources are skipped, they still need to be registered to the world.
Query iteration order ¶
After deserialization, it is not guaranteed that entity iteration order in queries is the same as before. More precisely, it should at first be the same as before, but will likely deviate over time from what would happen when continuing the original, serialized run. Multiple worlds deserialized from the same source should, however, behave exactly the same.
func Serialize ¶
Serialize an Ark ecs.World to JSON.
Serializes the following:
- Entities and the entity pool
- All components of all entities
- All resources
All components and resources must be "JSON-able" with encoding/json.
The options can be used to skip some or all components, entities entirely, and/or some or all resources.
Types ¶
type Option ¶
type Option func(o *serdeOptions)
Option is an option. Modifies o. Create them using Opts.
type Options ¶
type Options struct{}
Options is a helper to create Option instances. Use it via the instance Opts.
func (Options) Compress ¶ added in v0.2.0
Compress data using gzip. For serialized data created with this option, the option must also be used for deserialization. The optional compression level argument has no effect when deserializing.
Ideally, save as <file>.json.gz instead of <file>.json.
func (Options) SkipAllComponents ¶
SkipAllComponents skips serialization or de-serialization of all components.
func (Options) SkipAllResources ¶
SkipAllResources skips serialization or de-serialization of all resources.
func (Options) SkipComponents ¶
SkipComponents skips serialization or de-serialization of certain components.
When deserializing, the skipped components must still be registered.
func (Options) SkipEntities ¶
SkipEntities skips serialization or de-serialization of all entities and components.