entity

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Feb 28, 2026 License: GPL-3.0 Imports: 12 Imported by: 0

Documentation

Overview

Package entity provides pre-session entity management for Glyphoxa.

The DM uses this package to define and import game entities (NPCs, locations, items, factions, etc.) before a session starts. Entities defined here can be bulk-loaded into the knowledge graph (pkg/memory.KnowledgeGraph) at session start via the session initialisation layer.

Supported input formats:

All store operations are safe for concurrent use.

Index

Constants

This section is empty.

Variables

View Source
var ErrDuplicateID = errors.New("entity with that ID already exists")

ErrDuplicateID is returned by Add when an entity with the same ID already exists.

View Source
var ErrNotFound = errors.New("entity not found")

ErrNotFound is returned by Get and Update when the requested entity does not exist.

Functions

func ImportCampaign

func ImportCampaign(ctx context.Context, store Store, campaign *CampaignFile) (int, error)

ImportCampaign imports all entities from a parsed CampaignFile into store. Returns the number of entities successfully imported. An error from the store aborts the import and returns the count so far.

func ImportFoundryVTT

func ImportFoundryVTT(ctx context.Context, store Store, r io.Reader) (int, error)

ImportFoundryVTT imports entities from a Foundry VTT world export (JSON). It extracts actors (NPCs), items, and journal entries.

Unknown JSON fields are silently ignored. The import is best-effort: if an entity cannot be stored the error is returned together with the count of entities imported so far.

func ImportRoll20

func ImportRoll20(ctx context.Context, store Store, r io.Reader) (int, error)

ImportRoll20 imports entities from a Roll20 campaign export (JSON). It extracts characters (as NPCs) and handouts (as lore).

Unknown JSON fields are silently ignored. The import is best-effort: if an entity cannot be stored the error is returned together with the count of entities imported so far.

func Validate

func Validate(entity EntityDefinition) error

Validate checks an EntityDefinition for required fields and valid types.

Rules:

Types

type CampaignFile

type CampaignFile struct {
	Campaign CampaignMeta       `yaml:"campaign"`
	Entities []EntityDefinition `yaml:"entities"`
}

CampaignFile is the top-level structure of a Glyphoxa campaign YAML file.

Example:

campaign:
  name: "The Lost Mine of Phandelver"
  system: "dnd5e"
entities:
  - name: "Gundren Rockseeker"
    type: npc
    description: "A dwarf merchant hiring adventurers."

func LoadCampaignFile

func LoadCampaignFile(path string) (*CampaignFile, error)

LoadCampaignFile reads and parses a campaign YAML file from disk. Returns a descriptive error if the file cannot be opened or parsed.

func LoadCampaignFromReader

func LoadCampaignFromReader(r io.Reader) (*CampaignFile, error)

LoadCampaignFromReader parses campaign YAML from an io.Reader. The reader is consumed entirely; the caller is responsible for closing it.

type CampaignMeta

type CampaignMeta struct {
	// Name is the campaign's display name.
	Name string `yaml:"name"`

	// Description is a free-text summary of the campaign.
	Description string `yaml:"description"`

	// System is the game system identifier (e.g., "dnd5e", "pf2e", "custom").
	System string `yaml:"system"`
}

CampaignMeta holds top-level metadata for a campaign.

type EntityDefinition

type EntityDefinition struct {
	// ID is a unique identifier. Auto-generated if empty during import.
	ID string `yaml:"id" json:"id"`

	// Name is the entity's display name.
	Name string `yaml:"name" json:"name"`

	// Type classifies the entity (npc, location, item, faction, quest, etc.)
	Type EntityType `yaml:"type" json:"type"`

	// Description is a free-text description of the entity.
	Description string `yaml:"description" json:"description"`

	// Properties holds arbitrary key-value metadata.
	Properties map[string]string `yaml:"properties,omitempty" json:"properties,omitempty"`

	// Relationships defines connections to other entities.
	Relationships []RelationshipDef `yaml:"relationships,omitempty" json:"relationships,omitempty"`

	// Tags are searchable labels for categorization.
	Tags []string `yaml:"tags,omitempty" json:"tags,omitempty"`

	// Visibility controls which NPCs can "see" this entity.
	// An empty slice means visible to all.
	Visibility []string `yaml:"visibility,omitempty" json:"visibility,omitempty"`
}

EntityDefinition is the declarative format for defining game entities (NPCs, locations, items, factions) outside of the knowledge graph. It is used for pre-session setup via YAML config or VTT import.

type EntityType

type EntityType string

EntityType classifies an entity in the knowledge graph.

