feat: add multi-world hub system with lobby portals and hub-return addon

Lobby addon detects players in portal zones at X: -15/0/15 and transfers
them to Jamie/Lyla/Mya survival worlds. Hub-return addon gives players a
recovery compass and chat commands (!hub, !lobby) to return to the lobby.

Includes docker-compose.yml for 4 Bedrock servers (lobby + 3 child worlds),
spark pet behavior/resource packs, and updated .gitignore.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-18 22:02:56 +00:00
parent 4c68cb60bc
commit 389e053dc5
70 changed files with 3725 additions and 50 deletions

11
.gitignore vendored
View File

@@ -8,5 +8,16 @@ Thumbs.db
*.swp *.swp
*.swo *.swo
# Build artifacts
*.mcaddon
*.mcpack
addon/build/
# Environment
.env
# Server data (Docker volumes are external, but just in case)
server-data/
# Claude Code # Claude Code
.claude/ .claude/

View File

@@ -2,6 +2,20 @@
This is a Claude Code workspace for interacting with a Minecraft Bedrock world via the mc-ai-bridge MCP server. This is a Claude Code workspace for interacting with a Minecraft Bedrock world via the mc-ai-bridge MCP server.
## Multi-World Architecture
Four Bedrock servers on `10.0.0.247`, connected via native `/transfer` (no proxy):
| Server | Port | Purpose |
|--------|------|---------|
| Lobby | 19132 | Main entry point (adventure mode) |
| Jamie | 19133 | Jamie's survival world |
| Lyla | 19134 | Lyla's survival world |
| Mya | 19135 | Mya's survival world |
Players connect to `10.0.0.247:19132` (lobby) and use portal zones to transfer to child worlds.
Child worlds have a hub-return addon (compass, `!hub`/`!lobby` commands, portal zone) to transfer back.
## Connection ## Connection
The mc-ai-bridge runs at `10.0.0.247`: The mc-ai-bridge runs at `10.0.0.247`:

51
addon/README.md Normal file
View File

@@ -0,0 +1,51 @@
# Spark Dragon Pet Addon
A custom Minecraft Bedrock addon that adds **Spark** — a tameable mini dragon pet with real personality.
## Features
- **Tameable**: Feed fish or salmon (33% chance per feed) to tame
- **Home Zone System**: Use a Dragon Whistle to set a home location
- **Daily Routine**: Explores by day, returns home at dusk, sleeps at night
- **Follow Mode**: Crouch + interact to toggle between follow and home-routine modes
- **Leashable & Nameable**: Full pet functionality
- **Fall Damage Immune**: Dragons don't take fall damage
- **Healable**: Feed fish/salmon to restore health
## Building
```bash
cd addon
bash build.sh
```
This produces `build/spark_dragon_pet.mcaddon`.
## Installation
1. **Windows**: Double-click the `.mcaddon` file to auto-import into Minecraft
2. **Manual**: Copy the packs to:
- `com.mojang/development_behavior_packs/spark_pet_BP/`
- `com.mojang/development_resource_packs/spark_pet_RP/`
3. Activate both packs on your world (Create/Edit World → Add-Ons)
## Usage
1. **Spawn**: `/summon silverlabs:spark_dragon ~ ~ ~` or use the spawn egg in creative
2. **Tame**: Hold fish or salmon and interact with the dragon
3. **Set Home**: Craft a Dragon Whistle, hold it, and interact with your tamed Spark
4. **Toggle Follow/Stay**: Crouch + interact with your tamed Spark
5. **Heal**: Feed fish (+4 HP) or salmon (+6 HP)
## Daily Cycle (when home is set)
| Time | Behavior |
|------|----------|
| DawnNoon (012000) | Exploring within 32 blocks of home |
| Dusk (1200013000) | Navigating back home |
| Night (1300023000) | Sleeping at home |
| Pre-dawn (2300024000) | Waking up |
## Entity ID
`silverlabs:spark_dragon`

28
addon/build.sh Normal file
View File

@@ -0,0 +1,28 @@
#!/bin/bash
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BUILD_DIR="$SCRIPT_DIR/build"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
echo "Packaging Behavior Pack..."
cd "$SCRIPT_DIR/spark_pet_BP"
zip -r "$BUILD_DIR/spark_pet_BP.mcpack" . -x ".*"
echo "Packaging Resource Pack..."
cd "$SCRIPT_DIR/spark_pet_RP"
zip -r "$BUILD_DIR/spark_pet_RP.mcpack" . -x ".*"
echo "Creating .mcaddon bundle..."
cd "$BUILD_DIR"
zip -r "$BUILD_DIR/pets_4_jamies_stars.mcaddon" spark_pet_BP.mcpack spark_pet_RP.mcpack
echo ""
echo "Build complete!"
echo " Output: $BUILD_DIR/pets_4_jamies_stars.mcaddon"
echo ""
echo "To install:"
echo " - Double-click the .mcaddon file on Windows to auto-import"
echo " - Or copy packs to com.mojang/development_behavior_packs/ and development_resource_packs/"

View File

@@ -0,0 +1,36 @@
{
"format_version": "1.21.0",
"minecraft:block": {
"description": {
"identifier": "silverlabs:dragon_basket",
"menu_category": {
"category": "items",
"group": "itemGroup.name.bed"
}
},
"components": {
"minecraft:geometry": "geometry.dragon_basket",
"minecraft:material_instances": {
"*": {
"texture": "dragon_basket",
"render_method": "alpha_test"
}
},
"minecraft:collision_box": {
"origin": [-7, 0, -7],
"size": [14, 5, 14]
},
"minecraft:selection_box": {
"origin": [-7, 0, -7],
"size": [14, 5, 14]
},
"minecraft:destructible_by_mining": {
"seconds_to_destroy": 1.0
},
"minecraft:destructible_by_explosion": {
"explosion_resistance": 2.0
},
"minecraft:map_color": "#8B5E3C"
}
}
}

View File

@@ -0,0 +1,396 @@
{
"format_version": "1.21.0",
"minecraft:entity": {
"description": {
"identifier": "silverlabs:dragon_egg",
"is_spawnable": false,
"is_summonable": true,
"is_experimental": false,
"properties": {
"silverlabs:egg_stage": {
"type": "int",
"default": 0,
"range": [0, 3],
"client_sync": true
}
}
},
"component_groups": {
"silverlabs:egg_cold": {
"minecraft:damage_sensor": {
"triggers": [
{
"cause": "fire",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_warming",
"target": "self"
}
},
{
"cause": "fire_tick",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_warming",
"target": "self"
}
},
{
"cause": "lava",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_warming",
"target": "self"
}
},
{
"cause": "magma",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_warming",
"target": "self"
}
},
{
"cause": "entity_attack",
"deals_damage": true
},
{
"cause": "all",
"deals_damage": false
}
]
},
"minecraft:timer": {
"time": 120,
"looping": false,
"time_down_event": {
"event": "silverlabs:advance_to_warming",
"target": "self"
}
},
"minecraft:interact": {
"interactions": [
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "blaze_powder" }
]
},
"event": "silverlabs:advance_to_warming",
"target": "self"
},
"use_item": true,
"interact_text": "Warm Egg",
"play_sounds": "fire.fire"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" }
]
},
"event": "",
"target": "self"
},
"use_item": false,
"interact_text": "The egg feels cold..."
}
]
}
},
"silverlabs:egg_warming": {
"minecraft:damage_sensor": {
"triggers": [
{
"cause": "fire",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hot",
"target": "self"
}
},
{
"cause": "fire_tick",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hot",
"target": "self"
}
},
{
"cause": "lava",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hot",
"target": "self"
}
},
{
"cause": "magma",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hot",
"target": "self"
}
},
{
"cause": "entity_attack",
"deals_damage": true
},
{
"cause": "all",
"deals_damage": false
}
]
},
"minecraft:timer": {
"time": 120,
"looping": false,
"time_down_event": {
"event": "silverlabs:advance_to_hot",
"target": "self"
}
},
"minecraft:interact": {
"interactions": [
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "blaze_powder" }
]
},
"event": "silverlabs:advance_to_hot",
"target": "self"
},
"use_item": true,
"interact_text": "Heat Egg",
"play_sounds": "fire.fire"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" }
]
},
"event": "",
"target": "self"
},
"use_item": false,
"interact_text": "The egg is getting warmer..."
}
]
}
},
"silverlabs:egg_hot": {
"minecraft:damage_sensor": {
"triggers": [
{
"cause": "fire",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hatching",
"target": "self"
}
},
{
"cause": "fire_tick",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hatching",
"target": "self"
}
},
{
"cause": "lava",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hatching",
"target": "self"
}
},
{
"cause": "magma",
"deals_damage": false,
"on_damage": {
"event": "silverlabs:advance_to_hatching",
"target": "self"
}
},
{
"cause": "entity_attack",
"deals_damage": true
},
{
"cause": "all",
"deals_damage": false
}
]
},
"minecraft:timer": {
"time": 120,
"looping": false,
"time_down_event": {
"event": "silverlabs:advance_to_hatching",
"target": "self"
}
},
"minecraft:interact": {
"interactions": [
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "blaze_powder" }
]
},
"event": "silverlabs:advance_to_hatching",
"target": "self"
},
"use_item": true,
"interact_text": "Ignite Egg",
"play_sounds": "fire.fire"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" }
]
},
"event": "",
"target": "self"
},
"use_item": false,
"interact_text": "The egg is almost ready!"
}
]
}
},
"silverlabs:egg_hatching": {
"minecraft:damage_sensor": {
"triggers": [
{
"cause": "all",
"deals_damage": false
}
]
},
"minecraft:spawn_entity": {
"entities": [
{
"min_wait_time": 0,
"max_wait_time": 1,
"spawn_sound": "mob.enderdragon.growl",
"spawn_entity": "silverlabs:spark_dragon",
"num_to_spawn": 1,
"single_use": true
}
]
},
"minecraft:timer": {
"time": 3,
"looping": false,
"time_down_event": {
"event": "silverlabs:despawn_egg",
"target": "self"
}
}
},
"silverlabs:egg_despawning": {
"minecraft:instant_despawn": {}
}
},
"components": {
"minecraft:type_family": {
"family": ["dragon_egg"]
},
"minecraft:physics": {},
"minecraft:collision_box": {
"width": 0.5,
"height": 0.6
},
"minecraft:pushable": {
"is_pushable": false,
"is_pushable_by_piston": false
},
"minecraft:knockback_resistance": {
"value": 1.0
},
"minecraft:persistent": {},
"minecraft:scale": {
"value": 1.0
},
"minecraft:health": {
"value": 4,
"max": 4
},
"minecraft:loot": {
"table": "loot_tables/gameplay/egg_pickup.json"
},
"minecraft:behavior.look_at_player": {
"priority": 7,
"look_distance": 6.0,
"probability": 0.02
}
},
"events": {
"minecraft:entity_spawned": {
"add": {
"component_groups": ["silverlabs:egg_cold"]
}
},
"silverlabs:advance_to_warming": {
"remove": {
"component_groups": ["silverlabs:egg_cold"]
},
"add": {
"component_groups": ["silverlabs:egg_warming"]
},
"set_property": {
"silverlabs:egg_stage": 1
}
},
"silverlabs:advance_to_hot": {
"remove": {
"component_groups": ["silverlabs:egg_warming"]
},
"add": {
"component_groups": ["silverlabs:egg_hot"]
},
"set_property": {
"silverlabs:egg_stage": 2
}
},
"silverlabs:advance_to_hatching": {
"remove": {
"component_groups": ["silverlabs:egg_hot"]
},
"add": {
"component_groups": ["silverlabs:egg_hatching"]
},
"set_property": {
"silverlabs:egg_stage": 3
}
},
"silverlabs:despawn_egg": {
"add": {
"component_groups": ["silverlabs:egg_despawning"]
}
}
}
}
}

