Knowledge packs

KnowledgePack and its entry structs, the bundled default pack, JSON parsing, overlay merging and error handling.

A knowledge pack is JSON mapping "language-independent key → reading text and school attributes". The core only judges facts; reading texts and the school-specific star attributes live here. For the concept, the format and how to write an overlay, see the knowledge pack guide; the full field reference is knowledge/SCHEMA.md in the repository.

pack, err := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
intro := pack.StarIntro(iztro.StarZiweiMaj)

Every lookup takes a string; pass the StarXxx / PatternXxx / PalaceXxx / MutagenXxx constants. The default pack and the merge both live in the embedded wasm core; this package only encodes and decodes JSON.

Types

KnowledgePack

All fields are exported and tagged, so encoding/json works on them directly.

FieldTypeMeaning
SchemaintFormat version, currently 1
IDstringPack identifier; "iztro-docs" for the default pack
VersionstringPack version; for the default pack, retrieval date + short source commit
LanguagestringLanguage code of the texts, e.g. LanguageZhCN
ExtendsstringThe pack this overlay overlays; empty for a standalone pack
SourceKnowledgeSourceOrigin and licence
Starsmap[string]StarEntryStar entries, keyed by star key
Patternsmap[string]PatternEntryPattern entries, keyed by pattern key
Palacesmap[string]TextEntryPalace entries, keyed by palace key
Mutagensmap[string]TextEntryTransformation entries, keyed by transformation key
Conceptsmap[string]ConceptEntryGlossary entries, keyed by slug

KnowledgeSource

Name, URL, Commit, License, Author, RetrievedAt, Adapted (adaptation note), all string, empty when absent.

StarEntry

FieldTypeMeaning
NamestringDisplay name in this pack's language
Categorystring"major" / "minor" / "adjective" / "dec" / "flow" (a flowing star, a cross-reference entry pointing at its natal minor-star counterpart)
GroupstringGrouping: the adjective star's category, the decorative star's group
AttributesStarAttributesSchool attributes
IntrostringReading (Markdown)
Combinationsmap[string]stringReading for sharing a palace with another major star, keyed by that star

StarAttributes

YinYang (yin / yang), FiveElements (wood / fire / earth / metal / water), Stem (jia…gui), FiveElementsNote, Dipper, Chemistry, Career, Duty, Aliases ([]string), ElementColor, EnergyColor.

FiveElements and YinYang are what the pack's source says, and may differ from the core star data, which is value-for-value identical to iztro's. The reason is in the guide.

PatternEntry

Name, Quotes ([]string), Conditions, Intro.

TextEntry / ConceptEntry

TextEntry (palaces, transformations) has Name and Intro; ConceptEntry (glossary) has Title and Intro.

Absent means the zero value

The Go side does not use pointers to separate "not written" from "written as empty". An absent field is the empty string or nil, so compare against the empty string to tell whether an entry carries text.


BuiltinKnowledgePack

Purpose Get the bundled default knowledge pack.

Signature

func BuiltinKnowledgePack(language Language) (*KnowledgePack, error)
func BuiltinKnowledgePackContext(ctx context.Context, language Language) (*KnowledgePack, error)

Parameters

ParameterTypeMeaning
ctxcontext.ContextContext variant only; cancels waiting for a wasm instance
languageLanguageText language

Returns (*KnowledgePack, error). Languages without a bundled pack return an error, matchable with errors.Is(err, iztro.ErrInvalidArgument). Only LanguageZhCN has one today.

Example

pack, err := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
if err != nil {
    log.Fatal(err)
}

fmt.Println(pack.ID, pack.Version, pack.Language, pack.Source.License)
fmt.Println(len(pack.Stars), len(pack.Patterns), len(pack.Palaces), len(pack.Mutagens), len(pack.Concepts))

_, err = iztro.BuiltinKnowledgePack(iztro.LanguageEnUS)
fmt.Println(err, errors.Is(err, iztro.ErrInvalidArgument))

Output

iztro-docs 2026-08-19+ec2d58b zh-CN MIT
162 64 12 4 49
iztro: no builtin knowledge pack for language 'en-US' true

