package sandbox import ( "sort" "strconv" ) // SchemaOption is one sandbox option as the UI needs it: identity, type, the // selectable values (with display labels), and the default value. type SchemaOption struct { Name string `json:"name"` // SandboxOptions enum member (stable key + config_values suffix) Display string `json:"display"` // human label Category string `json:"category"` // raw category key (General/Entities/...) Type string `json:"type"` // "float" | "int" | "bool" Values []string `json:"values"` // selectable values in index order (the code stores the index) Labels []string `json:"labels"` // optional UI labels parallel to Values (may be empty) Default string `json:"default"` // default value (one of Values) } // SchemaCategory groups options under a UI-friendly title. type SchemaCategory struct { Key string `json:"key"` // raw category key Title string `json:"title"` // UI title Icon string `json:"icon"` // emoji for the section Options []SchemaOption `json:"options"` // in registration order } // categoryMeta maps the decompile's raw category keys to UI titles + icons, // in display order. var categoryMeta = []struct{ Key, Title, Icon string }{ {"General", "Player", "🧍"}, {"Entities", "Entities & Zombies", "🧟"}, {"World", "World & Blood Moon", "🌍"}, {"Resources", "Loot & Resources", "πŸ’°"}, {"Crafting", "Crafting", "πŸ”¨"}, {"Traders", "Traders", "πŸͺ™"}, {"Tasks", "Quests & Tasks", "πŸ“‹"}, {"Misc", "Miscellaneous", "πŸŽ›οΈ"}, } // Schema returns the full 150-option sandbox schema grouped into the 8 UI // categories, in display order. The UI renders per-option controls from this and // sends back a nameβ†’value map for Encode. func Schema() []SchemaCategory { byCat := map[string][]SchemaOption{} for i := range options { o := &options[i] so := SchemaOption{ Name: o.Name, Display: o.Display, Category: o.Category, Default: o.valueAtIndex(defaultIdx[o.Name]), } switch o.Type { case optFloat: so.Type = "float" for _, f := range o.set.Floats { so.Values = append(so.Values, strconv.FormatFloat(f, 'f', -1, 64)) } case optInt: so.Type = "int" for _, n := range o.set.Ints { so.Values = append(so.Values, strconv.Itoa(n)) } case optBool: so.Type = "bool" for _, b := range o.set.Bools { so.Values = append(so.Values, strconv.FormatBool(b)) } } so.Labels = append(so.Labels, o.set.Display...) byCat[o.Category] = append(byCat[o.Category], so) } var out []SchemaCategory for _, cm := range categoryMeta { out = append(out, SchemaCategory{Key: cm.Key, Title: cm.Title, Icon: cm.Icon, Options: byCat[cm.Key]}) } // Any category not in categoryMeta (forward-compat) appended at the end. known := map[string]bool{} for _, cm := range categoryMeta { known[cm.Key] = true } var extra []string for k := range byCat { if !known[k] { extra = append(extra, k) } } sort.Strings(extra) for _, k := range extra { out = append(out, SchemaCategory{Key: k, Title: k, Icon: "βš™οΈ", Options: byCat[k]}) } return out }