View File

@@ -0,0 +1,84 @@
{
"format_version": "1.21.0",
"minecraft:entity": {
"description": {
"identifier": "silverlabs:dragon_gravestone",
"is_spawnable": false,
"is_summonable": true,
"is_experimental": false
},
"component_groups": {
"silverlabs:active": {
"minecraft:interact": {
"interactions": [
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" }
]
},
"event": "silverlabs:break_gravestone",
"target": "self"
},
"use_item": false,
"interact_text": "Collect Memorial",
"play_sounds": "random.anvil_land"
}
]
}
},
"silverlabs:breaking": {
"minecraft:loot": {
"table": "loot_tables/gameplay/gravestone_break.json"
},
"minecraft:instant_despawn": {}
}
},
"components": {
"minecraft:type_family": {
"family": ["dragon_gravestone"]
},
"minecraft:physics": {},
"minecraft:collision_box": {
"width": 0.5,
"height": 0.8
},
"minecraft:pushable": {
"is_pushable": false,
"is_pushable_by_piston": false
},
"minecraft:knockback_resistance": {
"value": 1.0
},
"minecraft:damage_sensor": {
"triggers": [
{ "cause": "all", "deals_damage": false }
]
},
"minecraft:persistent": {},
"minecraft:scale": {
"value": 0.8
},
"minecraft:health": {
"value": 999,
"max": 999
}
},
"events": {
"minecraft:entity_spawned": {
"add": {
"component_groups": ["silverlabs:active"]
}
},
"silverlabs:break_gravestone": {
"remove": {
"component_groups": ["silverlabs:active"]
},
"add": {
"component_groups": ["silverlabs:breaking"]
}
}
}
}
}

View File

@@ -0,0 +1,86 @@
{
"format_version": "1.21.0",
"minecraft:entity": {
"description": {
"identifier": "silverlabs:dragon_toy",
"is_spawnable": false,
"is_summonable": true,
"is_experimental": false
},
"component_groups": {
"silverlabs:airborne": {
"minecraft:projectile": {
"on_hit": {
"definition_event": {
"event_trigger": {
"event": "silverlabs:on_landed",
"target": "self"
}
}
},
"power": 1.5,
"gravity": 0.04,
"offset": [0, 0.5, 0],
"should_bounce": true
}
},
"silverlabs:landed": {
"minecraft:physics": {},
"minecraft:health": {
"value": 1,
"max": 1
},
"minecraft:pushable": {
"is_pushable": true,
"is_pushable_by_piston": true
},
"minecraft:loot": {
"table": "loot_tables/gameplay/toy_return.json"
},
"minecraft:timer": {
"time": 60,
"looping": false,
"time_down_event": {
"event": "silverlabs:despawn",
"target": "self"
}
}
},
"silverlabs:despawning": {
"minecraft:instant_despawn": {}
}
},
"components": {
"minecraft:type_family": {
"family": ["dragon_toy"]
},
"minecraft:collision_box": {
"width": 0.3,
"height": 0.3
},
"minecraft:scale": {
"value": 0.6
}
},
"events": {
"minecraft:entity_spawned": {
"add": {
"component_groups": ["silverlabs:airborne"]
}
},
"silverlabs:on_landed": {
"remove": {
"component_groups": ["silverlabs:airborne"]
},
"add": {
"component_groups": ["silverlabs:landed"]
}
},
"silverlabs:despawn": {
"add": {
"component_groups": ["silverlabs:despawning"]
}
}
}
}
}

View File

