MDL Examples
This page contains working examples of MDL features.
Basic Hello World
A simple datapack that says hello when loaded:
pack "hello" "A simple hello world datapack" 82;
namespace "hello";
function "main" {
say Hello, Minecraft!;
tellraw @a {"text":"Welcome to my datapack!","color":"green"};
}
on_load "hello:main";
Counter with Scoped Variables
Demonstrates variables with different scopes:
pack "counter" "Counter example" 82;
namespace "counter";
var num globalCounter scope<global> = 0;
var num playerCounter = 0; // Defaults to player-specific scope
function "increment" {
globalCounter<global> = globalCounter<global> + 1;
playerCounter<@s> = playerCounter<@s> + 1;
say Global: $globalCounter$, Player: $playerCounter$;
}
function "show_all" {
function "counter:increment<@a>";
}
on_load "counter:increment";
While Loop Example
A countdown timer using a while loop:
pack "loops" "Loop example" 82;
namespace "loops";
var num counter scope<global> = 0;
function "countdown" {
counter<global> = 5;
while "$counter$ > 0" {
say Countdown: $counter$;
counter<global> = counter<global> - 1;
}
say Blast off!;
}
on_load "loops:countdown";
Raw Commands
Using raw Minecraft commands:
pack "raw" "Raw command example" 82;
namespace "raw";
function "custom" {
// Use raw Minecraft commands
effect give @s minecraft:speed 10 1;
particle minecraft:explosion ~ ~ ~ 1 1 1 0 10;
playsound minecraft:entity.player.levelup player @s ~ ~ ~ 1 1;
}
on_load "raw:custom";
Complete Game Example
A complete game with scoring, levels, and timers:
pack "game" "Complete game example" 82;
namespace "game";
// Variables
var num score = 0; // Defaults to player-specific scope
var num level = 1; // Defaults to player-specific scope
var num globalTimer scope<global> = 0;
// Main game function
function "start_game" {
score<@s> = 0;
level<@s> = 1;
say Game started! Level: $level$, Score: $score$;
}
// Level up function
function "level_up" {
if "$score$ >= 100" {
level<@s> = level<@s> + 1;
score<@s> = score<@s> - 100;
say Level up! New level: $level$;
tellraw @a {"text":"Player leveled up!","color":"gold"};
}
}
// Timer function
function "update_timer" {
globalTimer<global> = globalTimer<global> + 1;
if "$globalTimer$ >= 1200" { // 60 seconds
globalTimer<global> = 0;
say Time's up! Final score: $score$;
}
}
// Add score function
function "add_score" {
score<@s> = score<@s> + 10;
say Score: $score$;
function "game:level_up";
}
// Hooks
on_load "game:start_game";
on_tick "game:update_timer";
Team-Based System
A system that tracks team scores:
pack "teams" "Team system example" 82;
namespace "teams";
// Team variables
var num redScore scope<@a[team=red]> = 0;
var num blueScore scope<@a[team=blue]> = 0;
var num gameTimer scope<global> = 0;
// Initialize teams
function "init" {
redScore<@a[team=red]> = 0;
blueScore<@a[team=blue]> = 0;
gameTimer<global> = 0;
say Team game initialized!;
}
// Update game
function "update" {
gameTimer<global> = gameTimer<global> + 1;
if "$gameTimer$ >= 2400" { // 2 minutes
gameTimer<global> = 0;
say Game over! Red: $redScore$, Blue: $blueScore$;
if "$redScore$ > $blueScore$" {
tellraw @a {"text":"Red team wins!","color":"red"};
} else if "$blueScore$ > $redScore$" {
tellraw @a {"text":"Blue team wins!","color":"blue"};
} else {
tellraw @a {"text":"It's a tie!","color":"yellow"};
}
}
}
// Add points to red team
function "red_point" {
redScore<@a[team=red]> = redScore<@a[team=red]> + 1;
say Red team score: $redScore$;
}
// Add points to blue team
function "blue_point" {
blueScore<@a[team=blue]> = blueScore<@a[team=blue]> + 1;
say Blue team score: $blueScore$;
}
// Hooks
on_load "teams:init";
on_tick "teams:update";
Multi-File Example
Organizing code across multiple files:
main.mdl
(with pack declaration):
pack "multifile" "Multi-file example" 82;
namespace "core";
var num playerCount scope<global> = 0;
function "init" {
playerCount = 0;
say Core system initialized!;
}
on_load "core:init";
ui.mdl
(no pack declaration needed):
namespace "ui";
function "show_hud" {
tellraw @a {"text":"Players: $playerCount$","color":"green"};
}
function "update_hud" {
function "ui:show_hud<@a>";
}
game.mdl
(no pack declaration needed):
namespace "game";
function "start" {
say Game started!;
function "ui:update_hud";
}
Build all files together:
mdl build --mdl "main.mdl ui.mdl game.mdl" -o dist
Explicit Scopes in Conditions
Demonstrates how to use explicit scope selectors in if/while conditions to override declared variable scopes:
pack "scopes" "Explicit scope conditions example" 82;
namespace "scopes";
// Variables with different scopes
var num playerScore = 0; // Defaults to @s
var num globalCounter scope<global> = 0; // Global scope
var num teamScore scope<@a[team=red]> = 0; // Team scope
function "main" {
// Test explicit scope overrides in if conditions
if "$playerScore<@s>$ > 10" {
say "Current player score is high!";
}
if "$globalCounter<global>$ > 100" {
say "Global counter reached milestone!";
}
if "$teamScore<@a[team=red]>$ > 50" {
say "Red team is winning!";
}
// Check another player's score
if "$playerScore<@p[name=Steve]>$ > 5" {
say "Steve has a good score!";
}
// Check if any player has a high score
if "$playerScore<@a>$ > 20" {
say "Someone has a very high score!";
}
// Use explicit scopes in while loops too
while "$globalCounter<global>$ < 10" {
globalCounter<global> = globalCounter<global> + 1;
say "Counter: $globalCounter$";
}
}
// Function to test different scopes
function "test_scopes" {
// Set different values for different scopes
playerScore<@s> = 15; // Current player
globalCounter<global> = 150; // Global
teamScore<@a[team=red]> = 75; // Red team
// Test conditions with explicit scopes
if "$playerScore<@s>$ > 10" {
say "Player score check passed!";
}
if "$globalCounter<global>$ > 100" {
say "Global counter check passed!";
}
if "$teamScore<@a[team=red]>$ > 50" {
say "Team score check passed!";
}
}
on_load "scopes:main";
Key Features:
- Override declared scopes: Use
<@s>
,<global>
,<@a[team=red]>
in conditions - Check other entities: Compare scores across different players/teams
- Flexible conditions: Mix and match scopes as needed
- Clear intent: Explicit scope makes code more readable and debuggable