const (
	// EntityNPC represents a non-player character.
	EntityNPC EntityType = "npc"

	// EntityLocation represents a place in the game world.
	EntityLocation EntityType = "location"

	// EntityItem represents a physical object or artifact.
	EntityItem EntityType = "item"

	// EntityFaction represents an organisation, guild, or faction.
	EntityFaction EntityType = "faction"

	// EntityQuest represents a quest, mission, or story hook.
	EntityQuest EntityType = "quest"

	// EntityLore represents lore, historical records, or journal entries.
	EntityLore EntityType = "lore"
)

func (EntityType) IsValid

func (t EntityType) IsValid() bool

IsValid reports whether t is a recognised entity type.

type ListOptions

type ListOptions struct {
	// Type restricts results to entities of this type.
	// An empty value matches all types.
	Type EntityType

	// Tags restricts results to entities that carry all of the specified tags.
	// An empty slice matches all entities regardless of their tags.
	Tags []string
}

ListOptions narrows the result set of [Store.List]. All non-zero fields are applied as AND conditions.

type MemStore

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

MemStore is a thread-safe, in-memory implementation of Store. It is suitable for single-session use and testing. The zero value is ready to use.

func NewMemStore

func NewMemStore() *MemStore

NewMemStore returns an initialised MemStore.

func (*MemStore) Add

Add implements [Store.Add].

func (*MemStore) BulkImport

func (s *MemStore) BulkImport(ctx context.Context, entities []EntityDefinition) (int, error)

BulkImport implements [Store.BulkImport]. The import is best-effort: entities are added one at a time and the count of successfully added entities is returned along with the first error encountered.

func (*MemStore) Get

func (s *MemStore) Get(ctx context.Context, id string) (EntityDefinition, error)

Get implements [Store.Get].

func (*MemStore) List

func (s *MemStore) List(ctx context.Context, opts ListOptions) ([]EntityDefinition, error)

List implements [Store.List].

func (*MemStore) Remove

func (s *MemStore) Remove(ctx context.Context, id string) error

Remove implements [Store.Remove].

func (*MemStore) Update

func (s *MemStore) Update(ctx context.Context, entity EntityDefinition) error

Update implements [Store.Update].

type RelationshipDef

type RelationshipDef struct {
	// TargetID is the ID of the related entity.
	TargetID string `yaml:"target_id" json:"target_id"`

	// TargetName is an alternative to TargetID — resolved by name during import.
	// If both TargetID and TargetName are set, TargetID takes precedence.
	TargetName string `yaml:"target_name,omitempty" json:"target_name,omitempty"`

	// Type describes the relationship (e.g., "lives_in", "owns", "allied_with").
	Type string `yaml:"type" json:"type"`

	// Bidirectional indicates the relationship applies in both directions.
	Bidirectional bool `yaml:"bidirectional,omitempty" json:"bidirectional,omitempty"`
}

RelationshipDef declares a connection from an entity to another entity.

type Store

type Store interface {
	// Add creates a new entity. Returns the entity with a generated ID if
	// the provided entity's ID is empty.
	// Returns [ErrDuplicateID] if an entity with the same non-empty ID exists.
	Add(ctx context.Context, entity EntityDefinition) (EntityDefinition, error)

	// Get retrieves an entity by ID.
	// Returns [ErrNotFound] when no entity with that ID exists.
	Get(ctx context.Context, id string) (EntityDefinition, error)

	// List returns all entities, optionally filtered by type and/or tags.
	// An empty [ListOptions] returns all entities.
	// Results order is not guaranteed.
	List(ctx context.Context, opts ListOptions) ([]EntityDefinition, error)

	// Update replaces an existing entity definition.
	// The entity's ID must be non-empty.
	// Returns [ErrNotFound] when no entity with that ID exists.
	Update(ctx context.Context, entity EntityDefinition) error

	// Remove deletes an entity by ID.
	// Returns [ErrNotFound] when no entity with that ID exists.
	Remove(ctx context.Context, id string) error

	// BulkImport adds multiple entities atomically.
	// Each entity without an ID gets one auto-generated.
	// Returns the number of entities successfully imported and any error
	// that caused the import to abort early.
	BulkImport(ctx context.Context, entities []EntityDefinition) (int, error)
}

Store manages entity definitions for pre-session setup.

It is NOT the same as pkg/memory.KnowledgeGraph — it is a simpler CRUD layer for managing entity definitions before they are loaded into the knowledge graph at session start.

All implementations must be safe for concurrent use.

Jump to

Keyboard shortcuts

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