@@ -0,0 +1,992 @@
{
"format_version": "1.21.0",
"minecraft:entity": {
"description": {
"identifier": "silverlabs:spark_dragon",
"is_spawnable": true,
"is_summonable": true,
"is_experimental": false,
"properties": {
"silverlabs:growth_stage": {
"type": "int",
"default": 0,
"range": [0, 2],
"client_sync": true
},
"silverlabs:beacon_active": {
"type": "bool",
"default": false,
"client_sync": true
},
"silverlabs:mood": {
"type": "int",
"default": 1,
"range": [0, 2],
"client_sync": true
}
}
},
"component_groups": {
"silverlabs:wild": {
"minecraft:behavior.tempt": {
"priority": 3,
"speed_multiplier": 0.8,
"items": ["fish", "salmon"],
"can_tempt_vertically": true
},
"minecraft:behavior.avoid_mob_type": {
"priority": 4,
"max_dist": 8,
"walk_speed_multiplier": 1.0,
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "monster"
},
"max_dist": 8,
"walk_speed_multiplier": 1.0
}
]
}
},
"silverlabs:tamed": {
"minecraft:is_tamed": {},
"minecraft:behavior.follow_owner": {
"priority": 4,
"speed_multiplier": 0.8,
"start_distance": 8,
"stop_distance": 3
},
"minecraft:behavior.tempt": {
"priority": 3,
"speed_multiplier": 0.8,
"items": ["fish", "salmon"],
"can_tempt_vertically": true
},
"minecraft:sittable": {},
"minecraft:persistent": {},
"minecraft:behavior.nearest_attackable_target": {
"priority": 3,
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "dragon_toy"
},
"max_dist": 32
}
],
"must_see": false,
"reselect_targets": true
},
"minecraft:entity_sensor": {
"sensor_range": 500,
"relative_range": false,
"minimum_count": 1,
"event_filters": {
"test": "is_family",
"subject": "other",
"value": "whistle_signal"
},
"event": "silverlabs:whistle_called"
},
"minecraft:behavior.melee_attack": {
"priority": 2,
"speed_multiplier": 1.0,
"reach_multiplier": 1.0,
"track_target": true
},
"minecraft:attack": {
"damage": 1
},
"minecraft:on_target_escape": {
"event": "silverlabs:ball_caught",
"target": "self"
}
},
"silverlabs:tamed_following": {
"minecraft:is_tamed": {},
"minecraft:behavior.follow_owner": {
"priority": 2,
"speed_multiplier": 0.8,
"start_distance": 8,
"stop_distance": 3
},
"minecraft:sittable": {},
"minecraft:persistent": {},
"minecraft:teleport": {
"dark_teleport_chance": 0.0,
"light_teleport_chance": 0.1,
"max_random_teleport_time": 10,
"min_random_teleport_time": 5,
"random_teleport_cube_size": [10, 5, 10],
"target_distance": 64,
"target_teleport_chance": 0.3
}
},
"silverlabs:returning_fetch": {
"minecraft:behavior.follow_owner": {
"priority": 1,
"speed_multiplier": 1.0,
"start_distance": 15,
"stop_distance": 2
},
"minecraft:behavior.drop_item_for": {
"priority": 0,
"seconds_before_pickup": 0,
"cooldown": 60,
"drop_item_chance": 1.0,
"offering_distance": 5.0,
"speed_multiplier": 1.0,
"search_range": 20,
"search_height": 4,
"target_range": [5, 5, 5],
"time_of_day_range": [0.0, 1.0],
"loot_table": "loot_tables/gameplay/toy_return.json",
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "player"
},
"max_dist": 20
}
]
},
"minecraft:timer": {
"time": 5,
"looping": false,
"time_down_event": {
"event": "silverlabs:fetch_complete",
"target": "self"
}
}
},
"silverlabs:has_home": {
"minecraft:home": {
"restriction_radius": 32
},
"minecraft:scheduler": {
"min_delay_secs": 0,
"max_delay_secs": 0,
"scheduled_events": [
{
"filters": {
"all_of": [
{ "test": "hourly_clock_time", "operator": ">=", "value": 0 },
{ "test": "hourly_clock_time", "operator": "<", "value": 12000 }
]
},
"event": "silverlabs:start_exploring"
},
{
"filters": {
"all_of": [
{ "test": "hourly_clock_time", "operator": ">=", "value": 12000 },
{ "test": "hourly_clock_time", "operator": "<", "value": 13000 }
]
},
"event": "silverlabs:go_home"
},
{
"filters": {
"all_of": [
{ "test": "hourly_clock_time", "operator": ">=", "value": 13000 },
{ "test": "hourly_clock_time", "operator": "<", "value": 23000 }
]
},
"event": "silverlabs:start_sleeping"
},
{
"filters": {
"all_of": [
{ "test": "hourly_clock_time", "operator": ">=", "value": 23000 }
]
},
"event": "silverlabs:start_exploring"
}
]
}
},
"silverlabs:exploring": {
"minecraft:behavior.random_stroll": {
"priority": 6,
"speed_multiplier": 0.5,
"xz_dist": 12,
"y_dist": 2
},
"minecraft:behavior.random_look_around": {
"priority": 8
}
},
"silverlabs:going_home": {
"minecraft:behavior.go_home": {
"priority": 2,
"speed_multiplier": 0.8,
"interval": 1,
"goal_radius": 2,
"on_home": [
{
"event": "silverlabs:start_sleeping",
"target": "self"
}
]
}
},
"silverlabs:sleeping": {
"minecraft:is_sitting": {},
"minecraft:behavior.look_at_player": {
"priority": 8,
"look_distance": 4.0
}
},
"silverlabs:sitting": {
"minecraft:is_sitting": {}
},
"silverlabs:beacon_on": {
"minecraft:timer": {
"time": 12,
"looping": false,
"time_down_event": {
"event": "silverlabs:beacon_off",
"target": "self"
}
}
},
"silverlabs:tamed_called": {
"minecraft:is_tamed": {},
"minecraft:behavior.follow_owner": {
"priority": 1,
"speed_multiplier": 1.0,
"start_distance": 200,
"stop_distance": 3
},
"minecraft:sittable": {},
"minecraft:persistent": {},
"minecraft:teleport": {
"dark_teleport_chance": 0.0,
"light_teleport_chance": 1.0,
"max_random_teleport_time": 3,
"min_random_teleport_time": 1,
"random_teleport_cube_size": [20, 10, 20],
"target_distance": 24,
"target_teleport_chance": 1.0
}
},
"silverlabs:tamed_loot": {
"minecraft:loot": {
"table": "loot_tables/gameplay/dragon_death.json"
}
},
"silverlabs:guide_drop": {
"minecraft:behavior.drop_item_for": {
"priority": 1,
"seconds_before_pickup": 0,
"cooldown": 99999,
"drop_item_chance": 1.0,
"offering_distance": 5.0,
"speed_multiplier": 1.0,
"search_range": 10,
"search_height": 4,
"target_range": [5, 5, 5],
"time_of_day_range": [0.0, 1.0],
"loot_table": "loot_tables/gameplay/dragon_guide.json",
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "player"
},
"max_dist": 16
}
]
},
"minecraft:timer": {
"time": 10,
"looping": false,
"time_down_event": {
"event": "silverlabs:guide_dropped",
"target": "self"
}
}
},
"silverlabs:mood_happy": {
"minecraft:timer": {
"time": [480, 720],
"looping": false,
"time_down_event": {
"event": "silverlabs:mood_decay_to_content",
"target": "self"
}
}
},
"silverlabs:mood_content": {
"minecraft:timer": {
"time": [360, 600],
"looping": false,
"time_down_event": {
"event": "silverlabs:mood_decay_to_needy",
"target": "self"
}
}
},
"silverlabs:mood_needy": {
"minecraft:behavior.look_at_player": {
"priority": 3,
"look_distance": 10.0,
"probability": 0.1
}
},
"silverlabs:stage_baby": {
"minecraft:is_baby": {},
"minecraft:ageable": {
"duration": 1200,
"feed_items": ["fish", "salmon"],
"grow_up": {
"event": "silverlabs:grow_to_juvenile",
"target": "self"
}
},
"minecraft:scale": {
"value": 0.4
},
"minecraft:collision_box": {
"width": 0.35,
"height": 0.3
},
"minecraft:movement": {
"value": 0.15
},
"minecraft:health": {
"value": 10,
"max": 10
},
"minecraft:behavior.drop_item_for": {
"priority": 5,
"seconds_before_pickup": 0,
"cooldown": 600,
"drop_item_chance": 0.6,
"offering_distance": 5.0,
"minimum_teleport_distance": 2.0,
"speed_multiplier": 1.0,
"search_range": 10,
"search_height": 2,
"target_range": [5, 5, 5],
"teleport_offset": [0, 1, 0],
"time_of_day_range": [0.0, 0.5],
"loot_table": "loot_tables/gameplay/gift_baby.json",
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "player"
},
"max_dist": 16
}
]
},
"minecraft:behavior.play": {
"priority": 5,
"speed_multiplier": 0.7,
"friend_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "spark_dragon"
}
}
]
}
},
"silverlabs:stage_juvenile": {
"minecraft:scale": {
"value": 0.7
},
"minecraft:collision_box": {
"width": 0.5,
"height": 0.4
},
"minecraft:movement": {
"value": 0.2
},
"minecraft:health": {
"value": 20,
"max": 20
},
"minecraft:jump.static": {
"jump_power": 0.5
},
"minecraft:timer": {
"time": 1200,
"looping": false,
"time_down_event": {
"event": "silverlabs:grow_to_adult",
"target": "self"
}
},
"minecraft:behavior.drop_item_for": {
"priority": 5,
"seconds_before_pickup": 0,
"cooldown": 480,
"drop_item_chance": 0.7,
"offering_distance": 5.0,
"minimum_teleport_distance": 2.0,
"speed_multiplier": 1.0,
"search_range": 12,
"search_height": 2,
"target_range": [5, 5, 5],
"teleport_offset": [0, 1, 0],
"time_of_day_range": [0.0, 0.5],
"loot_table": "loot_tables/gameplay/gift_juvenile.json",
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "player"
},
"max_dist": 16
}
]
},
"minecraft:behavior.play": {
"priority": 5,
"speed_multiplier": 0.8,
"friend_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "spark_dragon"
}
}
]
},
"minecraft:behavior.raid_garden": {
"priority": 6,
"speed_multiplier": 1.0,
"search_range": 12,
"search_height": 2,
"goal_radius": 1.0,
"max_to_eat": 2,
"initial_eat_delay": 20
}
},
"silverlabs:stage_adult": {
"minecraft:scale": {
"value": 1.0
},
"minecraft:collision_box": {
"width": 0.6,
"height": 0.5
},
"minecraft:movement": {
"value": 0.25
},
"minecraft:health": {
"value": 30,
"max": 30
},
"minecraft:can_fly": {},
"minecraft:navigation.fly": {
"can_path_over_water": true,
"can_path_from_air": true
},
"minecraft:movement.fly": {},
"minecraft:flying_speed": {
"value": 0.04
},
"minecraft:behavior.drop_item_for": {
"priority": 5,
"seconds_before_pickup": 0,
"cooldown": 300,
"drop_item_chance": 0.8,
"offering_distance": 5.0,
"minimum_teleport_distance": 2.0,
"speed_multiplier": 1.0,
"search_range": 16,
"search_height": 4,
"target_range": [5, 5, 5],
"teleport_offset": [0, 1, 0],
"time_of_day_range": [0.0, 0.5],
"loot_table": "loot_tables/gameplay/gift_adult.json",
"entity_types": [
{
"filters": {
"test": "is_family",
"subject": "other",
"value": "player"
},
"max_dist": 16
}
]
}
}
},
"components": {
"minecraft:type_family": {
"family": ["spark_dragon", "pet", "mob"]
},
"minecraft:physics": {},
"minecraft:pushable": {
"is_pushable": true,
"is_pushable_by_piston": true
},
"minecraft:can_climb": {},
"minecraft:navigation.walk": {
"can_path_over_water": true,
"avoid_water": true,
"avoid_damage_blocks": true
},
"minecraft:movement.basic": {
"max_turn": 20.0
},
"minecraft:jump.static": {},
"minecraft:tameable": {
"probability": 0.33,
"tame_items": ["fish", "salmon"],
"tame_event": {
"event": "silverlabs:on_tamed",
"target": "self"
}
},
"minecraft:healable": {
"items": [
{ "item": "fish", "heal_amount": 4 },
{ "item": "salmon", "heal_amount": 6 }
]
},
"minecraft:leashable": {
"soft_distance": 4.0,
"hard_distance": 6.0,
"max_distance": 10.0
},
"minecraft:nameable": {},
"minecraft:breathable": {
"total_supply": 15,
"suffocate_time": 0,
"breathes_air": true,
"breathes_water": false
},
"minecraft:damage_sensor": {
"triggers": [
{
"cause": "fall",
"deals_damage": false
}
]
},
"minecraft:behavior.float": {
"priority": 0
},
"minecraft:behavior.look_at_player": {
"priority": 7,
"look_distance": 8.0,
"probability": 0.02
},
"minecraft:behavior.random_look_around": {
"priority": 9
},
"minecraft:behavior.random_stroll": {
"priority": 8,
"speed_multiplier": 0.4,
"xz_dist": 7,
"y_dist": 2
},
"minecraft:interact": {
"interactions": [
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "fish" },
{ "test": "has_component", "value": "minecraft:is_tamed" }
]
},
"event": "silverlabs:mood_boost",
"target": "self"
},
"use_item": false
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "salmon" },
{ "test": "has_component", "value": "minecraft:is_tamed" }
]
},
"event": "silverlabs:mood_boost",
"target": "self"
},
"use_item": false
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "potion" },
{ "test": "has_component", "value": "minecraft:is_tamed" }
]
},
"event": "silverlabs:mood_boost",
"target": "self"
},
"use_item": true,
"interact_text": "Give Water"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "amethyst_shard" },
{ "test": "has_component", "value": "minecraft:is_tamed" }
]
},
"event": "silverlabs:request_guide",
"target": "self"
},
"use_item": true,
"interact_text": "Request Guide",
"play_sounds": "random.orb"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" },
{ "test": "is_sneaking", "subject": "other", "value": false },
{ "test": "has_component", "value": "minecraft:is_tamed" },
{ "test": "has_component", "value": "minecraft:is_sitting" }
]
},
"event": "silverlabs:on_stand",
"target": "self"
},
"use_item": false,
"interact_text": "Get Up",
"play_sounds": "mob.wolf.bark"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" },
{ "test": "is_sneaking", "subject": "other", "value": false },
{ "test": "has_component", "value": "minecraft:is_tamed" },
{ "test": "has_component", "operator": "!=", "value": "minecraft:is_sitting" }
]
},
"event": "silverlabs:command_follow",
"target": "self"
},
"use_item": false,
"interact_text": "Follow Me",
"play_sounds": "mob.wolf.bark"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "bone" },
{ "test": "is_sneaking", "subject": "other", "value": true },
{ "test": "has_component", "value": "minecraft:is_tamed" },
{ "test": "has_component", "operator": "!=", "value": "minecraft:is_sitting" }
]
},
"event": "silverlabs:set_home",
"target": "self"
},
"use_item": false,
"interact_text": "Set Home",
"play_sounds": "random.levelup"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "value": "bone" },
{ "test": "is_sneaking", "subject": "other", "value": true },
{ "test": "has_component", "value": "minecraft:is_tamed" },
{ "test": "has_component", "value": "minecraft:is_sitting" },
{ "test": "has_component", "value": "minecraft:home" }
]
},
"event": "silverlabs:command_go_home",
"target": "self"
},
"use_item": false,
"interact_text": "Go Home",
"play_sounds": "note.pling"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" },
{ "test": "is_sneaking", "subject": "other", "value": true },
{ "test": "has_component", "value": "minecraft:is_tamed" },
{ "test": "has_component", "operator": "!=", "value": "minecraft:is_sitting" }
]
},
"event": "silverlabs:on_sit",
"target": "self"
},
"use_item": false,
"interact_text": "Stay"
},
{
"on_interact": {
"filters": {
"all_of": [
{ "test": "is_family", "subject": "other", "value": "player" },
{ "test": "has_equipment", "subject": "other", "domain": "hand", "operator": "not", "value": "name_tag" },
{ "test": "is_sneaking", "subject": "other", "value": true },
{ "test": "has_component", "value": "minecraft:is_tamed" },
{ "test": "has_component", "value": "minecraft:is_sitting" }
]
},
"event": "silverlabs:on_stand",
"target": "self"
},
"use_item": false,
"interact_text": "Stand"
}
]
},
"minecraft:spawn_entity": {}
},
"events": {
"minecraft:entity_spawned": {
"add": {
"component_groups": ["silverlabs:wild", "silverlabs:stage_baby"]
}
},
"silverlabs:on_tamed": {
"remove": {
"component_groups": ["silverlabs:wild"]
},
"add": {
"component_groups": ["silverlabs:tamed", "silverlabs:tamed_loot", "silverlabs:guide_drop", "silverlabs:mood_happy"]
},
"set_property": {
"silverlabs:mood": 2
}
},
"silverlabs:request_guide": {
"add": { "component_groups": ["silverlabs:guide_drop"] }
},
"silverlabs:guide_dropped": {
"remove": {
"component_groups": ["silverlabs:guide_drop"]
}
},
"silverlabs:mood_boost": {
"remove": {
"component_groups": ["silverlabs:mood_happy", "silverlabs:mood_content", "silverlabs:mood_needy"]
},
"add": {
"component_groups": ["silverlabs:mood_happy"]
},
"set_property": {
"silverlabs:mood": 2
}
},
"silverlabs:mood_decay_to_content": {
"remove": {
"component_groups": ["silverlabs:mood_happy"]
},
"add": {
"component_groups": ["silverlabs:mood_content"]
},
"set_property": {
"silverlabs:mood": 1
}
},
"silverlabs:mood_decay_to_needy": {
"remove": {
"component_groups": ["silverlabs:mood_content"]
},
"add": {
"component_groups": ["silverlabs:mood_needy"]
},
"set_property": {
"silverlabs:mood": 0
}
},
"silverlabs:grow_to_juvenile": {
"remove": {
"component_groups": ["silverlabs:stage_baby", "silverlabs:mood_happy", "silverlabs:mood_content", "silverlabs:mood_needy"]
},
"add": {
"component_groups": ["silverlabs:stage_juvenile"]
},
"set_property": {
"silverlabs:growth_stage": 1,
"silverlabs:mood": 1
}
},
"silverlabs:grow_to_adult": {
"remove": {
"component_groups": ["silverlabs:stage_juvenile"]
},
"add": {
"component_groups": ["silverlabs:stage_adult", "silverlabs:mood_content"]
},
"set_property": {
"silverlabs:growth_stage": 2,
"silverlabs:mood": 1
}
},
"silverlabs:ball_caught": {
"add": {
"component_groups": ["silverlabs:returning_fetch"]
}
},
"silverlabs:fetch_complete": {
"remove": {
"component_groups": ["silverlabs:returning_fetch", "silverlabs:mood_happy", "silverlabs:mood_content", "silverlabs:mood_needy"]
},
"add": {
"component_groups": ["silverlabs:tamed_following", "silverlabs:mood_happy"]
},
"set_property": {
"silverlabs:mood": 2
}
},
"silverlabs:command_follow": {
"add": {
"component_groups": ["silverlabs:tamed_following", "silverlabs:beacon_on"]
},
"remove": {
"component_groups": ["silverlabs:exploring", "silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch", "silverlabs:tamed_called"]
},
"set_property": {
"silverlabs:beacon_active": true
}
},
"silverlabs:whistle_called": {
"add": {
"component_groups": ["silverlabs:tamed_called", "silverlabs:beacon_on"]
},
"remove": {
"component_groups": ["silverlabs:exploring", "silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch", "silverlabs:tamed_following"]
},
"set_property": {
"silverlabs:beacon_active": true
}
},
"silverlabs:activate_beacon": {
"add": {
"component_groups": ["silverlabs:beacon_on"]
},
"set_property": {
"silverlabs:beacon_active": true
}
},
"silverlabs:beacon_off": {
"remove": {
"component_groups": ["silverlabs:beacon_on", "silverlabs:tamed_called"]
},
"add": {
"component_groups": ["silverlabs:tamed_following"]
},
"set_property": {
"silverlabs:beacon_active": false
}
},
"silverlabs:command_go_home": {
"add": {
"component_groups": ["silverlabs:going_home"]
},
"remove": {
"component_groups": ["silverlabs:exploring", "silverlabs:tamed_following", "silverlabs:sitting", "silverlabs:returning_fetch"]
}
},
"silverlabs:set_home": {
"add": {
"component_groups": ["silverlabs:has_home", "silverlabs:exploring"]
},
"remove": {
"component_groups": ["silverlabs:tamed_following", "silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch"]
}
},
"silverlabs:start_exploring": {
"add": {
"component_groups": ["silverlabs:exploring"]
},
"remove": {
"component_groups": ["silverlabs:sleeping", "silverlabs:going_home", "silverlabs:sitting", "silverlabs:returning_fetch"]
}
},
"silverlabs:go_home": {
"add": {
"component_groups": ["silverlabs:going_home"]
},
"remove": {
"component_groups": ["silverlabs:exploring", "silverlabs:sleeping", "silverlabs:returning_fetch"]
}
},
"silverlabs:start_sleeping": {
"add": {
"component_groups": ["silverlabs:sleeping"]
},
"remove": {
"component_groups": ["silverlabs:exploring", "silverlabs:going_home", "silverlabs:returning_fetch"]
}
},
"silverlabs:on_sit": {
"add": {
"component_groups": ["silverlabs:sitting"]
},
"remove": {
"component_groups": ["silverlabs:exploring", "silverlabs:going_home", "silverlabs:tamed_following", "silverlabs:returning_fetch"]
}
},
"silverlabs:on_stand": {
"remove": {
"component_groups": ["silverlabs:sitting", "silverlabs:sleeping", "silverlabs:returning_fetch"]
},
"add": {
"component_groups": ["silverlabs:tamed_following"]
}
}
}
}
}

View File

@@ -0,0 +1,82 @@
{
"format_version": "1.21.0",
"minecraft:entity": {
"description": {
"identifier": "silverlabs:whistle_signal",
"is_spawnable": false,
"is_summonable": true,
"is_experimental": false
},
"component_groups": {
"silverlabs:airborne": {
"minecraft:projectile": {
"on_hit": {
"definition_event": {
"event_trigger": {
"event": "silverlabs:on_landed",
"target": "self"
}
}
},
"power": 1.2,
"gravity": 0.05,
"offset": [0, 0.5, 0],
"should_bounce": false
}
},
"silverlabs:landed": {
"minecraft:physics": {},
"minecraft:health": {
"value": 1,
"max": 1
},
"minecraft:loot": {
"table": "loot_tables/gameplay/whistle_return.json"
},
"minecraft:timer": {
"time": 2,
"looping": false,
"time_down_event": {
"event": "silverlabs:despawn",
"target": "self"
}
}
},
"silverlabs:despawning": {
"minecraft:instant_despawn": {}
}
},
"components": {
"minecraft:type_family": {
"family": ["whistle_signal"]
},
"minecraft:collision_box": {
"width": 0.1,
"height": 0.1
},
"minecraft:scale": {
"value": 0.01
}
},
"events": {
"minecraft:entity_spawned": {
"add": {
"component_groups": ["silverlabs:airborne"]
}
},
"silverlabs:on_landed": {
"remove": {
"component_groups": ["silverlabs:airborne"]
},
"add": {
"component_groups": ["silverlabs:landed"]
}
},
"silverlabs:despawn": {
"add": {
"component_groups": ["silverlabs:despawning"]
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
{
"format_version": "1.21.120",
"minecraft:item": {
"description": {
"identifier": "silverlabs:dragon_bones",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:icon": "dragon_bones",
"minecraft:display_name": {
"value": "item.silverlabs:dragon_bones.name"
},
"minecraft:max_stack_size": 1,
"minecraft:glint": true
}
}
}

View File

@@ -0,0 +1,22 @@
{
"format_version": "1.21.120",
"minecraft:item": {
"description": {
"identifier": "silverlabs:dragon_egg",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:icon": "dragon_egg",
"minecraft:display_name": {
"value": "item.silverlabs:dragon_egg.name"
},
"minecraft:max_stack_size": 1,
"minecraft:glint": true,
"minecraft:entity_placer": {
"entity": "silverlabs:dragon_egg"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"format_version": "1.21.120",
"minecraft:item": {
"description": {
"identifier": "silverlabs:dragon_gravestone",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:icon": "dragon_gravestone",
"minecraft:display_name": {
"value": "item.silverlabs:dragon_gravestone.name"
},
"minecraft:max_stack_size": 1,
"minecraft:glint": true,
"minecraft:entity_placer": {
"entity": "silverlabs:dragon_gravestone"
}
}
}
}

View File

@@ -0,0 +1,26 @@
{
"format_version": "1.21.0",
"minecraft:item": {
"description": {
"identifier": "silverlabs:dragon_toy",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:icon": "dragon_toy",
"minecraft:display_name": {
"value": "item.silverlabs:dragon_toy.name"
},
"minecraft:max_stack_size": 16,
"minecraft:throwable": {
"do_swing_animation": true,
"max_draw_duration": 0,
"scale_power_by_draw_duration": false
},
"minecraft:projectile": {
"projectile_entity": "silverlabs:dragon_toy"
}
}
}
}

View File

@@ -0,0 +1,26 @@
{
"format_version": "1.21.0",
"minecraft:item": {
"description": {
"identifier": "silverlabs:dragon_whistle",
"menu_category": {
"category": "items"
}
},
"components": {
"minecraft:icon": "dragon_whistle",
"minecraft:display_name": {
"value": "item.silverlabs:dragon_whistle.name"
},
"minecraft:max_stack_size": 16,
"minecraft:throwable": {
"do_swing_animation": true,
"max_draw_duration": 0,
"scale_power_by_draw_duration": false
},
"minecraft:projectile": {
"projectile_entity": "silverlabs:whistle_signal"
}
}
}
}

View File

@@ -0,0 +1,22 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "silverlabs:dragon_bones", "weight": 1 }
]
},
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "silverlabs:dragon_gravestone", "weight": 1 }
]
},
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "minecraft:name_tag", "weight": 1 }
]
}
]
}

View File

