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:
- Native YAML campaign files (LoadCampaignFile, LoadCampaignFromReader)
- Foundry VTT world exports (ImportFoundryVTT)
- Roll20 campaign exports (ImportRoll20)
All store operations are safe for concurrent use.
Index ¶
- Variables
- func ImportCampaign(ctx context.Context, store Store, campaign *CampaignFile) (int, error)
- func ImportFoundryVTT(ctx context.Context, store Store, r io.Reader) (int, error)
- func ImportRoll20(ctx context.Context, store Store, r io.Reader) (int, error)
- func Validate(entity EntityDefinition) error
- type CampaignFile
- type CampaignMeta
- type EntityDefinition
- type EntityType
- type ListOptions
- type MemStore
- func (s *MemStore) Add(ctx context.Context, entity EntityDefinition) (EntityDefinition, error)
- func (s *MemStore) BulkImport(ctx context.Context, entities []EntityDefinition) (int, error)
- func (s *MemStore) Get(ctx context.Context, id string) (EntityDefinition, error)
- func (s *MemStore) List(ctx context.Context, opts ListOptions) ([]EntityDefinition, error)
- func (s *MemStore) Remove(ctx context.Context, id string) error
- func (s *MemStore) Update(ctx context.Context, entity EntityDefinition) error
- type RelationshipDef
- type Store
Constants ¶
This section is empty.
Variables ¶
var ErrDuplicateID = errors.New("entity with that ID already exists")
ErrDuplicateID is returned by Add when an entity with the same ID already exists.
var ErrNotFound = errors.New("entity not found")
ErrNotFound is returned by Get and Update when the requested entity does not exist.
Functions ¶
func ImportCampaign ¶
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 ¶
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 ¶
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:
- Name must be non-empty.
- Type must be a recognised EntityType.
- Every RelationshipDef must have a non-empty Type.
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 (*MemStore) Add ¶
func (s *MemStore) Add(ctx context.Context, entity EntityDefinition) (EntityDefinition, error)
Add implements [Store.Add].
func (*MemStore) BulkImport ¶
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) List ¶
func (s *MemStore) List(ctx context.Context, opts ListOptions) ([]EntityDefinition, error)
List implements [Store.List].
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.