feat(spark_pet): major overhaul — traits, animations, riding, fire, coloured hatching
All checks were successful
Deploy Addons / deploy (push) Successful in 24s

- Movement: slower follow (speed 0.3, stop_dist 5), near-zero teleport chance
- Scales: baby 0.65, juvenile 0.9, adult 1.3 (up from 0.4/0.7/1.0)
- Personality traits (0–4): set by feeding specific foods while sneaking;
  affects stroll range, follow distance, look-at-player frequency
- Passtime animations driven by pure Molang lifecycle math (no timer components):
  groom, sniff, stretch, happy_bounce cycling ~every 3 min per dragon
- Rideable adults: minecraft:rideable + input_ground_controlled, seat at [0,0.9,-0.3]
- Fire breathing: autonomous vs monsters (radius 16) + player-triggered (sneak + fire_charge)
- New hatching system: 6 nest block variants (oak/spruce/jungle/crimson/warped/obsidian),
  craft nest + dragon_egg → coloured egg item; place egg, bonemeal + blaze powder → hatch;
  dragon colour matches nest type via 6 separate egg entity types + born_color events
- 18 new PNG textures: 6 dragon colours, 6 nest blocks, 6 egg items (HSV hue rotation)
- Render controller updated to use texture array indexed by silverlabs:dragon_color property

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-25 02:12:44 +00:00
parent c32dbf42c4
commit 4bd9efc081
57 changed files with 2162 additions and 320 deletions

View File

@@ -1,6 +1,7 @@
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.spark_dragon.beacon": {
"initial_state": "inactive",
"states": {
@@ -19,22 +20,30 @@
}
}
},
"controller.animation.spark_dragon": {
"initial_state": "idle",
"states": {
"idle": {
"animations": ["idle"],
"transitions": [
{ "fire_breathing": "query.property('silverlabs:firing')" },
{ "flying": "!query.is_on_ground && query.property('silverlabs:growth_stage') == 2" },
{ "walking": "query.modified_move_speed > 0.1" },
{ "sleeping": "query.is_sitting && (query.day_light_level < 4)" },
{ "sitting": "query.is_sitting" }
{ "sitting": "query.is_sitting" },
{ "grooming": "query.is_on_ground && query.modified_move_speed <= 0.05 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 1" },
{ "sniffing": "query.is_on_ground && query.modified_move_speed <= 0.15 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 2" },
{ "happy_bounce": "query.is_on_ground && query.modified_move_speed <= 0.05 && query.property('silverlabs:mood') == 2 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 3" },
{ "stretching": "query.is_on_ground && query.modified_move_speed <= 0.05 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 4" }
]
},
"walking": {
"animations": ["walk"],
"transitions": [
{ "fire_breathing": "query.property('silverlabs:firing')" },
{ "flying": "!query.is_on_ground && query.property('silverlabs:growth_stage') == 2" },
{ "sniffing": "query.is_on_ground && query.modified_move_speed <= 0.15 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 2" },
{ "idle": "query.modified_move_speed <= 0.1" },
{ "sitting": "query.is_sitting" }
]
@@ -56,12 +65,51 @@
"flying": {
"animations": ["fly"],
"transitions": [
{ "fire_breathing": "query.property('silverlabs:firing')" },
{ "idle": "query.is_on_ground && query.modified_move_speed <= 0.1" },
{ "walking": "query.is_on_ground && query.modified_move_speed > 0.1" }
]
},
"grooming": {
"animations": ["groom"],
"transitions": [
{ "fire_breathing": "query.property('silverlabs:firing')" },
{ "idle": "query.modified_move_speed > 0.05 || query.is_sitting || math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) != 1" }
]
},
"sniffing": {
"animations": ["sniff"],
"transitions": [
{ "fire_breathing": "query.property('silverlabs:firing')" },
{ "idle": "query.modified_move_speed > 0.15 || query.is_sitting || math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) != 2" },
{ "walking": "query.modified_move_speed > 0.1 && math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) == 2" }
]
},
"happy_bounce": {
"animations": ["happy_bounce"],
"transitions": [
{ "fire_breathing": "query.property('silverlabs:firing')" },
{ "idle": "query.modified_move_speed > 0.05 || query.is_sitting || query.property('silverlabs:mood') != 2 || math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) != 3" }
]
},
"stretching": {
"animations": ["stretch"],
"transitions": [
{ "fire_breathing": "query.property('silverlabs:firing')" },
{ "idle": "query.modified_move_speed > 0.05 || query.is_sitting || math.mod(math.floor((query.life_time + math.mod(math.abs(math.floor(query.position(0) + query.position(2))), 5) * 36.0) / 36.0), 5) != 4" }
]
},
"fire_breathing": {
"animations": ["fire_breath"],
"transitions": [
{ "flying": "!query.property('silverlabs:firing') && !query.is_on_ground && query.property('silverlabs:growth_stage') == 2" },
{ "idle": "!query.property('silverlabs:firing') && query.is_on_ground" },
{ "walking": "!query.property('silverlabs:firing') && query.modified_move_speed > 0.1" }
]
}
}
},
"controller.animation.spark_dragon.mood": {
"initial_state": "content",
"states": {
@@ -91,5 +139,6 @@
}
}
}
}
}

View File

@@ -32,9 +32,17 @@
"1.0": [0, 5, 0],
"2.0": [0, -5, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"1.0": [3, 2, 0],
"2.0": [0, 0, 0]
}
}
}
},
"animation.spark_dragon.walk": {
"loop": true,
"animation_length": 0.8,
@@ -77,20 +85,16 @@
},
"wing_left": {
"rotation": {
"0.0": [0, 0, -10],
"0.2": [0, 0, -30],
"0.4": [0, 0, -10],
"0.6": [0, 0, -30],
"0.8": [0, 0, -10]
"0.0": [0, 0, -8],
"0.4": [0, 0, -18],
"0.8": [0, 0, -8]
}
},
"wing_right": {
"rotation": {
"0.0": [0, 0, 10],
"0.2": [0, 0, 30],
"0.4": [0, 0, 10],
"0.6": [0, 0, 30],
"0.8": [0, 0, 10]
"0.0": [0, 0, 8],
"0.4": [0, 0, 18],
"0.8": [0, 0, 8]
}
},
"tail": {
@@ -103,14 +107,15 @@
"body": {
"position": {
"0.0": [0, 0, 0],
"0.2": [0, 0.5, 0],
"0.2": [0, 0.4, 0],
"0.4": [0, 0, 0],
"0.6": [0, 0.5, 0],
"0.6": [0, 0.4, 0],
"0.8": [0, 0, 0]
}
}
}
},
"animation.spark_dragon.sit": {
"loop": true,
"animation_length": 2.0,
@@ -147,6 +152,7 @@
}
}
},
"animation.spark_dragon.sleep": {
"loop": true,
"animation_length": 4.0,
@@ -188,6 +194,7 @@
}
}
},
"animation.spark_dragon.fly": {
"loop": true,
"animation_length": 0.6,
@@ -241,6 +248,315 @@
"rotation": [10, 0, 0]
}
}
},
"animation.spark_dragon.groom": {
"loop": true,
"animation_length": 3.0,
"bones": {
"body": {
"position": [0, -1.5, 0]
},
"head": {
"rotation": {
"0.0": [0, 20, 5],
"0.5": [5, 30, 8],
"1.0": [0, 22, 5],
"1.5": [8, 28, 5],
"2.0": [0, 20, 5],
"2.5": [5, 32, 8],
"3.0": [0, 20, 5]
}
},
"leg_front_left": {
"rotation": {
"0.0": [-60, 0, 0],
"0.4": [-30, 15, 20],
"0.8": [-50, 5, 10],
"1.2": [-30, 15, 20],
"1.6": [-50, 5, 10],
"2.0": [-30, 15, 20],
"2.4": [-50, 5, 10],
"3.0": [-60, 0, 0]
}
},
"leg_front_right": {
"rotation": [-60, 0, 0]
},
"leg_back_left": {
"rotation": [-90, 20, 0]
},
"leg_back_right": {
"rotation": [-90, -20, 0]
},
"wing_left": {
"rotation": [0, 0, 5],
"position": [0, 0, 1]
},
"wing_right": {
"rotation": [0, 0, -5],
"position": [0, 0, 1]
},
"tail": {
"rotation": {
"0.0": [5, -35, 0],
"1.5": [5, -20, 0],
"3.0": [5, -35, 0]
}
}
}
},
"animation.spark_dragon.sniff": {
"loop": true,
"animation_length": 2.4,
"bones": {
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.4": [30, 5, 0],
"0.8": [25, -5, 0],
"1.2": [32, 3, 0],
"1.6": [20, 0, 0],
"2.0": [28, -4, 0],
"2.4": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"0.4": [0, -0.8, 1],
"1.2": [0, -0.6, 1],
"2.4": [0, 0, 0]
}
},
"body": {
"rotation": {
"0.0": [0, 0, 0],
"0.6": [5, 0, 0],
"1.8": [5, 0, 0],
"2.4": [0, 0, 0]
}
},
"tail": {
"rotation": {
"0.0": [0, -8, 0],
"0.6": [-10, 0, 0],
"1.2": [-15, 5, 0],
"1.8": [-10, -3, 0],
"2.4": [0, -8, 0]
}
},
"wing_left": {
"rotation": {
"0.0": [0, 0, -5],
"1.2": [0, 0, -8],
"2.4": [0, 0, -5]
}
},
"wing_right": {
"rotation": {
"0.0": [0, 0, 5],
"1.2": [0, 0, 8],
"2.4": [0, 0, 5]
}
}
}
},
"animation.spark_dragon.stretch": {
"loop": false,
"animation_length": 3.0,
"bones": {
"body": {
"position": {
"0.0": [0, 0, 0],
"0.4": [0, -0.5, 0],
"1.2": [0, -0.8, 0],
"2.0": [0, -0.3, 0],
"3.0": [0, 0, 0]
},
"rotation": {
"0.0": [0, 0, 0],
"0.6": [8, 0, 0],
"1.5": [5, 0, 0],
"3.0": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.6": [-5, 0, 0],
"1.2": [-15, 0, 0],
"2.0": [-20, 0, 0],
"2.6": [-5, 0, 3],
"3.0": [0, 0, 0]
}
},
"leg_front_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.5": [30, 0, 0],
"1.2": [45, 0, 0],
"2.2": [20, 0, 0],
"3.0": [0, 0, 0]
}
},
"leg_front_right": {
"rotation": {
"0.0": [0, 0, 0],
"0.5": [30, 0, 0],
"1.2": [45, 0, 0],
"2.2": [20, 0, 0],
"3.0": [0, 0, 0]
}
},
"leg_back_left": {
"rotation": {
"0.0": [0, 0, 0],
"0.8": [-15, 10, 0],
"1.5": [-25, 15, 0],
"2.5": [-10, 5, 0],
"3.0": [0, 0, 0]
}
},
"leg_back_right": {
"rotation": {
"0.0": [0, 0, 0],
"0.8": [-15, -10, 0],
"1.5": [-25, -15, 0],
"2.5": [-10, -5, 0],
"3.0": [0, 0, 0]
}
},
"wing_left": {
"rotation": {
"0.0": [0, 0, -5],
"1.0": [5, 0, -25],
"1.8": [10, 0, -40],
"2.4": [5, 0, -20],
"3.0": [0, 0, -5]
}
},
"wing_right": {
"rotation": {
"0.0": [0, 0, 5],
"1.0": [5, 0, 25],
"1.8": [10, 0, 40],
"2.4": [5, 0, 20],
"3.0": [0, 0, 5]
}
},
"tail": {
"rotation": {
"0.0": [0, -5, 0],
"0.8": [-5, 0, 0],
"1.5": [-15, 0, 0],
"2.5": [-20, 10, 0],
"3.0": [0, -5, 0]
}
}
}
},
"animation.spark_dragon.happy_bounce": {
"loop": true,
"animation_length": 0.7,
"bones": {
"body": {
"position": {
"0.0": [0, 0, 0],
"0.175": [0, 0.7, 0],
"0.35": [0, 0, 0],
"0.525": [0, 0.7, 0],
"0.7": [0, 0, 0]
}
},
"tail": {
"rotation": {
"0.0": [0, -20, 0],
"0.175": [0, 20, 0],
"0.35": [0, -20, 0],
"0.525": [0, 20, 0],
"0.7": [0, -20, 0]
}
},
"wing_left": {
"rotation": {
"0.0": [0, 0, -10],
"0.175": [0, 0, -30],
"0.35": [0, 0, -10],
"0.525": [0, 0, -30],
"0.7": [0, 0, -10]
}
},
"wing_right": {
"rotation": {
"0.0": [0, 0, 10],
"0.175": [0, 0, 30],
"0.35": [0, 0, 10],
"0.525": [0, 0, 30],
"0.7": [0, 0, 10]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.175": [-5, 0, 0],
"0.35": [0, 0, 0],
"0.525": [-5, 0, 0],
"0.7": [0, 0, 0]
}
}
}
},
"animation.spark_dragon.fire_breath": {
"loop": false,
"animation_length": 1.2,
"bones": {
"body": {
"rotation": {
"0.0": [0, 0, 0],
"0.3": [-8, 0, 0],
"0.7": [-10, 0, 0],
"1.0": [-5, 0, 0],
"1.2": [0, 0, 0]
}
},
"head": {
"rotation": {
"0.0": [0, 0, 0],
"0.2": [10, 0, 0],
"0.4": [-5, 0, 0],
"0.8": [-8, 0, 0],
"1.0": [5, 0, 0],
"1.2": [0, 0, 0]
}
},
"wing_left": {
"rotation": {
"0.0": [0, 0, -5],
"0.4": [15, 0, -50],
"0.8": [15, 0, -50],
"1.2": [0, 0, -5]
}
},
"wing_right": {
"rotation": {
"0.0": [0, 0, 5],
"0.4": [15, 0, 50],
"0.8": [15, 0, 50],
"1.2": [0, 0, 5]
}
},
"tail": {
"rotation": {
"0.0": [0, -5, 0],
"0.5": [-20, 0, 0],
"1.0": [-25, 0, 0],
"1.2": [0, -5, 0]
}
}
}
}
}
}

View File

@@ -7,7 +7,12 @@
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/spark_dragon"
"color_0": "textures/entity/spark_dragon_white",
"color_1": "textures/entity/spark_dragon_brown",
"color_2": "textures/entity/spark_dragon_green",
"color_3": "textures/entity/spark_dragon_red",
"color_4": "textures/entity/spark_dragon_teal",
"color_5": "textures/entity/spark_dragon_black"
},
"geometry": {
"default": "geometry.spark_dragon"
@@ -21,6 +26,11 @@
"sit": "animation.spark_dragon.sit",
"sleep": "animation.spark_dragon.sleep",
"fly": "animation.spark_dragon.fly",
"groom": "animation.spark_dragon.groom",
"sniff": "animation.spark_dragon.sniff",
"stretch": "animation.spark_dragon.stretch",
"happy_bounce": "animation.spark_dragon.happy_bounce",
"fire_breath": "animation.spark_dragon.fire_breath",
"controller": "controller.animation.spark_dragon",
"beacon_controller": "controller.animation.spark_dragon.beacon",
"mood_controller": "controller.animation.spark_dragon.mood"

View File

@@ -4,11 +4,23 @@
"controller.render.spark_dragon": {
"geometry": "Geometry.default",
"materials": [
{
"*": "Material.default"
}
{ "*": "Material.default" }
],
"textures": ["Texture.default"]
"textures": [
"Array.textures[query.property('silverlabs:dragon_color')]"
],
"arrays": {
"textures": {
"Array.textures": [
"Texture.color_0",
"Texture.color_1",
"Texture.color_2",
"Texture.color_3",
"Texture.color_4",
"Texture.color_5"
]
}
}
}
}
}

View File

@@ -2,11 +2,48 @@ entity.silverlabs:spark_dragon.name=Spark Dragon
item.spawn_egg.entity.silverlabs:spark_dragon.name=Spawn Spark Dragon
item.silverlabs:dragon_whistle.name=Dragon Whistle
tile.silverlabs:dragon_basket.name=Dragon Basket
## Dragon Nests
tile.silverlabs:dragon_nest_oak.name=Oak Dragon Nest
tile.silverlabs:dragon_nest_spruce.name=Spruce Dragon Nest
tile.silverlabs:dragon_nest_jungle.name=Jungle Dragon Nest
tile.silverlabs:dragon_nest_crimson.name=Crimson Dragon Nest
tile.silverlabs:dragon_nest_warped.name=Warped Dragon Nest
tile.silverlabs:dragon_nest_obsidian.name=Obsidian Dragon Nest
## Dragon Eggs
item.silverlabs:dragon_egg.name=Spark Dragon Egg
entity.silverlabs:dragon_egg.name=Spark Dragon Egg
item.silverlabs:dragon_egg_oak.name=Oak Nest Egg (White Dragon)
item.silverlabs:dragon_egg_spruce.name=Spruce Nest Egg (Brown Dragon)
item.silverlabs:dragon_egg_jungle.name=Jungle Nest Egg (Green Dragon)
item.silverlabs:dragon_egg_crimson.name=Crimson Nest Egg (Red Dragon)
item.silverlabs:dragon_egg_warped.name=Warped Nest Egg (Teal Dragon)
item.silverlabs:dragon_egg_obsidian.name=Obsidian Nest Egg (Black Dragon)
entity.silverlabs:dragon_egg_color_0.name=Spark Dragon Egg (White)
entity.silverlabs:dragon_egg_color_1.name=Spark Dragon Egg (Brown)
entity.silverlabs:dragon_egg_color_2.name=Spark Dragon Egg (Green)
entity.silverlabs:dragon_egg_color_3.name=Spark Dragon Egg (Red)
entity.silverlabs:dragon_egg_color_4.name=Spark Dragon Egg (Teal)
entity.silverlabs:dragon_egg_color_5.name=Spark Dragon Egg (Black)
## Dragon Items
item.silverlabs:dragon_bones.name=Dragon Bones
item.silverlabs:dragon_gravestone.name=Dragon Gravestone
entity.silverlabs:dragon_gravestone.name=Dragon Gravestone
item.silverlabs:dragon_toy.name=Spark Ball
entity.silverlabs:dragon_toy.name=Spark Ball
entity.silverlabs:whistle_signal.name=Whistle Signal
## Dragon Interactions — Traits
action.interact.silverlabs.teach_relaxed=Teach: Relaxed (Raw Chicken + Sneak)
action.interact.silverlabs.teach_explorer=Teach: Explorer (Raw Beef + Sneak)
action.interact.silverlabs.teach_affectionate=Teach: Affectionate (Cooked Salmon + Sneak)
action.interact.silverlabs.teach_playful=Teach: Playful (Melon Slice + Sneak)
action.interact.silverlabs.teach_independent=Teach: Independent (Bamboo + Sneak)
## Dragon Interactions — Fire
action.interact.silverlabs.breathe_fire=Breathe Fire (Fire Charge + Sneak)
## Riding
action.interact.mount=Ride Dragon

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 155 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 394 B

View File

@@ -8,6 +8,24 @@
"dragon_egg": {
"textures": "textures/items/dragon_egg"
},
"dragon_egg_oak": {
"textures": "textures/items/dragon_egg_oak"
},
"dragon_egg_spruce": {
"textures": "textures/items/dragon_egg_spruce"
},
"dragon_egg_jungle": {
"textures": "textures/items/dragon_egg_jungle"
},
"dragon_egg_crimson": {
"textures": "textures/items/dragon_egg_crimson"
},
"dragon_egg_warped": {
"textures": "textures/items/dragon_egg_warped"
},
"dragon_egg_obsidian": {
"textures": "textures/items/dragon_egg_obsidian"
},
"dragon_toy": {
"textures": "textures/items/dragon_toy"
},

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

View File

@@ -6,6 +6,24 @@
"texture_data": {
"dragon_basket": {
"textures": "textures/blocks/dragon_basket"
},
"dragon_nest_oak": {
"textures": "textures/blocks/dragon_nest_oak"
},
"dragon_nest_spruce": {
"textures": "textures/blocks/dragon_nest_spruce"
},
"dragon_nest_jungle": {
"textures": "textures/blocks/dragon_nest_jungle"
},
"dragon_nest_crimson": {
"textures": "textures/blocks/dragon_nest_crimson"
},
"dragon_nest_warped": {
"textures": "textures/blocks/dragon_nest_warped"
},
"dragon_nest_obsidian": {
"textures": "textures/blocks/dragon_nest_obsidian"
}
}
}