@@ -0,0 +1,33 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "minecraft:written_book",
"weight": 1,
"functions": [
{
"function": "set_book_contents",
"author": "SilverLABS",
"title": "Spark Dragon Guide",
"pages": [
"§l§5Spark Dragon Guide§r\n\nWelcome, Dragon Keeper!\n\nThis guide covers everything you need to know about caring for your Spark Dragon companion.\n\n§oTurn the page to begin...§r",
"§l§6Getting Started§r\n\nTo hatch a Spark Dragon:\n\n§f1. Craft a §eDragon Basket§f and place it\n§f2. Place a §dSpark Dragon Egg§f nearby\n§f3. The egg will hatch into a baby!\n\nTo tame:\n§f• Hold §bRaw Cod§f or §cRaw Salmon§f\n§f• Interact with the baby dragon\n§f• Each attempt has a §a33%§f chance\n§f• Hearts appear when tamed!\n\n§7Name your dragon with a §eName Tag§7!§r",
"§l§6Commands§r\n\nOnce tamed, interact to command:\n\n§f• §eFollow Me§f - interact (standing)\n§f• §eStay§f - sneak + interact (sits)\n§f• §eStand§f - sneak + interact (sitting)\n§f• §eGet Up§f - interact while sitting\n§f• §eSet Home§f - sneak + bone (standing)\n§f• §eGo Home§f - sneak + bone (sitting)\n\n§7Commands cycle based on current state.§r",
"§l§6Feeding & Healing§r\n\nFeed your dragon to heal it:\n\n§f• §bRaw Cod§f: restores §a4 HP§f\n§f• §cRaw Salmon§f: restores §a6 HP§f\n\nFeeding fish and giving §9Water Bottles§f both §dimprove your dragon's mood§r!\n\n§7Tip: Water bottles are an easy mood boost — just brew or fill one at a water source.§r",
"§l§6Home & Basket§r\n\nSet up a home for your dragon:\n\n§f1. Place a §eDragon Basket§f\n§f2. Stand near it with your dragon\n§f3. Hold a §eBone§f and sneak + interact\n\nWith a home set, your dragon will:\n§f• Explore by day (32 block radius)\n§f• Return home at dusk\n§f• Sleep through the night\n§f• Wake at dawn to explore\n\n§7Send it home: sneak + bone while sitting.§r",
"§l§6Growth Stages§r\n\nDragons grow through 3 stages:\n\n§a1. Baby§f (small, 10 HP)\n Grows up by feeding or waiting\n\n§e2. Juvenile§f (medium, 20 HP)\n Timer-based growth (~20 min)\n May raid gardens!\n\n§c3. Adult§f (full size, 30 HP)\n Can fly! Drops better gifts.\n\n§7Feed fish to speed up baby growth.§r",
"§l§6Mood System§r\n\nYour dragon has feelings!\n\n§a★ Happy§f - Green star particles\n Recently fed, watered, or played\n\n§7● Content§f - No particles\n Default calm state\n\n§4♨ Needy§f - Gray smoke particles\n Wants food or attention!\n\n§dBoost mood with:§f fish, §9water bottles§f, or fetch!\nMood decays over time.\n\n§7Juveniles are always content.§r",
"§l§6Playing Fetch§r\n\nCraft a §dSpark Ball§f:\n String around Leather\n (shaped recipe, crafting table)\n\n§f• Throw the ball (use item)\n§f• Dragon chases and catches it\n§f• Returns the ball to you!\n§f• Resets mood to §aHappy§r\n\n§7Great way to bond with your dragon and keep it happy!§r",
"§l§6Death & Gravestones§r\n\nIf your dragon dies, it leaves a §7Dragon Gravestone§f at the death location.\n\n§f• Look for the §ebeacon column§f of particles rising into the sky\n§f• The gravestone glows to help you find it\n§f• Collect §7Dragon Bones§f as a memorial\n\n§7The beacon makes gravestones visible from far away.§r",
"§l§6Tips & Tricks§r\n\n§f• Dragons are §afall immune§f\n§f• Use a §eLead§f to guide them\n§f• §eName Tags§f work normally\n§f• Craft a §dDragon Whistle§f for ranged recall (throw it!)\n§f• Give an §dAmethyst Shard§f to get another copy of this guide\n§f• §9Water Bottles§f boost mood without using food\n\n§5Enjoy your Spark Dragon!§r\n§7- SilverLABS§r"
]
}
]
}
]
}
]
}

View File

@@ -0,0 +1,14 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{
"type": "item",
"name": "silverlabs:dragon_egg",
"weight": 1
}
]
}
]
}

View File

@@ -0,0 +1,23 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "minecraft:diamond", "weight": 5 },
{ "type": "item", "name": "minecraft:emerald", "weight": 8 },
{ "type": "item", "name": "minecraft:gold_ingot", "weight": 15 },
{ "type": "item", "name": "minecraft:iron_ingot", "weight": 20 },
{ "type": "item", "name": "minecraft:amethyst_shard", "weight": 12 },
{ "type": "item", "name": "minecraft:lapis_lazuli", "weight": 15,
"functions": [{ "function": "set_count", "count": { "min": 2, "max": 5 } }]
},
{ "type": "item", "name": "minecraft:redstone", "weight": 15,
"functions": [{ "function": "set_count", "count": { "min": 2, "max": 4 } }]
},
{ "type": "item", "name": "minecraft:golden_apple", "weight": 3 },
{ "type": "item", "name": "minecraft:name_tag", "weight": 7 },
{ "type": "item", "name": "silverlabs:dragon_egg", "weight": 1 }
]
}
]
}

View File

@@ -0,0 +1,16 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "minecraft:feather", "weight": 20 },
{ "type": "item", "name": "minecraft:wheat_seeds", "weight": 20 },
{ "type": "item", "name": "minecraft:string", "weight": 15 },
{ "type": "item", "name": "minecraft:bone", "weight": 15 },
{ "type": "item", "name": "minecraft:yellow_flower", "weight": 10 },
{ "type": "item", "name": "minecraft:red_flower", "weight": 10 },
{ "type": "item", "name": "minecraft:stick", "weight": 10 }
]
}
]
}

View File

@@ -0,0 +1,16 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "minecraft:iron_nugget", "weight": 20 },
{ "type": "item", "name": "minecraft:gold_nugget", "weight": 15 },
{ "type": "item", "name": "minecraft:coal", "weight": 20 },
{ "type": "item", "name": "minecraft:redstone", "weight": 15 },
{ "type": "item", "name": "minecraft:lapis_lazuli", "weight": 10 },
{ "type": "item", "name": "minecraft:flint", "weight": 10 },
{ "type": "item", "name": "minecraft:copper_ingot", "weight": 10 }
]
}
]
}

View File

@@ -0,0 +1,10 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "silverlabs:dragon_gravestone", "weight": 1 }
]
}
]
}

View File

@@ -0,0 +1,10 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "silverlabs:dragon_toy", "weight": 1 }
]
}
]
}

View File

@@ -0,0 +1,10 @@
{
"pools": [
{
"rolls": 1,
"entries": [
{ "type": "item", "name": "silverlabs:dragon_whistle", "weight": 1 }
]
}
]
}

View File

@@ -0,0 +1,23 @@
{
"format_version": 2,
"header": {
"name": "Pets 4 Jamie's STARS",
"description": "Tameable dragon pets with eggs, gravestones and personality — built for Jamie's STARS!",
"uuid": "7cf924ce-e246-4c8c-998c-f420edb26451",
"version": [1, 0, 0],
"min_engine_version": [1, 21, 0]
},
"modules": [
{
"type": "data",
"uuid": "6806e843-c0b4-4a4d-9cb3-d5352e396fe5",
"version": [1, 0, 0]
}
],
"dependencies": [
{
"uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b",
"version": [1, 0, 0]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

View File

@@ -0,0 +1,22 @@
{
"format_version": "1.21.0",
"minecraft:recipe_shaped": {
"description": {
"identifier": "silverlabs:dragon_basket_recipe"
},
"tags": ["crafting_table"],
"pattern": [
"S S",
"WLW",
"SSS"
],
"key": {
"S": { "item": "minecraft:stick" },
"W": { "item": "minecraft:wool" },
"L": { "item": "minecraft:leather" }
},
"result": {
"item": "silverlabs:dragon_basket"
}
}
}

View File

@@ -0,0 +1,23 @@
{
"format_version": "1.20.10",
"minecraft:recipe_shaped": {
"description": {
"identifier": "silverlabs:dragon_egg"
},
"tags": ["crafting_table"],
"pattern": [
" B ",
"AGA",
" A "
],
"key": {
"B": { "item": "minecraft:blaze_powder" },
"A": { "item": "minecraft:amethyst_shard" },
"G": { "item": "minecraft:gold_ingot" }
},
"result": {
"item": "silverlabs:dragon_egg",
"count": 1
}
}
}

View File

@@ -0,0 +1,22 @@
{
"format_version": "1.20.10",
"minecraft:recipe_shaped": {
"description": {
"identifier": "silverlabs:dragon_toy"
},
"tags": ["crafting_table"],
"pattern": [
" S ",
"SLS",
" S "
],
"key": {
"S": { "item": "minecraft:string" },
"L": { "item": "minecraft:leather" }
},
"result": {
"item": "silverlabs:dragon_toy",
"count": 4
}
}
}

View File

@@ -0,0 +1,41 @@
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.dragon_egg": {
"initial_state": "cold",
"states": {
"cold": {
"animations": ["idle"],
"transitions": [
{ "warming": "query.property('silverlabs:egg_stage') == 1" }
]
},
"warming": {
"animations": ["wobble"],
"particle_effects": [
{ "effect": "smoke" }
],
"transitions": [
{ "hot": "query.property('silverlabs:egg_stage') == 2" }
]
},
"hot": {
"animations": ["shake"],
"particle_effects": [
{ "effect": "flame" },
{ "effect": "smoke" }
],
"transitions": [
{ "hatching": "query.property('silverlabs:egg_stage') == 3" }
]
},
"hatching": {
"animations": ["shake"],
"particle_effects": [
{ "effect": "flame" }
]
}
}
}
}
}

View File

@@ -0,0 +1,26 @@
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.dragon_gravestone": {
"initial_state": "active",
"states": {
"active": {
"animations": ["idle"],
"particle_effects": [
{ "effect": "memorial_glow" }
]
}
}
},
"controller.animation.dragon_gravestone.beacon": {
"initial_state": "active",
"states": {
"active": {
"particle_effects": [
{ "effect": "beacon_beam" }
]
}
}
}
}
}

View File

@@ -0,0 +1,95 @@
{
"format_version": "1.10.0",
"animation_controllers": {
"controller.animation.spark_dragon.beacon": {
"initial_state": "inactive",
"states": {
"inactive": {
"transitions": [
{ "active": "query.property('silverlabs:beacon_active')" }
]
},
"active": {
"particle_effects": [
{ "effect": "beacon_beam" }
],
"transitions": [
{ "inactive": "!query.property('silverlabs:beacon_active')" }
]
}
}
},
"controller.animation.spark_dragon": {
"initial_state": "idle",
"states": {
"idle": {
"animations": ["idle"],
"transitions": [
{ "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" }
]
},
"walking": {
"animations": ["walk"],
"transitions": [
{ "flying": "!query.is_on_ground && query.property('silverlabs:growth_stage') == 2" },
{ "idle": "query.modified_move_speed <= 0.1" },
{ "sitting": "query.is_sitting" }
]
},
"sitting": {
"animations": ["sit"],
"transitions": [
{ "idle": "!query.is_sitting" },
{ "sleeping": "query.is_sitting && (query.day_light_level < 4)" }
]
},
"sleeping": {
"animations": ["sleep"],
"transitions": [
{ "idle": "!query.is_sitting" },
{ "sitting": "query.is_sitting && (query.day_light_level >= 4)" }
]
},
"flying": {
"animations": ["fly"],
"transitions": [
{ "idle": "query.is_on_ground && query.modified_move_speed <= 0.1" },
{ "walking": "query.is_on_ground && query.modified_move_speed > 0.1" }
]
}
}
},
"controller.animation.spark_dragon.mood": {
"initial_state": "content",
"states": {
"happy": {
"particle_effects": [
{ "effect": "mood_happy" }
],
"transitions": [
{ "content": "query.property('silverlabs:mood') == 1" },
{ "needy": "query.property('silverlabs:mood') == 0" }
]
},
"content": {
"transitions": [
{ "happy": "query.property('silverlabs:mood') == 2" },
{ "needy": "query.property('silverlabs:mood') == 0" }
]
},
"needy": {
"particle_effects": [
{ "effect": "mood_needy" }
],
"transitions": [
{ "happy": "query.property('silverlabs:mood') == 2" },
{ "content": "query.property('silverlabs:mood') == 1" }
]
}
}
}
}
}

View File

@@ -0,0 +1,58 @@
{
"format_version": "1.8.0",
"animations": {
"animation.dragon_egg.idle": {
"loop": true,
"animation_length": 4.0,
"bones": {
"egg": {
"position": {
"0.0": [0, 0, 0],
"2.0": [0, 0.3, 0],
"4.0": [0, 0, 0]
}
}
}
},
"animation.dragon_egg.wobble": {
"loop": true,
"animation_length": 2.0,
"bones": {
"egg": {
"rotation": {
"0.0": [0, 0, 0],
"0.5": [0, 0, 5],
"1.0": [0, 0, 0],
"1.5": [0, 0, -5],
"2.0": [0, 0, 0]
},
"position": {
"0.0": [0, 0, 0],
"1.0": [0, 0.2, 0],
"2.0": [0, 0, 0]
}
}
}
},
"animation.dragon_egg.shake": {
"loop": true,
"animation_length": 0.4,
"bones": {
"egg": {
"rotation": {
"0.0": [0, 0, -10],
"0.1": [0, 0, 10],
"0.2": [0, 0, -10],
"0.3": [0, 0, 10],
"0.4": [0, 0, -10]
},
"position": {
"0.0": [0, 0.5, 0],
"0.2": [0, 0, 0],
"0.4": [0, 0.5, 0]
}
}
}
}
}
}

View File

@@ -0,0 +1,18 @@
{
"format_version": "1.8.0",
"animations": {
"animation.dragon_gravestone.idle": {
"loop": true,
"animation_length": 4.0,
"bones": {
"stone": {
"scale": {
"0.0": [1, 1, 1],
"2.0": [1, 1.02, 1],
"4.0": [1, 1, 1]
}
}
}
}
}
}

View File

@@ -0,0 +1,246 @@
{
"format_version": "1.8.0",
"animations": {
"animation.spark_dragon.idle": {
"loop": true,
"animation_length": 2.0,
"bones": {
"wing_left": {
"rotation": {
"0.0": [0, 0, -5],
"1.0": [0, 0, -15],
"2.0": [0, 0, -5]
}
},
"wing_right": {
"rotation": {
"0.0": [0, 0, 5],
"1.0": [0, 0, 15],
"2.0": [0, 0, 5]
}
},
"body": {
"position": {
"0.0": [0, 0, 0],
"1.0": [0, 0.3, 0],
"2.0": [0, 0, 0]
}
},
"tail": {
"rotation": {
"0.0": [0, -5, 0],
"1.0": [0, 5, 0],
"2.0": [0, -5, 0]
}
}
}
},
"animation.spark_dragon.walk": {
"loop": true,
"animation_length": 0.8,
"bones": {
"leg_front_left": {
"rotation": {
"0.0": [20, 0, 0],
"0.2": [0, 0, 0],
"0.4": [-20, 0, 0],
"0.6": [0, 0, 0],
"0.8": [20, 0, 0]
}
},
"leg_front_right": {
"rotation": {
"0.0": [-20, 0, 0],
"0.2": [0, 0, 0],
"0.4": [20, 0, 0],
"0.6": [0, 0, 0],
"0.8": [-20, 0, 0]
}
},
"leg_back_left": {
"rotation": {
"0.0": [-20, 0, 0],
"0.2": [0, 0, 0],
"0.4": [20, 0, 0],
"0.6": [0, 0, 0],
"0.8": [-20, 0, 0]
}
},
"leg_back_right": {
"rotation": {
"0.0": [20, 0, 0],
"0.2": [0, 0, 0],
"0.4": [-20, 0, 0],
"0.6": [0, 0, 0],
"0.8": [20, 0, 0]
}
},
"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]
}
},
"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]
}
},
"tail": {
"rotation": {
"0.0": [0, -10, 0],
"0.4": [0, 10, 0],
"0.8": [0, -10, 0]
}
},
"body": {
"position": {
"0.0": [0, 0, 0],
"0.2": [0, 0.5, 0],
"0.4": [0, 0, 0],
"0.6": [0, 0.5, 0],
"0.8": [0, 0, 0]
}
}
}
},
"animation.spark_dragon.sit": {
"loop": true,
"animation_length": 2.0,
"bones": {
"body": {
"position": [0, -1.5, 0]
},
"leg_front_left": {
"rotation": [-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": [10, -30, 0],
"1.0": [10, -25, 0],
"2.0": [10, -30, 0]
}
}
}
},
"animation.spark_dragon.sleep": {
"loop": true,
"animation_length": 4.0,
"bones": {
"body": {
"position": [0, -2, 0],
"scale": {
"0.0": [1, 1, 1],
"2.0": [1, 1.04, 1],
"4.0": [1, 1, 1]
}
},
"head": {
"rotation": [20, 40, 10],
"position": [0, -1, 2]
},
"leg_front_left": {
"rotation": [-90, 0, 0]
},
"leg_front_right": {
"rotation": [-90, 0, 0]
},
"leg_back_left": {
"rotation": [-90, 30, 0]
},
"leg_back_right": {
"rotation": [-90, -30, 0]
},
"wing_left": {
"rotation": [30, 0, 10],
"position": [0, -1, 1]
},
"wing_right": {
"rotation": [30, 0, -10],
"position": [0, -1, 1]
},
"tail": {
"rotation": [20, -60, 0]
}
}
},
"animation.spark_dragon.fly": {
"loop": true,
"animation_length": 0.6,
"bones": {
"body": {
"rotation": [-15, 0, 0],
"position": {
"0.0": [0, 0, 0],
"0.3": [0, 0.4, 0],
"0.6": [0, 0, 0]
}
},
"wing_left": {
"rotation": {
"0.0": [-10, 0, -60],
"0.15": [10, 0, -10],
"0.3": [-10, 0, -60],
"0.45": [10, 0, -10],
"0.6": [-10, 0, -60]
}
},
"wing_right": {
"rotation": {
"0.0": [-10, 0, 60],
"0.15": [10, 0, 10],
"0.3": [-10, 0, 60],
"0.45": [10, 0, 10],
"0.6": [-10, 0, 60]
}
},
"leg_front_left": {
"rotation": [-45, 0, 0]
},
"leg_front_right": {
"rotation": [-45, 0, 0]
},
"leg_back_left": {
"rotation": [-60, 10, 0]
},
"leg_back_right": {
"rotation": [-60, -10, 0]
},
"tail": {
"rotation": {
"0.0": [15, -3, 0],
"0.3": [15, 3, 0],
"0.6": [15, -3, 0]
}
},
"head": {
"rotation": [10, 0, 0]
}
}
}
}
}

View File

@@ -0,0 +1,6 @@
{
"format_version": [1, 1, 0],
"silverlabs:dragon_basket": {
"sound": "wood"
}
}

View File

@@ -0,0 +1,33 @@
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "silverlabs:dragon_egg",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/dragon_egg"
},
"geometry": {
"default": "geometry.dragon_egg"
},
"render_controllers": [
"controller.render.dragon_egg"
],
"animations": {
"idle": "animation.dragon_egg.idle",
"wobble": "animation.dragon_egg.wobble",
"shake": "animation.dragon_egg.shake",
"controller": "controller.animation.dragon_egg"
},
"scripts": {
"animate": ["controller"]
},
"particle_effects": {
"flame": "minecraft:basic_flame_particle",
"smoke": "minecraft:basic_smoke_particle"
}
}
}
}

View File

@@ -0,0 +1,32 @@
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "silverlabs:dragon_gravestone",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/dragon_gravestone"
},
"geometry": {
"default": "geometry.dragon_gravestone"
},
"render_controllers": [
"controller.render.dragon_gravestone"
],
"animations": {
"idle": "animation.dragon_gravestone.idle",
"controller": "controller.animation.dragon_gravestone",
"beacon_controller": "controller.animation.dragon_gravestone.beacon"
},
"scripts": {
"animate": ["controller", "beacon_controller"]
},
"particle_effects": {
"memorial_glow": "minecraft:endrod",
"beacon_beam": "minecraft:endrod"
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "silverlabs:dragon_toy",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/dragon_toy"
},
"geometry": {
"default": "geometry.dragon_toy"
},
"render_controllers": [
"controller.render.dragon_toy"
]
}
}
}

View File

@@ -0,0 +1,42 @@
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "silverlabs:spark_dragon",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/spark_dragon"
},
"geometry": {
"default": "geometry.spark_dragon"
},
"render_controllers": [
"controller.render.spark_dragon"
],
"animations": {
"idle": "animation.spark_dragon.idle",
"walk": "animation.spark_dragon.walk",
"sit": "animation.spark_dragon.sit",
"sleep": "animation.spark_dragon.sleep",
"fly": "animation.spark_dragon.fly",
"controller": "controller.animation.spark_dragon",
"beacon_controller": "controller.animation.spark_dragon.beacon",
"mood_controller": "controller.animation.spark_dragon.mood"
},
"scripts": {
"animate": ["controller", "beacon_controller", "mood_controller"]
},
"particle_effects": {
"beacon_beam": "minecraft:endrod",
"mood_happy": "minecraft:villager_happy",
"mood_needy": "minecraft:large_smoke"
},
"spawn_egg": {
"base_color": "#7B2FBE",
"overlay_color": "#F5A623"
}
}
}
}

View File

@@ -0,0 +1,20 @@
{
"format_version": "1.10.0",
"minecraft:client_entity": {
"description": {
"identifier": "silverlabs:whistle_signal",
"materials": {
"default": "entity_alphatest"
},
"textures": {
"default": "textures/entity/dragon_toy"
},
"geometry": {
"default": "geometry.dragon_toy"
},
"render_controllers": [
"controller.render.dragon_toy"
]
}
}
}

View File

@@ -0,0 +1,23 @@
{
"format_version": 2,
"header": {
"name": "Pets 4 Jamie's STARS Resources",
"description": "Textures, models and animations for Pets 4 Jamie's STARS",
"uuid": "5f25d547-00bb-49ce-8be3-d86cd3941c9b",
"version": [1, 0, 0],
"min_engine_version": [1, 21, 0]
},
"modules": [
{
"type": "resources",
"uuid": "6adc20cd-25a5-4ca5-aa12-f5e43ee9ea22",
"version": [1, 0, 0]
}
],
"dependencies": [
{
"uuid": "7cf924ce-e246-4c8c-998c-f420edb26451",
"version": [1, 0, 0]
}
]
}

View File

@@ -0,0 +1,52 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.dragon_basket",
"texture_width": 16,
"texture_height": 16
},
"bones": [
{
"name": "basket",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-7, 0, -7],
"size": [14, 2, 14],
"uv": [0, 0],
"inflate": 0
},
{
"origin": [-7, 2, -7],
"size": [14, 3, 1],
"uv": [0, 0]
},
{
"origin": [-7, 2, 6],
"size": [14, 3, 1],
"uv": [0, 0]
},
{
"origin": [-7, 2, -6],
"size": [1, 3, 12],
"uv": [0, 0]
},
{
"origin": [6, 2, -6],
"size": [1, 3, 12],
"uv": [0, 0]
},
{
"origin": [-5, 1, -5],
"size": [10, 1, 10],
"uv": [0, 8],
"inflate": 0
}
]
}
]
}
]
}

View File

@@ -0,0 +1,53 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.dragon_egg",
"texture_width": 32,
"texture_height": 32,
"visible_bounds_width": 1.0,
"visible_bounds_height": 1.0,
"visible_bounds_offset": [0, 0.4, 0]
},
"bones": [
{
"name": "root",
"pivot": [0, 0, 0]
},
{
"name": "egg",
"parent": "root",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-2, 0, -2],
"size": [4, 2, 4],
"uv": [0, 18]
},
{
"origin": [-3, 2, -3],
"size": [6, 3, 6],
"uv": [0, 8]
},
{
"origin": [-2.5, 5, -2.5],
"size": [5, 3, 5],
"uv": [0, 0]
},
{
"origin": [-1.5, 8, -1.5],
"size": [3, 2, 3],
"uv": [18, 0]
},
{
"origin": [-0.5, 10, -0.5],
"size": [1, 1, 1],
"uv": [20, 8]
}
]
}
]
}
]
}

View File

@@ -0,0 +1,55 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.dragon_gravestone",
"texture_width": 32,
"texture_height": 32,
"visible_bounds_width": 1.0,
"visible_bounds_height": 1.5,
"visible_bounds_offset": [0, 0.5, 0]
},
"bones": [
{
"name": "root",
"pivot": [0, 0, 0]
},
{
"name": "base",
"parent": "root",
"pivot": [0, 0, 0],
"cubes": [
{
"origin": [-4, 0, -2],
"size": [8, 2, 4],
"uv": [0, 20]
}
]
},
{
"name": "stone",
"parent": "base",
"pivot": [0, 2, 0],
"cubes": [
{
"origin": [-3, 2, -1],
"size": [6, 8, 2],
"uv": [0, 0]
},
{
"origin": [-2, 10, -1],
"size": [4, 2, 2],
"uv": [0, 10]
},
{
"origin": [-1, 12, -1],
"size": [2, 1, 2],
"uv": [0, 14]
}
]
}
]
}
]
}

View File

@@ -0,0 +1,26 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.dragon_toy",
"texture_width": 16,
"texture_height": 16
},
"bones": [
{
"name": "body",
"pivot": [0, 2, 0],
"cubes": [
{
"origin": [-2, 0, -2],
"size": [4, 4, 4],
"uv": [0, 0],
"inflate": 0.5
}
]
}
]
}
]
}

View File

@@ -0,0 +1,149 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.spark_dragon",
"texture_width": 64,
"texture_height": 32,
"visible_bounds_width": 1.5,
"visible_bounds_height": 1.0,
"visible_bounds_offset": [0, 0.25, 0]
},
"bones": [
{
"name": "root",
"pivot": [0, 0, 0]
},
{
"name": "body",
"parent": "root",
"pivot": [0, 4, 0],
"cubes": [
{
"origin": [-3, 2, -4],
"size": [6, 5, 8],
"uv": [0, 0]
}
]
},
{
"name": "head",
"parent": "body",
"pivot": [0, 6, -4],
"cubes": [
{
"origin": [-2.5, 4.5, -9],
"size": [5, 5, 5],
"uv": [20, 0]
},
{
"origin": [-1.5, 4.5, -11],
"size": [3, 3, 2],
"uv": [40, 0]
},
{
"origin": [-0.5, 9.5, -8],
"size": [1, 2, 1],
"uv": [50, 0]
},
{
"origin": [0.5, 9.5, -7],
"size": [1, 2, 1],
"uv": [54, 0]
}
]
},
{
"name": "leg_front_left",
"parent": "body",
"pivot": [2, 2, -2],
"cubes": [
{
"origin": [1, 0, -3],
"size": [2, 3, 2],
"uv": [0, 13]
}
]
},
{
"name": "leg_front_right",
"parent": "body",
"pivot": [-2, 2, -2],
"cubes": [
{
"origin": [-3, 0, -3],
"size": [2, 3, 2],
"uv": [8, 13]
}
]
},
{
"name": "leg_back_left",
"parent": "body",
"pivot": [2, 2, 3],
"cubes": [
{
"origin": [1, 0, 2],
"size": [2, 3, 2],
"uv": [16, 13]
}
]
},
{
"name": "leg_back_right",
"parent": "body",
"pivot": [-2, 2, 3],
"cubes": [
{
"origin": [-3, 0, 2],
"size": [2, 3, 2],
"uv": [24, 13]
}
]
},
{
"name": "tail",
"parent": "body",
"pivot": [0, 4, 4],
"cubes": [
{
"origin": [-1, 3, 4],
"size": [2, 2, 6],
"uv": [32, 13]
},
{
"origin": [-0.5, 3.5, 10],
"size": [1, 1, 3],
"uv": [48, 13]
}
]
},
{
"name": "wing_left",
"parent": "body",
"pivot": [3, 7, 0],
"cubes": [
{
"origin": [3, 6.5, -2],
"size": [6, 0.5, 4],
"uv": [0, 19]
}
]
},
{
"name": "wing_right",
"parent": "body",
"pivot": [-3, 7, 0],
"cubes": [
{
"origin": [-9, 6.5, -2],
"size": [6, 0.5, 4],
"uv": [0, 24]
}
]
}
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

View File

@@ -0,0 +1,14 @@
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.dragon_egg": {
"geometry": "Geometry.default",
"materials": [
{
"*": "Material.default"
}
],
"textures": ["Texture.default"]
}
}
}

View File

@@ -0,0 +1,14 @@
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.dragon_gravestone": {
"geometry": "Geometry.default",
"materials": [
{
"*": "Material.default"
}
],
"textures": ["Texture.default"]
}
}
}

View File

@@ -0,0 +1,14 @@
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.dragon_toy": {
"geometry": "Geometry.default",
"materials": [
{
"*": "Material.default"
}
],
"textures": ["Texture.default"]
}
}
}

View File

@@ -0,0 +1,14 @@
{
"format_version": "1.8.0",
"render_controllers": {
"controller.render.spark_dragon": {
"geometry": "Geometry.default",
"materials": [
{
"*": "Material.default"
}
],
"textures": ["Texture.default"]
}
}
}

View File

@@ -0,0 +1,12 @@
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
item.silverlabs:dragon_egg.name=Spark Dragon Egg
entity.silverlabs:dragon_egg.name=Spark Dragon Egg
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

View File

@@ -0,0 +1,21 @@
{
"resource_pack_name": "spark_pet_RP",
"texture_name": "atlas.items",
"texture_data": {
"dragon_whistle": {
"textures": "textures/items/dragon_whistle"
},
"dragon_egg": {
"textures": "textures/items/dragon_egg"
},
"dragon_toy": {
"textures": "textures/items/dragon_toy"
},
"dragon_bones": {
"textures": "textures/items/dragon_bones"
},
"dragon_gravestone": {
"textures": "textures/items/dragon_gravestone"
},
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

View File

@@ -0,0 +1,11 @@
{
"resource_pack_name": "spark_pet",
"texture_name": "atlas.terrain",
"padding": 8,
"num_mip_levels": 4,
"texture_data": {
"dragon_basket": {
"textures": "textures/blocks/dragon_basket"
}
}
}

114
docker-compose.yml Normal file
View File

@@ -0,0 +1,114 @@
services:
lobby:
image: itzg/minecraft-bedrock-server
container_name: mc-lobby
environment:
EULA: "TRUE"
SERVER_NAME: "SilverLABS Hub"
GAMEMODE: adventure
DIFFICULTY: peaceful
ALLOW_CHEATS: "true"
ONLINE_MODE: "false"
SERVER_PORT: "19132"
LEVEL_NAME: "Hub World"
MAX_PLAYERS: "10"
DEFAULT_PLAYER_PERMISSION_LEVEL: operator
OP_PERMISSION_LEVEL: "4"
ports:
- "${LOBBY_PORT:-19132}:19132/udp"
volumes:
- lobby-data:/data
- ./lobby-addon/lobby_transfer_BP:/data/behavior_packs/lobby_transfer_BP
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
restart: unless-stopped
networks:
- mc-network
jamie:
image: itzg/minecraft-bedrock-server
container_name: mc-jamie
environment:
EULA: "TRUE"
SERVER_NAME: "Jamie's World"
GAMEMODE: survival
DIFFICULTY: normal
ALLOW_CHEATS: "true"
ONLINE_MODE: "false"
SERVER_PORT: "19132"
LEVEL_NAME: "Jamie World"
MAX_PLAYERS: "10"
DEFAULT_PLAYER_PERMISSION_LEVEL: operator
OP_PERMISSION_LEVEL: "4"
ports:
- "${JAMIE_PORT:-19133}:19132/udp"
volumes:
- jamie-data:/data
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
restart: unless-stopped
networks:
- mc-network
lyla:
image: itzg/minecraft-bedrock-server
container_name: mc-lyla
environment:
EULA: "TRUE"
SERVER_NAME: "Lyla's World"
GAMEMODE: survival
DIFFICULTY: normal
ALLOW_CHEATS: "true"
ONLINE_MODE: "false"
SERVER_PORT: "19132"
LEVEL_NAME: "Lyla World"
MAX_PLAYERS: "10"
DEFAULT_PLAYER_PERMISSION_LEVEL: operator
OP_PERMISSION_LEVEL: "4"
ports:
- "${LYLA_PORT:-19134}:19132/udp"
volumes:
- lyla-data:/data
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
restart: unless-stopped
networks:
- mc-network
mya:
image: itzg/minecraft-bedrock-server
container_name: mc-mya
environment:
EULA: "TRUE"
SERVER_NAME: "Mya's World"
GAMEMODE: survival
DIFFICULTY: normal
ALLOW_CHEATS: "true"
ONLINE_MODE: "false"
SERVER_PORT: "19132"
LEVEL_NAME: "Mya World"
MAX_PLAYERS: "10"
DEFAULT_PLAYER_PERMISSION_LEVEL: operator
OP_PERMISSION_LEVEL: "4"
ports:
- "${MYA_PORT:-19135}:19132/udp"
volumes:
- mya-data:/data
- ./hub-return-addon/hub_return_transfer_BP:/data/behavior_packs/hub_return_transfer_BP
- ./addon/spark_pet_BP:/data/behavior_packs/spark_pet_BP
- ./addon/spark_pet_RP:/data/resource_packs/spark_pet_RP
restart: unless-stopped
networks:
- mc-network
volumes:
lobby-data:
jamie-data:
lyla-data:
mya-data:
networks:
mc-network:
driver: bridge

View File

@@ -0,0 +1,25 @@
{
"format_version": 2,
"header": {
"name": "Hub Return Transfer",
"description": "Transfers players back to lobby when they step on the return portal",
"uuid": "b2c3d4e5-1111-2222-3333-fedcba654321",
"version": [1, 0, 1],
"min_engine_version": [1, 21, 0]
},
"modules": [
{
"type": "script",
"language": "javascript",
"uuid": "b2c3d4e5-4444-5555-6666-fedcba987654",
"version": [1, 0, 1],
"entry": "scripts/main.js"
}
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "2.0.0"
}
]
}

View File

@@ -0,0 +1,224 @@
import { world, system, ItemStack } from "@minecraft/server";
const LOBBY_HOST = "10.0.0.247";
const LOBBY_PORT = 19132;
const COMPASS_ID = "minecraft:recovery_compass";
const PORTAL_PROP = "hub_portal_location";
const PORTAL_RADIUS = 3;
const TRANSFER_COOLDOWN = 5000; // 5 seconds
// Track recently transferred players
const recentTransfers = new Map();
function doTransfer(player) {
const now = Date.now();
if (recentTransfers.has(player.name) && now - recentTransfers.get(player.name) < TRANSFER_COOLDOWN) {
player.sendMessage("§c[Hub] §fPlease wait a moment before transferring again.");
return;
}
recentTransfers.set(player.name, now);
world.sendMessage(`§a${player.name} is returning to the Hub...`);
try {
player.runCommand(`transfer "${player.name}" ${LOBBY_HOST} ${LOBBY_PORT}`);
} catch (e) {
world.sendMessage(`§cTransfer failed: ${e.message}`);
}
}
// ─── A. Compass Distribution ────────────────────────────────────
function giveCompassIfMissing(player) {
const inventory = player.getComponent("minecraft:inventory");
if (!inventory) return;
const container = inventory.container;
for (let i = 0; i < container.size; i++) {
const item = container.getItem(i);
if (item && item.typeId === COMPASS_ID) return; // already has one
}
container.addItem(new ItemStack(COMPASS_ID, 1));
player.sendMessage("§b[Hub] §fYou received a §dHub Compass§f — use it to return to the lobby!");
}
world.afterEvents.playerSpawn.subscribe((event) => {
const player = event.player;
// Small delay to let inventory load
system.runTimeout(() => {
try {
giveCompassIfMissing(player);
} catch (e) {
// Silently ignore — player may have disconnected
}
}, 20);
});
// ─── B. Compass Use Transfer ────────────────────────────────────
world.afterEvents.itemUse.subscribe((event) => {
const player = event.source;
const item = event.itemStack;
if (item.typeId !== COMPASS_ID) return;
doTransfer(player);
});
// ─── C. Portal Zone Detection ───────────────────────────────────
system.runInterval(() => {
const portalJson = world.getDynamicProperty(PORTAL_PROP);
if (!portalJson) return;
let portal;
try {
portal = JSON.parse(portalJson);
} catch {
return;
}
const now = Date.now();
const players = world.getAllPlayers();
for (const player of players) {
if (recentTransfers.has(player.name) && now - recentTransfers.get(player.name) < TRANSFER_COOLDOWN) {
continue;
}
const pos = player.location;
const dx = Math.abs(pos.x - portal.x);
const dy = Math.abs(pos.y - portal.y);
const dz = Math.abs(pos.z - portal.z);
if (dx <= PORTAL_RADIUS && dy <= 3 && dz <= PORTAL_RADIUS) {
doTransfer(player);
}
}
}, 20);
// ─── D. Chat Commands ───────────────────────────────────────────
function handleChatCommand(player, msg) {
if (msg === "!compass") {
try {
giveCompassIfMissing(player);
player.sendMessage("§b[Hub] §fCompass check complete.");
} catch (e) {
player.sendMessage(`§c[Hub] §fCouldn't give compass: ${e.message}`);
}
return true;
}
if (msg === "!setportal") {
const pos = player.location;
const loc = {
x: Math.floor(pos.x),
y: Math.floor(pos.y),
z: Math.floor(pos.z),
};
world.setDynamicProperty(PORTAL_PROP, JSON.stringify(loc));
buildPortal(loc, player.dimension);
player.sendMessage(`§b[Hub] §fReturn portal set at §d${loc.x}, ${loc.y}, ${loc.z}§f!`);
return true;
}
if (msg === "!hub" || msg === "!lobby") {
doTransfer(player);
return true;
}
return false;
}
// Try beforeEvents.chatSend (pre-release in some BDS versions)
try {
world.beforeEvents.chatSend.subscribe((event) => {
const msg = event.message.trim().toLowerCase();
if (msg.startsWith("!")) {
event.cancel = true;
const player = event.sender;
system.run(() => handleChatCommand(player, msg));
}
});
} catch {
// chatSend not available — fall back to polling player chat via scriptEvent
}
// Fallback: listen for scriptevent commands (players run: /scriptevent hub:cmd <command>)
system.afterEvents.scriptEventReceive.subscribe((event) => {
if (event.id !== "hub:cmd") return;
const player = event.sourceEntity;
if (!player) return;
const msg = (event.message || "").trim().toLowerCase();
handleChatCommand(player, `!${msg}`);
});
// ─── E. Portal Auto-Build on First Load ─────────────────────────
function buildPortal(loc, dimension) {
const x = loc.x;
const y = loc.y;
const z = loc.z;
const commands = [];
// Clear space for portal (3 wide, 5 tall, 1 deep)
commands.push(`fill ${x - 1} ${y} ${z} ${x + 1} ${y + 4} ${z} air`);
// Base row: 3 obsidian
commands.push(`setblock ${x - 1} ${y} ${z} obsidian`);
commands.push(`setblock ${x} ${y} ${z} obsidian`);
commands.push(`setblock ${x + 1} ${y} ${z} obsidian`);
// Left column: 3 crying obsidian
commands.push(`setblock ${x - 1} ${y + 1} ${z} crying_obsidian`);
commands.push(`setblock ${x - 1} ${y + 2} ${z} crying_obsidian`);
commands.push(`setblock ${x - 1} ${y + 3} ${z} crying_obsidian`);
// Right column: 3 crying obsidian
commands.push(`setblock ${x + 1} ${y + 1} ${z} crying_obsidian`);
commands.push(`setblock ${x + 1} ${y + 2} ${z} crying_obsidian`);
commands.push(`setblock ${x + 1} ${y + 3} ${z} crying_obsidian`);
// Center: 3 purple stained glass
commands.push(`setblock ${x} ${y + 1} ${z} stained_glass ["color":"purple"]`);
commands.push(`setblock ${x} ${y + 2} ${z} stained_glass ["color":"purple"]`);
commands.push(`setblock ${x} ${y + 3} ${z} stained_glass ["color":"purple"]`);
// Top: 1 obsidian cap
commands.push(`setblock ${x} ${y + 4} ${z} obsidian`);
for (const cmd of commands) {
try {
dimension.runCommand(cmd);
} catch (e) {
// Block placement may fail if chunks not loaded — non-fatal
}
}
}
system.runTimeout(() => {
const existing = world.getDynamicProperty(PORTAL_PROP);
if (existing) return; // Portal location already set
// Get spawn point and offset by 5 blocks on X
const spawn = world.getDefaultSpawnLocation();
const loc = {
x: spawn.x + 5,
y: spawn.y,
z: spawn.z,
};
world.setDynamicProperty(PORTAL_PROP, JSON.stringify(loc));
// Need a dimension reference — use overworld
const overworld = world.getDimension("overworld");
buildPortal(loc, overworld);
world.sendMessage("§b[Hub] §fReturn portal auto-built near spawn! Use §d!setportal§f to relocate it.");
}, 100);
system.run(() => {
world.sendMessage("§b[World] §fHub return system loaded! Use compass, step on portal, or type §d!hub§f to return.");
});

View File

@@ -0,0 +1,25 @@
{
"format_version": 2,
"header": {
"name": "Lobby Portal Transfer",
"description": "Auto-transfers players when they step into portal areas",
"uuid": "a1b2c3d4-1111-2222-3333-abcdef123456",
"version": [1, 0, 1],
"min_engine_version": [1, 21, 0]
},
"modules": [
{
"type": "script",
"language": "javascript",
"uuid": "a1b2c3d4-4444-5555-6666-abcdef789012",
"version": [1, 0, 1],
"entry": "scripts/main.js"
}
],
"dependencies": [
{
"module_name": "@minecraft/server",
"version": "2.0.0"
}
]
}

View File

@@ -0,0 +1,53 @@
import { world, system } from "@minecraft/server";
// Portal definitions: name, center position, and direct transfer target
const portals = [
{ name: "Jamie's World", x: -15, y: 65, z: -24, host: "10.0.0.247", port: 19133 },
{ name: "Lyla's World", x: 0, y: 65, z: -24, host: "10.0.0.247", port: 19134 },
{ name: "Mya's World", x: 15, y: 65, z: -24, host: "10.0.0.247", port: 19135 },
];
const PORTAL_RADIUS_X = 2.5;
const PORTAL_RADIUS_Z = 2.0;
const PORTAL_RADIUS_Y = 2.0;
const COOLDOWN_TICKS = 100; // 5 seconds cooldown
// Track cooldowns per player
const cooldowns = new Map();
system.runInterval(() => {
for (const player of world.getAllPlayers()) {
const pos = player.location;
const playerId = player.id;
// Check cooldown
const lastTransfer = cooldowns.get(playerId) || 0;
if (system.currentTick - lastTransfer < COOLDOWN_TICKS) continue;
for (const portal of portals) {
const dx = Math.abs(pos.x - portal.x);
const dy = Math.abs(pos.y - portal.y);
const dz = Math.abs(pos.z - portal.z);
if (dx < PORTAL_RADIUS_X && dy < PORTAL_RADIUS_Y && dz < PORTAL_RADIUS_Z) {
cooldowns.set(playerId, system.currentTick);
player.sendMessage(`§6Transferring to ${portal.name}...`);
try {
player.runCommand(`transfer "${player.name}" ${portal.host} ${portal.port}`);
} catch (e) {
player.sendMessage(`§cTransfer failed: ${e.message}`);
}
break;
}
}
}
}, 10); // Check every half second
// Clean up cooldowns when players leave
world.afterEvents.playerLeave.subscribe((event) => {
cooldowns.delete(event.playerId);
});
system.run(() => {
world.sendMessage("§6[Hub] §7Portal transfer system loaded!");
});