ParseKnowledgePack

Purpose Parse a pack from JSON text.

Signature

func ParseKnowledgePack(data []byte) (*KnowledgePack, error)

Returns (*KnowledgePack, error). Invalid JSON, a missing or zero schema, and a schema newer than this library supports all return an ErrInvalidArgument-class error — the same semantics as the Rust core's parser (KnowledgePack::from_json).

Serializing is plain encoding/json:

data, err := json.Marshal(pack)

Example

overlay, err := iztro.ParseKnowledgePack([]byte(`{"schema":1,"id":"my-school","version":"1",
    "language":"zh-CN","extends":"iztro-docs",
    "stars":{"ziweiMaj":{"intro":"我的紫微","attributes":{"aliases":["帝座"]}}},
    "patterns":{"zi_fu_tong_gong":{"intro":"我的紫府同宫"}}}`))
if err != nil {
    log.Fatal(err)
}
fmt.Println(overlay.ID, overlay.Extends)

_, err = iztro.ParseKnowledgePack([]byte("nope"))
fmt.Println(err)
_, err = iztro.ParseKnowledgePack([]byte(`{"schema":99}`))
fmt.Println(err)

Output

my-school iztro-docs
iztro: invalid knowledge pack: invalid character 'o' in literal null (expecting 'u')
iztro: knowledge pack schema 99 is newer than supported 1

Merged

Purpose Layer overlay packs onto this one and return a new pack.

Signature

func (p *KnowledgePack) Merged(overlays ...*KnowledgePack) (*KnowledgePack, error)
func (p *KnowledgePack) MergedContext(ctx context.Context, overlays ...*KnowledgePack) (*KnowledgePack, error)

Parameters

ParameterTypeMeaning
ctxcontext.ContextContext variant only; cancels waiting for a wasm instance
overlays...*KnowledgePackOverlays applied in argument order; later ones win

Returns A new *KnowledgePack; neither this pack nor the overlays change. A nil receiver, a nil overlay, or a pack whose schema is invalid (hand-built structs are validated by the core here) all return an ErrInvalidArgument-class error.

The rules are in the guide: section by section, key by key, an overlay's non-empty fields replace the same-keyed entry's fields, Attributes and Combinations merge field by field, array fields are replaced wholesale. The merge itself runs in the wasm core, so all three languages agree.

Example

pack, _ := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
merged, err := pack.Merged(overlay)
if err != nil {
    log.Fatal(err)
}

zi := merged.Star(iztro.StarZiweiMaj)
fmt.Println(merged.ID, zi.Name, zi.Attributes.Aliases, zi.Attributes.Chemistry, zi.Intro)
fmt.Println(merged.PatternIntro(iztro.PatternZiFuTongGong),
    merged.Pattern(iztro.PatternZiFuTongGong).Quotes)
fmt.Println(string([]rune(pack.StarIntro(iztro.StarZiweiMaj))[:5]))

_, err = pack.Merged(nil)
fmt.Println(err)

Output

my-school 紫微 [帝座] 尊贵 我的紫微
我的紫府同宫 [紫府同宫终身福厚。]
紫微星号称
iztro: mergeKnowledgePacks: nil overlay pack

Star / Pattern / Palace / Mutagen / Concept

Purpose Look up an entry by language-independent key.

Signature

func (p *KnowledgePack) Star(starKey string) *StarEntry
func (p *KnowledgePack) Pattern(patternKey string) *PatternEntry
func (p *KnowledgePack) Palace(palaceKey string) *TextEntry
func (p *KnowledgePack) Mutagen(mutagenKey string) *TextEntry
func (p *KnowledgePack) Concept(slug string) *ConceptEntry

Returns nil when the pack has no such entry, and nil for a nil receiver rather than a panic. The pointer is to a copy of the entry, so writing through it does not change the pack.

Example

pack, _ := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
zi := pack.Star(iztro.StarZiweiMaj)

fmt.Println(zi.Name, zi.Category, zi.Attributes.Dipper, zi.Attributes.Aliases)
fmt.Println(zi.Combinations[iztro.StarTianfuMaj] != "")
fmt.Println(pack.Palace(iztro.PalaceSoul).Name, pack.Mutagen(iztro.MutagenLu).Name)
fmt.Println(pack.Concept("tong-gong").Title)
fmt.Println(pack.Star("nope") == nil)

Output

紫微 major 中天星系 [帝王星 老板星 俸禄星]
true
命宫 化禄
遇、加、逢、同宫、同度
true

StarIntro / PatternIntro

Purpose Get the reading text directly.

Signature

func (p *KnowledgePack) StarIntro(starKey string) string
func (p *KnowledgePack) PatternIntro(patternKey string) string

Returns The empty string both when the entry is missing and when it exists without a reading.

Example List the natal patterns with their quotations:

pack, _ := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
chart, _ := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageZhCN, nil)
hits, _ := chart.Patterns(nil)

for _, hit := range hits {
    fmt.Println(hit.Name, "|", pack.Pattern(hit.Key).Quotes[0])
    fmt.Println(string([]rune(pack.PatternIntro(hit.Key))[:10]))
}

Output

府相朝垣 | 府相朝垣命必荣
“食禄千锺”的断语使

TextOptions

Purpose Output options for the ToTextWith family (ToTextWith / PalaceToTextWith / SurroundedPalacesToTextWith / PatternsToTextWith, and the same-named methods on Horoscope): the source of readings and the pattern criteria. The zero value emits the chart facts only under the default criteria, byte-identical to the method without With.

Definition

type TextOptions struct {
    Knowledge     Knowledge
    PatternConfig *PatternConfig
}

Fields

FieldTypeDescription
KnowledgeKnowledgeSource of readings; the zero value adds none. When given, each palace's star readings follow that palace's fact lines, the pattern readings follow the pattern list, and the natal text closes with ## Mutagen Notes — see Text with readings
PatternConfig*PatternConfigPattern criteria, the same argument as Patterns(config); acts on both the text's pattern section and the pattern readings. nil takes the core default

Example (on a zh-CN chart, since the bundled pack is Chinese)

text, _ := chart.ToTextWith(iztro.TextOptions{Knowledge: iztro.BuiltinKnowledge()})
same, _ := chart.ToTextWith(iztro.TextOptions{})
plain, _ := chart.ToText()

fmt.Println(same == plain, utf8.RuneCountInString(plain), utf8.RuneCountInString(text))

cfg := iztro.PatternConfig{BrightnessSource: iztro.BrightnessSourcePositional}
byPosition, _ := chart.ToTextWith(iztro.TextOptions{Knowledge: iztro.BuiltinKnowledge(), PatternConfig: &cfg})

Output

true 3389 20767

Knowledge / BuiltinKnowledge / KnowledgeFrom

Purpose The value of the Knowledge field of TextOptions: the source of readings for the ToTextWith family.

Signature

type Knowledge struct { /* unexported */ }

func BuiltinKnowledge() Knowledge
func KnowledgeFrom(pack *KnowledgePack) Knowledge

Values

ValueMeaning
BuiltinKnowledge()The bundled default pack for the chart language; when that language has no bundled pack (only zh-CN has one) the method returns ErrInvalidArgument rather than silently falling back
KnowledgeFrom(pack)The given pack (custom, or the result of Merged); a nil pack equals the zero value
Knowledge{} (zero value)No readings; the output of TextOptions{} is byte-identical to the method without With

Example

pack, _ := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
data, _ := os.ReadFile("my-school.json")
overlay, _ := iztro.ParseKnowledgePack(data)
mine, _ := pack.Merged(overlay)

text, _ := chart.ToTextWith(iztro.TextOptions{Knowledge: iztro.KnowledgeFrom(mine)})

ForAstrolabe / ForHoroscope

Purpose Pick by chart: cut a sub-pack holding only the entries relevant to this chart.

Signature

func (p *KnowledgePack) ForAstrolabe(chart *Astrolabe, config *PatternConfig) (*KnowledgePack, error)
func (p *KnowledgePack) ForAstrolabeContext(ctx context.Context, chart *Astrolabe, config *PatternConfig) (*KnowledgePack, error)
func (p *KnowledgePack) ForHoroscope(horoscope *Horoscope, config *PatternConfig) (*KnowledgePack, error)
func (p *KnowledgePack) ForHoroscopeContext(ctx context.Context, horoscope *Horoscope, config *PatternConfig) (*KnowledgePack, error)

Parameters

ParameterTypeDescription
ctxcontext.ContextContext variants only; cancels waiting for a wasm instance
chart*AstrolabeThe chart to select by; a re-anchored chart selects by its re-anchored layout
horoscope*HoroscopeA horoscope from chart.Horoscope(...); the natal part is selected along with it
config*PatternConfigPattern criteria, the same argument as Patterns(config); nil for the default

Returns (*KnowledgePack, error). A standard pack with the metadata carried over: Stars holds the stars on the chart (major, minor, adjective and the four groups of twelve gods; the 14 major stars' Combinations keep only partners that actually share the palace), Patterns the hits under the config criteria, Mutagens all four entries, Palaces and Concepts empty. ForHoroscope adds each scope's flowing stars and the patterns hit from the decadal down to the hourly perspective. Pair the sub-pack with Patterns(config) / PatternsToTextWith under the same criteria: different criteria hit different sets, and the readings would then miss or over-include entries. Selection reads the pack as it currently is (the whole pack is sent to the core), so entries edited in place make it into the sub-pack. A nil receiver or argument, or a horoscope not obtained from Astrolabe.Horoscope, returns ErrInvalidArgument. The selection rule is on Picking by chart.

Example

pack, _ := iztro.BuiltinKnowledgePack(iztro.LanguageZhCN)
chart, _ := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageZhCN, nil)

sub, _ := pack.ForAstrolabe(chart, nil)
fmt.Println(len(sub.Stars), len(sub.Patterns), len(sub.Mutagens), len(sub.Palaces))
for k := range sub.Stars[iztro.StarWuquMaj].Combinations {
    fmt.Println(k)
}

h, _ := chart.Horoscope("2025-1-1", 0)
sub, _ = pack.ForHoroscope(h, nil)
fmt.Println(len(sub.Stars), len(sub.Patterns))

Output

108 1 4 0
tianxiangMaj
158 16

Wuqu shares its palace with Tianxiang on this chart, so Wuqu's Combinations in the sub-pack keeps only the Tianxiang entry.


Knowledge.ForAstrolabe / Knowledge.ForHoroscope

Purpose Pick by chart through a Knowledge sentinel. With BuiltinKnowledge() the core reads the bundled pack directly, so there is no need to fetch the whole pack with BuiltinKnowledgePack and send it back; with KnowledgeFrom(pack) it equals the pack.ForAstrolabe family.

Signature

func (k Knowledge) ForAstrolabe(chart *Astrolabe, config *PatternConfig) (*KnowledgePack, error)
func (k Knowledge) ForAstrolabeContext(ctx context.Context, chart *Astrolabe, config *PatternConfig) (*KnowledgePack, error)
func (k Knowledge) ForHoroscope(horoscope *Horoscope, config *PatternConfig) (*KnowledgePack, error)
func (k Knowledge) ForHoroscopeContext(ctx context.Context, horoscope *Horoscope, config *PatternConfig) (*KnowledgePack, error)

Parameters The same as the (*KnowledgePack).ForAstrolabe family.

Returns As above. The zero value Knowledge{} has no source of material and returns ErrInvalidArgument; BuiltinKnowledge() also returns ErrInvalidArgument for a chart language without a bundled pack.

Example

chart, _ := iztro.BySolar("2000-8-16", 2, iztro.GenderFemale, true, iztro.LanguageZhCN, nil)

sub, _ := iztro.BuiltinKnowledge().ForAstrolabe(chart, nil)
fmt.Println(len(sub.Stars), len(sub.Patterns))

Output

108 1

On this page