diff --git a/desktop/src/EggPicker.tsx b/desktop/src/EggPicker.tsx index bf56062..05839d2 100644 --- a/desktop/src/EggPicker.tsx +++ b/desktop/src/EggPicker.tsx @@ -39,6 +39,11 @@ interface TemplateMeta { /// `id` (e.g. "mars" in "mars.drakon") when rendering the "by /// " chip in the picker row. author?: AuthorBlock; + /// Display ordering hint for the egg-picker UI. Lower = shown earlier. + /// Builtin difficulty ladder: unicorn=1, sun=2, kingkong=3. + /// Templates without an explicit value (user-imported community ones) + /// sort AFTER explicit-order templates, by name alphabetically. + display_order?: number; } /// Disambiguator label for the egg-picker row. Two templates with the @@ -134,11 +139,19 @@ export function EggPicker({ onConfirm, onCancel, onImport }: Props) { const loadTemplates = useCallback(async (): Promise => { try { const rows = await invoke("template_list"); - const order = (s: string) => + const sourceRank = (s: string) => s === "builtin" ? 0 : s === "community" ? 1 : 2; + // Templates without `display_order` sort AFTER explicit ones — + // builtin difficulty ladder (unicorn=1, sun=2, kingkong=3) wins, + // community/custom imports fall back to name alphabetic at the + // tail. Using +Infinity keeps the comparator stable and avoids + // mixing "unordered" templates into the middle of the ladder. + const orderRank = (m: TemplateMeta) => + m.display_order ?? Number.POSITIVE_INFINITY; rows.sort( (a, b) => - order(a.source) - order(b.source) || + sourceRank(a.source) - sourceRank(b.source) || + orderRank(a.template.meta) - orderRank(b.template.meta) || a.template.meta.name.localeCompare(b.template.meta.name), ); setTemplates(rows); diff --git a/src/template/registry.rs b/src/template/registry.rs index 8ae0a2e..2319030 100644 --- a/src/template/registry.rs +++ b/src/template/registry.rs @@ -545,6 +545,7 @@ mod tests { // picker / pet creation would silently break. assert!(BUILTIN.get_dir("sun").is_some()); assert!(BUILTIN.get_dir("unicorn").is_some()); + assert!(BUILTIN.get_dir("kingkong").is_some()); } fn stage_at(idx: u32, trigger: Trigger) -> Stage { @@ -618,6 +619,7 @@ mod tests { license: None, description: None, source_url: None, + display_order: None, }, species: TemplateSpecies { name: "Test".into(), diff --git a/src/template/types.rs b/src/template/types.rs index 2b3f233..a4402e0 100644 --- a/src/template/types.rs +++ b/src/template/types.rs @@ -72,6 +72,12 @@ pub struct TemplateMeta { pub description: Option, #[serde(default)] pub source_url: Option, + /// Display ordering hint for the egg-picker UI. Lower = shown + /// earlier. Templates without an explicit value (e.g. user-imported + /// community ones) sort after explicit-order templates, alphabetically. + /// Builtin difficulty ladder: unicorn=1, sun=2, kingkong=3. + #[serde(default)] + pub display_order: Option, } /// Author shape on disk. Templates in the wild use either: diff --git a/src/xp/engine.rs b/src/xp/engine.rs index 53e43a6..31250c9 100644 --- a/src/xp/engine.rs +++ b/src/xp/engine.rs @@ -1005,6 +1005,29 @@ mod tests { assert_eq!(pet.name, "Sparkle"); } + #[tokio::test] + async fn pick_template_kingkong_loads_and_creates_pet() { + // KingKong is the 3rd builtin (hard mode, ~2.5× Sun). Same + // load-canary as the unicorn test: silently broken levels / + // stages / rules in this template would drop it from the + // picker without anything red-flagging. + let _g = env_test_lock(); + let dir = tempfile::tempdir().expect("tempdir"); + std::env::set_var("PETPET_HOME", dir.path()); + let db = crate::db::DbHandle::open(&dir.path().join("test.db")) + .await + .expect("open db"); + let engine = XPEngine::open(db.clone()).await.expect("open engine"); + + let pet = engine + .pick_template("kingkong", Some("Konga".into())) + .await + .expect("kingkong should load and snapshot"); + + assert_eq!(pet.template_id, "kingkong"); + assert_eq!(pet.name, "Konga"); + } + #[tokio::test] async fn pick_template_unknown_errors() { let _g = env_test_lock(); diff --git a/templates/builtin/kingkong/levels.json b/templates/builtin/kingkong/levels.json new file mode 100644 index 0000000..c3fb359 --- /dev/null +++ b/templates/builtin/kingkong/levels.json @@ -0,0 +1,405 @@ +{ + "max_level": 99, + "entries": [ + { + "level": 0, + "xp_required": 0 + }, + { + "level": 1, + "xp_required": 200 + }, + { + "level": 2, + "xp_required": 391 + }, + { + "level": 3, + "xp_required": 588 + }, + { + "level": 4, + "xp_required": 791 + }, + { + "level": 5, + "xp_required": 1000 + }, + { + "level": 6, + "xp_required": 1215 + }, + { + "level": 7, + "xp_required": 1436 + }, + { + "level": 8, + "xp_required": 1663 + }, + { + "level": 9, + "xp_required": 1896 + }, + { + "level": 10, + "xp_required": 2135 + }, + { + "level": 11, + "xp_required": 2380 + }, + { + "level": 12, + "xp_required": 2631 + }, + { + "level": 13, + "xp_required": 2888 + }, + { + "level": 14, + "xp_required": 3151 + }, + { + "level": 15, + "xp_required": 3420 + }, + { + "level": 16, + "xp_required": 3695 + }, + { + "level": 17, + "xp_required": 3976 + }, + { + "level": 18, + "xp_required": 4263 + }, + { + "level": 19, + "xp_required": 4556 + }, + { + "level": 20, + "xp_required": 4855 + }, + { + "level": 21, + "xp_required": 5160 + }, + { + "level": 22, + "xp_required": 5471 + }, + { + "level": 23, + "xp_required": 5788 + }, + { + "level": 24, + "xp_required": 6111 + }, + { + "level": 25, + "xp_required": 6440 + }, + { + "level": 26, + "xp_required": 6775 + }, + { + "level": 27, + "xp_required": 7116 + }, + { + "level": 28, + "xp_required": 7463 + }, + { + "level": 29, + "xp_required": 7816 + }, + { + "level": 30, + "xp_required": 8175 + }, + { + "level": 31, + "xp_required": 8540 + }, + { + "level": 32, + "xp_required": 8911 + }, + { + "level": 33, + "xp_required": 9288 + }, + { + "level": 34, + "xp_required": 9671 + }, + { + "level": 35, + "xp_required": 10060 + }, + { + "level": 36, + "xp_required": 10455 + }, + { + "level": 37, + "xp_required": 10856 + }, + { + "level": 38, + "xp_required": 11263 + }, + { + "level": 39, + "xp_required": 11676 + }, + { + "level": 40, + "xp_required": 12095 + }, + { + "level": 41, + "xp_required": 12520 + }, + { + "level": 42, + "xp_required": 12951 + }, + { + "level": 43, + "xp_required": 13388 + }, + { + "level": 44, + "xp_required": 13831 + }, + { + "level": 45, + "xp_required": 14280 + }, + { + "level": 46, + "xp_required": 14735 + }, + { + "level": 47, + "xp_required": 15196 + }, + { + "level": 48, + "xp_required": 15663 + }, + { + "level": 49, + "xp_required": 16136 + }, + { + "level": 50, + "xp_required": 16615 + }, + { + "level": 51, + "xp_required": 17100 + }, + { + "level": 52, + "xp_required": 17591 + }, + { + "level": 53, + "xp_required": 18088 + }, + { + "level": 54, + "xp_required": 18591 + }, + { + "level": 55, + "xp_required": 19100 + }, + { + "level": 56, + "xp_required": 19615 + }, + { + "level": 57, + "xp_required": 20136 + }, + { + "level": 58, + "xp_required": 20663 + }, + { + "level": 59, + "xp_required": 21196 + }, + { + "level": 60, + "xp_required": 21735 + }, + { + "level": 61, + "xp_required": 22280 + }, + { + "level": 62, + "xp_required": 22831 + }, + { + "level": 63, + "xp_required": 23388 + }, + { + "level": 64, + "xp_required": 23951 + }, + { + "level": 65, + "xp_required": 24520 + }, + { + "level": 66, + "xp_required": 25095 + }, + { + "level": 67, + "xp_required": 25676 + }, + { + "level": 68, + "xp_required": 26263 + }, + { + "level": 69, + "xp_required": 26856 + }, + { + "level": 70, + "xp_required": 27455 + }, + { + "level": 71, + "xp_required": 28060 + }, + { + "level": 72, + "xp_required": 28671 + }, + { + "level": 73, + "xp_required": 29288 + }, + { + "level": 74, + "xp_required": 29911 + }, + { + "level": 75, + "xp_required": 30540 + }, + { + "level": 76, + "xp_required": 31175 + }, + { + "level": 77, + "xp_required": 31816 + }, + { + "level": 78, + "xp_required": 32463 + }, + { + "level": 79, + "xp_required": 33116 + }, + { + "level": 80, + "xp_required": 33775 + }, + { + "level": 81, + "xp_required": 34440 + }, + { + "level": 82, + "xp_required": 35111 + }, + { + "level": 83, + "xp_required": 35788 + }, + { + "level": 84, + "xp_required": 36471 + }, + { + "level": 85, + "xp_required": 37160 + }, + { + "level": 86, + "xp_required": 37855 + }, + { + "level": 87, + "xp_required": 38556 + }, + { + "level": 88, + "xp_required": 39263 + }, + { + "level": 89, + "xp_required": 39976 + }, + { + "level": 90, + "xp_required": 40695 + }, + { + "level": 91, + "xp_required": 41420 + }, + { + "level": 92, + "xp_required": 42151 + }, + { + "level": 93, + "xp_required": 42888 + }, + { + "level": 94, + "xp_required": 43631 + }, + { + "level": 95, + "xp_required": 44380 + }, + { + "level": 96, + "xp_required": 45135 + }, + { + "level": 97, + "xp_required": 45896 + }, + { + "level": 98, + "xp_required": 46663 + }, + { + "level": 99, + "xp_required": 47436 + } + ] +} \ No newline at end of file diff --git a/templates/builtin/kingkong/rules.json b/templates/builtin/kingkong/rules.json new file mode 100644 index 0000000..c53ae58 --- /dev/null +++ b/templates/builtin/kingkong/rules.json @@ -0,0 +1,44 @@ +[ + { "id": "usage-default", "source_type": "usage", "match": {}, "priority": 10, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 }, + "description": "KingKong: usage-floor mult (rule_mult clamps ≥ 0.5)" }, + { "id": "usage-tier-mini", "source_type": "usage", "match": {"tier":"mini"}, "priority": 50, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-tier-frontier", "source_type": "usage", "match": {"tier":"frontier"}, "priority": 50, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-fam-gpt-o", "source_type": "usage", "match": {"family":"gpt-o"}, "priority": 70, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.4,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-claude-opus-4-7", "source_type": "usage", "match": {"model":"claude-opus-4-7"}, "priority": 100, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-gpt-5-5", "source_type": "usage", "match": {"model":"gpt-5-5"}, "priority": 100, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-claude-opus-4-6", "source_type": "usage", "match": {"model":"claude-opus-4-6"}, "priority": 100, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-claude-sonnet-4-7", "source_type": "usage", "match": {"model":"claude-sonnet-4-7"}, "priority": 100, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-gpt-5", "source_type": "usage", "match": {"model":"gpt-5"}, "priority": 100, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-gemini-2-5-pro", "source_type": "usage", "match": {"model":"gemini-2-5-pro"}, "priority": 100, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + { "id": "usage-claude-sonnet-4-6", "source_type": "usage", "match": {"model":"claude-sonnet-4-6"}, "priority": 100, + "config": { "weight": {"input":0.1,"output":1.5,"reasoning":1.0,"cache_creation":0.25,"cache_read":0.01}, + "divisor": 8000, "multiplier": 0.5, "min_xp": 1, "max_xp": 250 } }, + + { "id": "act-user-prompt", "source_type": "activity", "match": {"kind":"user_prompt_submit"}, "config": {"xp":0}, "priority": 50, "description": "KingKong: no XP for chatter — only milestones + tokens grow this beast" }, + { "id": "act-assistant-stop", "source_type": "activity", "match": {"kind":"assistant_stop"}, "config": {"xp":0}, "priority": 50 }, + { "id": "act-tool-success", "source_type": "activity", "match": {"kind":"tool_use_end","success":true}, "config": {"xp":0}, "priority": 60 }, + { "id": "act-task-completed", "source_type": "activity", "match": {"kind":"task_completed"}, "config": {"xp":3}, "priority": 50, "description": "KingKong: halved task milestone (vs Sun=7)" }, + { "id": "act-subagent-stop", "source_type": "activity", "match": {"kind":"subagent_stop"}, "config": {"xp":2}, "priority": 50, "description": "KingKong: halved subagent reward (vs Sun=5)" }, + { "id": "act-session-start", "source_type": "activity", "match": {"kind":"session_start"}, "config": {"xp":1}, "priority": 50, "description": "KingKong: halved session greeting (vs Sun=2)" }, + { "id": "act-pre-compact", "source_type": "activity", "match": {"kind":"pre_compact"}, "config": {"xp":0}, "priority": 50 } +] diff --git a/templates/builtin/kingkong/stages/stage_0/sprite.png b/templates/builtin/kingkong/stages/stage_0/sprite.png new file mode 100644 index 0000000..71955af Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_0/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_0/stage.json b/templates/builtin/kingkong/stages/stage_0/stage.json new file mode 100644 index 0000000..4805a85 --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_0/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_0", + "name": "Stage 0", + "flavor": "Obsidian egg — sparks of starlight in the shell.", + "trigger": { + "metric": "level", + "value": 0 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_1/sprite.png b/templates/builtin/kingkong/stages/stage_1/sprite.png new file mode 100644 index 0000000..7736505 Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_1/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_1/stage.json b/templates/builtin/kingkong/stages/stage_1/stage.json new file mode 100644 index 0000000..ea65b7f --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_1/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_1", + "name": "Stage 1", + "flavor": "Cracked. A young primate stirs.", + "trigger": { + "metric": "level", + "value": 1 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_2/sprite.png b/templates/builtin/kingkong/stages/stage_2/sprite.png new file mode 100644 index 0000000..e4792fe Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_2/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_2/stage.json b/templates/builtin/kingkong/stages/stage_2/stage.json new file mode 100644 index 0000000..113165b --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_2/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_2", + "name": "Stage 2", + "flavor": "Wide-eyed cub, testing its grip.", + "trigger": { + "metric": "level", + "value": 7 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_3/sprite.png b/templates/builtin/kingkong/stages/stage_3/sprite.png new file mode 100644 index 0000000..3f9cee7 Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_3/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_3/stage.json b/templates/builtin/kingkong/stages/stage_3/stage.json new file mode 100644 index 0000000..b8a3fa5 --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_3/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_3", + "name": "Stage 3", + "flavor": "Lean and watchful, learning the climb.", + "trigger": { + "metric": "level", + "value": 15 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_4/sprite.png b/templates/builtin/kingkong/stages/stage_4/sprite.png new file mode 100644 index 0000000..8115b7f Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_4/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_4/stage.json b/templates/builtin/kingkong/stages/stage_4/stage.json new file mode 100644 index 0000000..3fced5c --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_4/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_4", + "name": "Stage 4", + "flavor": "Young silverback, finding its roar.", + "trigger": { + "metric": "level", + "value": 25 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_5/sprite.png b/templates/builtin/kingkong/stages/stage_5/sprite.png new file mode 100644 index 0000000..c9b5b40 Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_5/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_5/stage.json b/templates/builtin/kingkong/stages/stage_5/stage.json new file mode 100644 index 0000000..25f417d --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_5/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_5", + "name": "Stage 5", + "flavor": "Armoured stride — bone and muscle hardened.", + "trigger": { + "metric": "level", + "value": 40 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_6/sprite.png b/templates/builtin/kingkong/stages/stage_6/sprite.png new file mode 100644 index 0000000..1faf533 Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_6/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_6/stage.json b/templates/builtin/kingkong/stages/stage_6/stage.json new file mode 100644 index 0000000..90f2b76 --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_6/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_6", + "name": "Stage 6", + "flavor": "First circuits embedded — chrome under fur.", + "trigger": { + "metric": "level", + "value": 55 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_7/sprite.png b/templates/builtin/kingkong/stages/stage_7/sprite.png new file mode 100644 index 0000000..ab2a612 Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_7/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_7/stage.json b/templates/builtin/kingkong/stages/stage_7/stage.json new file mode 100644 index 0000000..837e507 --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_7/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_7", + "name": "Stage 7", + "flavor": "Cybernetic warrior, gauntlet glowing.", + "trigger": { + "metric": "level", + "value": 72 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_8/sprite.png b/templates/builtin/kingkong/stages/stage_8/sprite.png new file mode 100644 index 0000000..c1b3884 Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_8/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_8/stage.json b/templates/builtin/kingkong/stages/stage_8/stage.json new file mode 100644 index 0000000..444030c --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_8/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_8", + "name": "Stage 8", + "flavor": "Half titan, half god. Engines online.", + "trigger": { + "metric": "level", + "value": 86 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/stages/stage_9/sprite.png b/templates/builtin/kingkong/stages/stage_9/sprite.png new file mode 100644 index 0000000..8c312bc Binary files /dev/null and b/templates/builtin/kingkong/stages/stage_9/sprite.png differ diff --git a/templates/builtin/kingkong/stages/stage_9/stage.json b/templates/builtin/kingkong/stages/stage_9/stage.json new file mode 100644 index 0000000..42031e3 --- /dev/null +++ b/templates/builtin/kingkong/stages/stage_9/stage.json @@ -0,0 +1,10 @@ +{ + "id": "stage_9", + "name": "Stage 9", + "flavor": "Cyborg legend. Lightning in the knuckles.", + "trigger": { + "metric": "level", + "value": 99 + }, + "attributes": {} +} diff --git a/templates/builtin/kingkong/template.json b/templates/builtin/kingkong/template.json new file mode 100644 index 0000000..ce37629 --- /dev/null +++ b/templates/builtin/kingkong/template.json @@ -0,0 +1,33 @@ +{ + "$schema": "petpet-template/v1", + "meta": { + "id": "kingkong", + "name": "KingKong", + "version": "1.0.0", + "author": "petpet-builtin", + "license": "MIT", + "description": "A titan beast forged from stone and circuitry. Hard difficulty — only deliberate progress (tasks completed, subagents dispatched) and AI token usage feed it. Idle chat won't budge the meter. Roughly 2.5× the time investment of Sun.", + "display_order": 3 + }, + "species": { + "name": "KingKong", + "description": "King Kong — born from a starlit black-stone egg, evolving from young primate to armoured titan to cyber-god. Demands real work, not chitchat.", + "default_pet_name": "KingKong", + "flavor": "Forged in obsidian, ascending in titanium." + }, + "labels": [ + { "text": "Hard", "color": "#1a1a1a", "fg": "#d4af37" }, + { "text": "Challenge", "color": "#d4af37", "fg": "#1a1a1a" } + ], + "theme": { + "primary": "#3a4a6a", + "secondary": "#d4af37", + "accent": "#1a1a1a", + "palette": ["#1a1a1a", "#3a4a6a", "#5d7099", "#8a9bb8", "#d4af37", "#f0e0a0"] + }, + "assets": { + "sheet": "sheet.png", + "frames": "sheet.json", + "thumb": "thumb.png" + } +} diff --git a/templates/builtin/kingkong/thumb.png b/templates/builtin/kingkong/thumb.png new file mode 100644 index 0000000..71955af Binary files /dev/null and b/templates/builtin/kingkong/thumb.png differ diff --git a/templates/builtin/sun/template.json b/templates/builtin/sun/template.json index b0927bc..1b7a703 100644 --- a/templates/builtin/sun/template.json +++ b/templates/builtin/sun/template.json @@ -6,7 +6,8 @@ "version": "1.0.0", "author": "petpet-builtin", "license": "MIT", - "description": "A monkey-king companion born from the magical stone of Huaguo Mountain. Medium difficulty — engaged users reach the final Buddha form in a few months of regular use." + "description": "A monkey-king companion born from the magical stone of Huaguo Mountain. Medium difficulty — engaged users reach the final Buddha form in a few months of regular use.", + "display_order": 2 }, "species": { "name": "Sun", diff --git a/templates/builtin/unicorn/template.json b/templates/builtin/unicorn/template.json index 2d494ff..a78f50e 100644 --- a/templates/builtin/unicorn/template.json +++ b/templates/builtin/unicorn/template.json @@ -6,7 +6,8 @@ "version": "1.0.0", "author": "petpet-builtin", "license": "MIT", - "description": "A sparkly pink unicorn companion — Easy difficulty. Hatches from a crystal egg and grows into a winged alicorn on a rainbow cloud, then ascends in gold." + "description": "A sparkly pink unicorn companion — Easy difficulty. Hatches from a crystal egg and grows into a winged alicorn on a rainbow cloud, then ascends in gold.", + "display_order": 1 }, "species": { "name": "Unicorn",