data

package
v0.17.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 29, 2026 License: LGPL-3.0 Imports: 5 Imported by: 0

README

data

Config/manifest-loading plugin for Cardinal. Loads versioned backend data (definitions, manifests) into the world through a ConfigManifest component, so game code can read authored data via the ECS rather than bespoke loaders.

Regenerating the wire code

The wire.gen.go files are generated by world sdk generate. From the world-engine repo root:

world sdk generate ./pkg/plugin/data \
  --go-out ./pkg/plugin/data/gen

Requires Docker (the generator runs protoc/buf in a container). Rerun after changing any command/component/event struct in this plugin.

--proto-out ./pkg/plugin/data/proto is optional. The generator compiles the schema in a temp dir, so nothing in the build reads a persisted copy. Add the flag when you want to read the wire contract directly — what a field became, or whether a type fell back to opaque JSON.

Documentation

Overview

Package data is a Cardinal plugin that loads JSON configuration into a world-owned catalog at world init.

Each kind is a user-defined type implementing Definition (Name() + JSONFile()). The plugin fetches each file via a Source, unmarshals the bytes into the kind, and stores the result in an in-memory catalog keyed by Name(). Game systems read the data via:

mobs := data.Get[component.Mobs](plugin)

Loaded data does not live on Cardinal components — only the catalog does. The single snapshot-resident artifact is a ConfigManifest component recording, per file, the content hash of what's currently loaded. On a snapshot restore the reconcile system reads the snapshot's manifest and re-fetches each changed file at the snapshot's hash (from a versioned operator source) so an in-flight game resumes on the config it was running. Where the source can't pin history (the embed: a rebuilt binary served new bytes for an old hash) the system logs a warning and keeps the current config; where it should be able to but can't (operator says "I don't have that version") the system panics — fail loud, ops problem.

Usage:

dataPlugin := data.NewPlugin(data.Config{
    EmbeddedFS: myEmbeddedFS,
})
data.Register[component.Abilities](dataPlugin)
data.Register[component.Mobs](dataPlugin)
w.RegisterPlugin(dataPlugin)

// Anywhere downstream:
abilities := data.Get[component.Abilities](dataPlugin)

All Register[T] calls must happen before World.RegisterPlugin so the plugin can load every kind into the catalog before the tick loop begins. Get[T] is valid immediately after World.RegisterPlugin returns.

The plugin picks the underlying Source based on the runtime environment (embedded files for local dev; operator/forge integration is a future addition that flips automatically when OPERATOR_ADDR is set). Shards do not select a source themselves — they hand the plugin their embedded data and the plugin handles the rest.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Get

func Get[T Definition](p *Plugin) T

Get returns the loaded value for kind T from p. Pass the world's plugin into systems that read its catalog, then call Get after w.RegisterPlugin(dataPlugin) has run:

mobs := data.Get[component.Mobs](dataPlugin)

Panics if p is nil, p has not been registered with a world, or T was never registered with p.

func Register

func Register[T Definition](p *Plugin)

Register adds T to the plugin's load list. Each registered kind is fetched, unmarshaled, and (if applicable) run through Resolve and Validate at World.RegisterPlugin time.

Panics after World.RegisterPlugin or if another kind has already claimed the same Name() or JSONFile().

Types

type Config

type Config struct {
	// EmbeddedFS is the build-time embedded filesystem used as the data source in local dev and as
	// a fallback once operator integration ships. Required unless Source is set.
	EmbeddedFS embed.FS

	// Source overrides automatic source selection. Tests and custom integrations set this;
	// production callers leave it nil and let the plugin pick based on the environment.
	Source Source
}

Config holds plugin options.

type ConfigManifest

type ConfigManifest = component.ConfigManifest

ConfigManifest is the snapshot-resident component recording, per file, the content hash of the config the world is running. Internal to the plugin under normal use; re-exported for tests and any tooling that needs to inspect it.

type Definition

type Definition = system.Definition

Definition is the contract a config kind must satisfy to be loaded by the plugin.

type EmbedSource

type EmbedSource = system.EmbedSource

EmbedSource serves files baked into the binary via go:embed.

type Plugin

type Plugin struct {
	// contains filtered or unexported fields
}

Plugin owns one world's catalog, manifest, and configuration sources.

func NewPlugin

func NewPlugin(config Config) *Plugin

NewPlugin builds a data plugin instance. Call Register[T] for each kind before passing the plugin to World.RegisterPlugin.

If config.Source is nil (the production path), the plugin picks a Source from the current environment via system.PickSource using config.EmbeddedFS as the embedded fallback.

func (*Plugin) Register

func (p *Plugin) Register(w *cardinal.World)

Register implements cardinal.Plugin. Called synchronously by World.RegisterPlugin, before StartGame. Loads every registered kind and registers the reconcile system that keeps the catalog matched to the snapshot's ConfigManifest. Each world needs a separate Plugin instance.

func (*Plugin) Source

func (p *Plugin) Source() Source

Source returns the configured Source so games can write custom loaders for kinds that need per-kind conditional logic (e.g. environment-gated content) and still go through the same dev/prod data path.

type Resolver

type Resolver = system.Resolver

Resolver is an optional Definition interface for loading additional files from the same Source after the primary JSON has been unmarshaled.

type Singleton added in v0.13.0

type Singleton = system.Singleton

Singleton is an optional Definition marker: the kind's config is a single JSON object rather than a collection, so its source returns one object instead of an array.

type Source

type Source = system.Source

Source supplies the raw bytes for a named file along with its content hash (embed, local disk, operator, etc).

type Validator

type Validator = system.Validator

Validator is an optional Definition interface for enforcing post-load invariants. A non-nil error panics.

Directories

Path Synopsis
Package component holds the Cardinal components the data plugin owns.
Package component holds the Cardinal components the data plugin owns.
gen
Code generated by world sdk generate.
Code generated by world sdk generate.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL