horsegen: generate data per region

This commit is contained in:
2026-01-15 13:43:54 -05:00
parent 5b5e008b5e
commit d6fb4b6caf
16 changed files with 1287 additions and 2261 deletions
-263
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
View File
+4 -6
View File
@@ -7,12 +7,13 @@ import (
"sync" "sync"
"testing" "testing"
"git.sunturtle.xyz/zephyr/horse" horse "git.sunturtle.xyz/zephyr/horse/go"
"git.sunturtle.xyz/zephyr/horse/go/global"
) )
var SortedSkills = sync.OnceValue(func() []horse.Skill { var SortedSkills = sync.OnceValue(func() []horse.Skill {
skills := make([]horse.Skill, 0, len(horse.AllSkills)) skills := make([]horse.Skill, 0, len(global.AllSkills))
for _, v := range horse.AllSkills { for _, v := range global.AllSkills {
skills = append(skills, v) skills = append(skills, v)
} }
slices.SortFunc(skills, func(a, b horse.Skill) int { return cmp.Compare(a.ID, b.ID) }) slices.SortFunc(skills, func(a, b horse.Skill) int { return cmp.Compare(a.ID, b.ID) })
@@ -22,9 +23,6 @@ var SortedSkills = sync.OnceValue(func() []horse.Skill {
func TestSkillStrings(t *testing.T) { func TestSkillStrings(t *testing.T) {
t.Parallel() t.Parallel()
for _, s := range SortedSkills() { for _, s := range SortedSkills() {
if n := s.ID.String(); strings.HasPrefix(n, "SkillID(") {
t.Error(n)
}
// We could check that s.ID.String() matches s.Name, // We could check that s.ID.String() matches s.Name,
// but that may be awkward for inherited skills. // but that may be awkward for inherited skills.
for _, a := range s.Activations { for _, a := range s.Activations {
@@ -1,6 +1,6 @@
module horse/character module horse/global/character
// Automatically generated with the horsegen tool; DO NOT EDIT // Automatically generated with horsegen; DO NOT EDIT
import std/core/vector import std/core/vector
import std/core-extras import std/core-extras
@@ -1,4 +1,4 @@
module horse/skill-group module horse/global/skill-group
// Automatically generated with horsegen; DO NOT EDIT // Automatically generated with horsegen; DO NOT EDIT
+3 -1
View File
@@ -1,4 +1,6 @@
module horse/skill module horse/global/skill
// Automatically generated with horsegen; DO NOT EDIT
import std/num/decimal import std/num/decimal
pub import horse/skill-group pub import horse/skill-group
+1 -1
View File
@@ -1,5 +1,5 @@
{{ define "go-character" -}} {{ define "go-character" -}}
package horse package {{ $.Region }}
// Automatically generated with horsegen; DO NOT EDIT // Automatically generated with horsegen; DO NOT EDIT
+2 -2
View File
@@ -1,7 +1,7 @@
{{ define "koka-character" -}} {{ define "koka-character" -}}
module horse/character module horse/{{ $.Region }}/character
// Automatically generated with the horsegen tool; DO NOT EDIT // Automatically generated with horsegen; DO NOT EDIT
import std/core/vector import std/core/vector
import std/core-extras import std/core-extras
+9 -6
View File
@@ -26,7 +26,7 @@ func LoadTemplates() (*template.Template, error) {
// ExecCharacter renders the Koka character module to kk and the Go character file to g. // ExecCharacter renders the Koka character module to kk and the Go character file to g.
// If either is nil, it is skipped. // If either is nil, it is skipped.
func ExecCharacter(t *template.Template, kk, g io.Writer, c []NamedID[Character], pairs, trios []AffinityRelation) error { func ExecCharacter(t *template.Template, region string, kk, g io.Writer, c []NamedID[Character], pairs, trios []AffinityRelation) error {
if len(pairs) != len(c)*len(c) { if len(pairs) != len(c)*len(c) {
return fmt.Errorf("there are %d pairs but there must be %d for %d characters", len(pairs), len(c)*len(c), len(c)) return fmt.Errorf("there are %d pairs but there must be %d for %d characters", len(pairs), len(c)*len(c), len(c))
} }
@@ -53,6 +53,7 @@ func ExecCharacter(t *template.Template, kk, g io.Writer, c []NamedID[Character]
} }
data := struct { data := struct {
Region string
Characters []NamedID[Character] Characters []NamedID[Character]
Pairs []AffinityRelation Pairs []AffinityRelation
Trios []AffinityRelation Trios []AffinityRelation
@@ -60,7 +61,7 @@ func ExecCharacter(t *template.Template, kk, g io.Writer, c []NamedID[Character]
TrioMaps map[int]map[int]map[int]int TrioMaps map[int]map[int]map[int]int
Count int Count int
MaxID int MaxID int
}{c, pairs, trios, pm, tm, len(c), maxid} }{region, c, pairs, trios, pm, tm, len(c), maxid}
var err error var err error
if kk != nil { if kk != nil {
err = errors.Join(t.ExecuteTemplate(kk, "koka-character", &data)) err = errors.Join(t.ExecuteTemplate(kk, "koka-character", &data))
@@ -71,7 +72,7 @@ func ExecCharacter(t *template.Template, kk, g io.Writer, c []NamedID[Character]
return err return err
} }
func ExecSkill(t *template.Template, kk, g io.Writer, groups []NamedID[SkillGroup], skills []Skill) error { func ExecSkill(t *template.Template, region string, kk, g io.Writer, groups []NamedID[SkillGroup], skills []Skill) error {
m := make(map[int][]Skill, len(groups)) m := make(map[int][]Skill, len(groups))
u := make(map[int]int, len(groups)) u := make(map[int]int, len(groups))
for _, t := range skills { for _, t := range skills {
@@ -88,10 +89,11 @@ func ExecSkill(t *template.Template, kk, g io.Writer, groups []NamedID[SkillGrou
} }
} }
data := struct { data := struct {
Region string
Groups []NamedID[SkillGroup] Groups []NamedID[SkillGroup]
Skills []Skill Skills []Skill
Related map[int][]Skill Related map[int][]Skill
}{groups, skills, m} }{region, groups, skills, m}
var err error var err error
if kk != nil { if kk != nil {
err = errors.Join(t.ExecuteTemplate(kk, "koka-skill", &data)) err = errors.Join(t.ExecuteTemplate(kk, "koka-skill", &data))
@@ -102,11 +104,12 @@ func ExecSkill(t *template.Template, kk, g io.Writer, groups []NamedID[SkillGrou
return err return err
} }
func ExecSkillGroupKK(t *template.Template, w io.Writer, g []NamedID[SkillGroup], s []Skill) error { func ExecSkillGroupKK(t *template.Template, region string, w io.Writer, g []NamedID[SkillGroup], s []Skill) error {
data := struct { data := struct {
Region string
Groups []NamedID[SkillGroup] Groups []NamedID[SkillGroup]
Skills []Skill Skills []Skill
}{g, s} }{region, g, s}
return t.ExecuteTemplate(w, "koka-skill-group", &data) return t.ExecuteTemplate(w, "koka-skill-group", &data)
} }
+22 -12
View File
@@ -15,12 +15,13 @@ import (
func main() { func main() {
var ( var (
mdb string mdb string
kkOut, goOut string out string
region string
) )
flag.StringVar(&mdb, "mdb", os.ExpandEnv(`$USERPROFILE\AppData\LocalLow\Cygames\Umamusume\master\master.mdb`), "`path` to Umamusume master.mdb") flag.StringVar(&mdb, "mdb", os.ExpandEnv(`$USERPROFILE\AppData\LocalLow\Cygames\Umamusume\master\master.mdb`), "`path` to Umamusume master.mdb")
flag.StringVar(&kkOut, "kk", `.\horse`, "existing `dir`ectory for output Koka files") flag.StringVar(&out, "o", `.`, "root `dir`ectory for output files")
flag.StringVar(&goOut, "go", `.`, "existing `dir`ectory for output Go files") flag.StringVar(&region, "region", "global", "region the database is for (global, jp)")
flag.Parse() flag.Parse()
pctx, stop := signal.NotifyContext(context.Background(), os.Interrupt) pctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
@@ -85,35 +86,44 @@ func main() {
os.Exit(1) os.Exit(1)
} }
if err := os.MkdirAll(filepath.Join(out, "horse", region), 0775); err != nil {
slog.Error("create koka output dir", slog.Any("err", err))
os.Exit(1)
}
if err := os.MkdirAll(filepath.Join(out, "go", region), 0775); err != nil {
slog.Error("create go output dir", slog.Any("err", err))
os.Exit(1)
}
eg, ctx = errgroup.WithContext(pctx) eg, ctx = errgroup.WithContext(pctx)
eg.Go(func() error { eg.Go(func() error {
cf, err := os.Create(filepath.Join(kkOut, "character.kk")) cf, err := os.Create(filepath.Join(out, "horse", region, "character.kk"))
if err != nil { if err != nil {
return err return err
} }
gf, err := os.Create(filepath.Join(goOut, "character.go")) gf, err := os.Create(filepath.Join(out, "go", region, "character.go"))
if err != nil { if err != nil {
return err return err
} }
slog.Info("write characters") slog.Info("write characters")
return ExecCharacter(t, cf, gf, charas, pairs, trios) return ExecCharacter(t, region, cf, gf, charas, pairs, trios)
}) })
eg.Go(func() error { eg.Go(func() error {
sf, err := os.Create(filepath.Join(kkOut, "skill.kk")) sf, err := os.Create(filepath.Join(out, "horse", region, "skill.kk"))
if err != nil { if err != nil {
return err return err
} }
gf, err := os.Create(filepath.Join(goOut, "skill_data.go")) gf, err := os.Create(filepath.Join(out, "go", region, "skill.go"))
slog.Info("write skills") slog.Info("write skills")
return ExecSkill(t, sf, gf, sg, skills) return ExecSkill(t, region, sf, gf, sg, skills)
}) })
eg.Go(func() error { eg.Go(func() error {
sf, err := os.Create(filepath.Join(kkOut, "skill-group.kk")) sf, err := os.Create(filepath.Join(out, "horse", region, "skill-group.kk"))
if err != nil { if err != nil {
return err return err
} }
slog.Info("write skill groups") slog.Info("write skill groups")
return ExecSkillGroupKK(t, sf, sg, skills) return ExecSkillGroupKK(t, region, sf, sg, skills)
}) })
if err := eg.Wait(); err != nil { if err := eg.Wait(); err != nil {
slog.Error("generate", slog.Any("err", err)) slog.Error("generate", slog.Any("err", err))
+5 -1
View File
@@ -1,9 +1,13 @@
{{- define "go-skill-data" -}} {{- define "go-skill-data" -}}
package horse package {{ $.Region }}
// Automatically generated with horsegen; DO NOT EDIT // Automatically generated with horsegen; DO NOT EDIT
import . "git.sunturtle.xyz/zephyr/horse/go"
{{/*
//go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type SkillID -trimprefix Skill -linecomment //go:generate go run golang.org/x/tools/cmd/stringer@v0.41.0 -type SkillID -trimprefix Skill -linecomment
*/ -}}
const ( const (
{{- range $s := $.Skills }} {{- range $s := $.Skills }}
Skill{{ goenum $s.Name }}{{ if ne $s.InheritID 0 }}Inherit{{ end }} SkillID = {{ $s.ID }} // {{ $s.Name }} Skill{{ goenum $s.Name }}{{ if ne $s.InheritID 0 }}Inherit{{ end }} SkillID = {{ $s.ID }} // {{ $s.Name }}
+4 -2
View File
@@ -1,5 +1,5 @@
{{- define "koka-skill-group" -}} {{- define "koka-skill-group" -}}
module horse/skill-group module horse/{{ $.Region }}/skill-group
// Automatically generated with horsegen; DO NOT EDIT // Automatically generated with horsegen; DO NOT EDIT
@@ -48,7 +48,9 @@ pub fun skill-group/(==)(a: skill-group, b: skill-group): bool
{{- end -}} {{- end -}}
{{- define "koka-skill" -}} {{- define "koka-skill" -}}
module horse/skill module horse/{{ $.Region }}/skill
// Automatically generated with horsegen; DO NOT EDIT
import std/num/decimal import std/num/decimal
pub import horse/skill-group pub import horse/skill-group
-995
View File
File diff suppressed because one or more lines are too long