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"
"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 {
skills := make([]horse.Skill, 0, len(horse.AllSkills))
for _, v := range horse.AllSkills {
skills := make([]horse.Skill, 0, len(global.AllSkills))
for _, v := range global.AllSkills {
skills = append(skills, v)
}
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) {
t.Parallel()
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,
// but that may be awkward for inherited skills.
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-extras
@@ -1,4 +1,4 @@
module horse/skill-group
module horse/global/skill-group
// 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
pub import horse/skill-group
+1 -1
View File
@@ -1,5 +1,5 @@
{{ define "go-character" -}}
package horse
package {{ $.Region }}
// Automatically generated with horsegen; DO NOT EDIT
+2 -2
View File
@@ -1,7 +1,7 @@
{{ 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-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.
// 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) {
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 {
Region string
Characters []NamedID[Character]
Pairs []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
Count int
MaxID int
}{c, pairs, trios, pm, tm, len(c), maxid}
}{region, c, pairs, trios, pm, tm, len(c), maxid}
var err error
if kk != nil {
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
}
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))
u := make(map[int]int, len(groups))
for _, t := range skills {
@@ -88,10 +89,11 @@ func ExecSkill(t *template.Template, kk, g io.Writer, groups []NamedID[SkillGrou
}
}
data := struct {
Region string
Groups []NamedID[SkillGroup]
Skills []Skill
Related map[int][]Skill
}{groups, skills, m}
}{region, groups, skills, m}
var err error
if kk != nil {
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
}
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 {
Region string
Groups []NamedID[SkillGroup]
Skills []Skill
}{g, s}
}{region, g, s}
return t.ExecuteTemplate(w, "koka-skill-group", &data)
}
+22 -12
View File
@@ -15,12 +15,13 @@ import (
func main() {
var (
mdb string
kkOut, goOut string
mdb 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(&kkOut, "kk", `.\horse`, "existing `dir`ectory for output Koka files")
flag.StringVar(&goOut, "go", `.`, "existing `dir`ectory for output Go files")
flag.StringVar(&out, "o", `.`, "root `dir`ectory for output files")
flag.StringVar(&region, "region", "global", "region the database is for (global, jp)")
flag.Parse()
pctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
@@ -85,35 +86,44 @@ func main() {
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.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 {
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 {
return err
}
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 {
sf, err := os.Create(filepath.Join(kkOut, "skill.kk"))
sf, err := os.Create(filepath.Join(out, "horse", region, "skill.kk"))
if err != nil {
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")
return ExecSkill(t, sf, gf, sg, skills)
return ExecSkill(t, region, sf, gf, sg, skills)
})
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 {
return err
}
slog.Info("write skill groups")
return ExecSkillGroupKK(t, sf, sg, skills)
return ExecSkillGroupKK(t, region, sf, sg, skills)
})
if err := eg.Wait(); err != nil {
slog.Error("generate", slog.Any("err", err))
+5 -1
View File
@@ -1,9 +1,13 @@
{{- define "go-skill-data" -}}
package horse
package {{ $.Region }}
// 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
*/ -}}
const (
{{- range $s := $.Skills }}
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" -}}
module horse/skill-group
module horse/{{ $.Region }}/skill-group
// Automatically generated with horsegen; DO NOT EDIT
@@ -48,7 +48,9 @@ pub fun skill-group/(==)(a: skill-group, b: skill-group): bool
{{- end -}}
{{- define "koka-skill" -}}
module horse/skill
module horse/{{ $.Region }}/skill
// Automatically generated with horsegen; DO NOT EDIT
import std/num/decimal
pub import horse/skill-group
-995
View File
File diff suppressed because one or more lines are too long