minecraft-datapack-language 15.4.27__py3-none-any.whl → 15.4.29__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- minecraft_datapack_language/__init__.py +17 -2
- minecraft_datapack_language/_version.py +2 -2
- minecraft_datapack_language/ast_nodes.py +87 -59
- minecraft_datapack_language/mdl_compiler.py +470 -0
- minecraft_datapack_language/mdl_errors.py +14 -0
- minecraft_datapack_language/mdl_lexer.py +624 -0
- minecraft_datapack_language/mdl_parser.py +573 -0
- minecraft_datapack_language-15.4.29.dist-info/METADATA +266 -0
- minecraft_datapack_language-15.4.29.dist-info/RECORD +16 -0
- minecraft_datapack_language/cli.py +0 -159
- minecraft_datapack_language/cli_build.py +0 -1292
- minecraft_datapack_language/cli_check.py +0 -155
- minecraft_datapack_language/cli_colors.py +0 -264
- minecraft_datapack_language/cli_help.py +0 -508
- minecraft_datapack_language/cli_new.py +0 -300
- minecraft_datapack_language/cli_utils.py +0 -276
- minecraft_datapack_language/expression_processor.py +0 -352
- minecraft_datapack_language/linter.py +0 -409
- minecraft_datapack_language/mdl_lexer_js.py +0 -754
- minecraft_datapack_language/mdl_parser_js.py +0 -1049
- minecraft_datapack_language/pack.py +0 -758
- minecraft_datapack_language-15.4.27.dist-info/METADATA +0 -1274
- minecraft_datapack_language-15.4.27.dist-info/RECORD +0 -25
- {minecraft_datapack_language-15.4.27.dist-info → minecraft_datapack_language-15.4.29.dist-info}/WHEEL +0 -0
- {minecraft_datapack_language-15.4.27.dist-info → minecraft_datapack_language-15.4.29.dist-info}/entry_points.txt +0 -0
- {minecraft_datapack_language-15.4.27.dist-info → minecraft_datapack_language-15.4.29.dist-info}/licenses/LICENSE +0 -0
- {minecraft_datapack_language-15.4.27.dist-info → minecraft_datapack_language-15.4.29.dist-info}/top_level.txt +0 -0
@@ -1,1274 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.4
|
2
|
-
Name: minecraft-datapack-language
|
3
|
-
Version: 15.4.27
|
4
|
-
Summary: Compile JavaScript-style MDL language or Python API into a Minecraft datapack (1.21+ ready). Features variables, control flow, error handling, and VS Code extension.
|
5
|
-
Project-URL: Homepage, https://www.mcmdl.com
|
6
|
-
Project-URL: Documentation, https://www.mcmdl.com/docs
|
7
|
-
Project-URL: Repository, https://github.com/aaron777collins/MinecraftDatapackLanguage
|
8
|
-
Project-URL: Bug Tracker, https://github.com/aaron777collins/MinecraftDatapackLanguage/issues
|
9
|
-
Project-URL: VS Code Extension, https://marketplace.visualstudio.com/items?itemName=mdl.minecraft-datapack-language
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: License :: OSI Approved :: MIT License
|
12
|
-
Classifier: Operating System :: OS Independent
|
13
|
-
Requires-Python: >=3.9
|
14
|
-
Description-Content-Type: text/markdown
|
15
|
-
License-File: LICENSE
|
16
|
-
Requires-Dist: mecha>=0.99.0
|
17
|
-
Provides-Extra: dev
|
18
|
-
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
19
|
-
Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
|
20
|
-
Dynamic: license-file
|
21
|
-
|
22
|
-
# <img src="https://github.com/aaron777collins/MinecraftDatapackLanguage/raw/main/icons/icon-128.png" width="32" height="32" alt="MDL Icon"> Minecraft Datapack Language (MDL)
|
23
|
-
|
24
|
-
A **modern JavaScript-style compiler** that lets you write Minecraft datapacks with **real control structures, variables, and expressions** that actually work.
|
25
|
-
|
26
|
-
📖 **[View Full Documentation](https://www.mcmdl.com/)** - Complete guides, examples, and API reference
|
27
|
-
📦 **[View on PyPI](https://pypi.org/project/minecraft-datapack-language/)** - Download and install from PyPI
|
28
|
-
🔧 **[VS Code Extension](https://marketplace.visualstudio.com/items?itemName=mdl.minecraft-datapack-language)** - Syntax highlighting, IntelliSense, and snippets
|
29
|
-
|
30
|
-

|
31
|
-

|
32
|
-

|
33
|
-

|
34
|
-

|
35
|
-
|
36
|
-
## 🎯 **MODERN** JavaScript-Style MDL Language
|
37
|
-
|
38
|
-
**MDL uses a modern JavaScript-style language format** with **real control structures, variables, and expressions**:
|
39
|
-
|
40
|
-
### ✨ **MODERN** Features
|
41
|
-
- **🎯 JavaScript-style syntax** with curly braces `{}` and semicolons `;`
|
42
|
-
- **📝 Modern comments** using `//` and `/* */`
|
43
|
-
- **🔢 Number variables** with `var num` type (stored in scoreboards)
|
44
|
-
- **🔄 Full control structures** including `if/else if/else`, `while` loops with method selection
|
45
|
-
- **💲 Variable substitution** with `$variable$` syntax
|
46
|
-
- **🧮 Expressions** with arithmetic operations (`+`, `-`, `*`, `/`)
|
47
|
-
- **📦 Namespace system** for modular code organization
|
48
|
-
- **🎨 VS Code extension** with full IntelliSense and snippets
|
49
|
-
- **🧪 Comprehensive testing** with E2E validation
|
50
|
-
- **📚 Extensive documentation** with examples for every feature
|
51
|
-
|
52
|
-
### 🏗️ Core Features
|
53
|
-
- ✅ **Modern pack format 82** by default for latest Minecraft features
|
54
|
-
- ✅ **JavaScript-style syntax** with curly braces and semicolons
|
55
|
-
- ✅ **Real control structures** - `if/else if/else`, `while` loops with recursion/schedule methods
|
56
|
-
- ✅ **Number variables** stored in scoreboards with `$variable$` substitution
|
57
|
-
- ✅ **Expressions** with arithmetic operations and variable substitution
|
58
|
-
- ✅ **Multi-file projects** with automatic merging and dependency resolution
|
59
|
-
- ✅ **Variable optimization** - automatic load function generation for initialization
|
60
|
-
- ✅ **Selector optimization** - proper `@a` usage for system commands
|
61
|
-
- ✅ **Easy hooks** into `minecraft:tick` and `minecraft:load` via function tags
|
62
|
-
- ✅ **Tag support** for `function`, `item`, `block`, `entity_type`, `fluid`, and `game_event`
|
63
|
-
|
64
|
-
> **Note**: Version 12.0+ uses **pack_format 82** by default for the modern JavaScript-style syntax.
|
65
|
-
|
66
|
-
---
|
67
|
-
|
68
|
-
## 🚀 Install
|
69
|
-
|
70
|
-
### Option A — from PyPI (recommended for users)
|
71
|
-
Global, isolated CLI via **pipx**:
|
72
|
-
```bash
|
73
|
-
python3 -m pip install --user pipx
|
74
|
-
python3 -m pipx ensurepath # reopen terminal
|
75
|
-
pipx install minecraft-datapack-language
|
76
|
-
|
77
|
-
mdl --help
|
78
|
-
```
|
79
|
-
|
80
|
-
Virtualenv (if you prefer):
|
81
|
-
```bash
|
82
|
-
python3 -m venv .venv
|
83
|
-
source .venv/bin/activate # Windows: .\.venv\Scripts\Activate.ps1
|
84
|
-
pip install minecraft-datapack-language
|
85
|
-
```
|
86
|
-
|
87
|
-
### Option B — from source (for contributors)
|
88
|
-
```bash
|
89
|
-
# inside the repo
|
90
|
-
python -m pip install -e .
|
91
|
-
```
|
92
|
-
|
93
|
-
---
|
94
|
-
|
95
|
-
## 🔄 Update
|
96
|
-
|
97
|
-
- **pipx**: `pipx upgrade minecraft-datapack-language`
|
98
|
-
- **pip (venv)**: `pip install -U minecraft-datapack-language`
|
99
|
-
- Pin a version: `pipx install "minecraft-datapack-language==<version>"` (replace `<version>` with desired version)
|
100
|
-
|
101
|
-
---
|
102
|
-
|
103
|
-
## 💻 CLI
|
104
|
-
|
105
|
-
### Modern JavaScript-style MDL (v15.0+)
|
106
|
-
```bash
|
107
|
-
# Build JavaScript-style MDL files
|
108
|
-
mdl build --mdl my_pack/mypack.mdl -o dist --wrapper mypack
|
109
|
-
mdl check my_pack/mypack.mdl
|
110
|
-
|
111
|
-
# Validate generated mcfunction files
|
112
|
-
mdl check my_pack/mypack.mdl
|
113
|
-
|
114
|
-
# Multi-file projects
|
115
|
-
mdl build --mdl my_pack/ -o dist # Build entire directory
|
116
|
-
mdl build --mdl "file1.mdl file2.mdl" -o dist # Build specific files
|
117
|
-
|
118
|
-
# Create new projects
|
119
|
-
mdl new my_awesome_pack
|
120
|
-
```
|
121
|
-
|
122
|
-
### 🐛 **Comprehensive Error Handling**
|
123
|
-
|
124
|
-
MDL provides detailed error reporting with exact locations and helpful suggestions:
|
125
|
-
|
126
|
-
```bash
|
127
|
-
# Check for errors with detailed output
|
128
|
-
mdl check my_pack.mdl --verbose
|
129
|
-
```
|
130
|
-
|
131
|
-
**Example Error Output:**
|
132
|
-
```
|
133
|
-
Error 1: MDLSyntaxError in test.mdl:15:8
|
134
|
-
Missing closing brace for if statement
|
135
|
-
Context:
|
136
|
-
13: if (score > 10) {
|
137
|
-
14: say "High score!"
|
138
|
-
15: score = 0
|
139
|
-
16: }
|
140
|
-
|
141
|
-
Suggestion: Add closing brace '}' after line 15
|
142
|
-
|
143
|
-
Error 2: MDLLexerError in test.mdl:22:12
|
144
|
-
Unterminated string literal
|
145
|
-
Context:
|
146
|
-
20: say "Hello world
|
147
|
-
21: score = 10
|
148
|
-
22: say "Goodbye
|
149
|
-
|
150
|
-
Suggestion: Add closing quote '"' at the end of line 20
|
151
|
-
```
|
152
|
-
|
153
|
-
**Error Features:**
|
154
|
-
- ✅ **Exact Location**: Line and column numbers for precise error location
|
155
|
-
- ✅ **Context Lines**: Shows surrounding code for better debugging
|
156
|
-
- ✅ **Helpful Suggestions**: Specific fix recommendations
|
157
|
-
- ✅ **Multiple Error Collection**: Reports all errors, not just the first
|
158
|
-
- ✅ **Error Types**: Syntax, Lexer, Parser, Validation, File, Build, and Configuration errors
|
159
|
-
|
160
|
-
### Comments in MDL
|
161
|
-
MDL supports modern JavaScript-style comments:
|
162
|
-
```javascript
|
163
|
-
// Single-line comments
|
164
|
-
/* Multi-line comments */
|
165
|
-
|
166
|
-
pack "My Pack" {
|
167
|
-
function example() {
|
168
|
-
// This comment will be properly converted to mcfunction
|
169
|
-
say Hello World!;
|
170
|
-
}
|
171
|
-
}
|
172
|
-
```
|
173
|
-
|
174
|
-
Generated mcfunction files will have proper `#` comments:
|
175
|
-
```mcfunction
|
176
|
-
# This is a generated comment
|
177
|
-
say Hello World!
|
178
|
-
```
|
179
|
-
|
180
|
-
### Build a whole folder of `.mdl` files
|
181
|
-
```bash
|
182
|
-
mdl build --mdl src/ -o dist
|
183
|
-
# Recursively parses src/**/*.mdl, merges into one pack (errors on duplicate functions).
|
184
|
-
# Only the first file should have a pack declaration - all others are modules.
|
185
|
-
```
|
186
|
-
|
187
|
-
### Build multiple specific `.mdl` files
|
188
|
-
```bash
|
189
|
-
mdl build --mdl "src/core.mdl src/features.mdl src/ui.mdl" -o dist
|
190
|
-
# Parses multiple specific files and merges them into one datapack.
|
191
|
-
# Only the first file should have a pack declaration - all others are modules.
|
192
|
-
```
|
193
|
-
|
194
|
-
### Validate a folder (JSON diagnostics)
|
195
|
-
```bash
|
196
|
-
mdl check --json src/
|
197
|
-
```
|
198
|
-
|
199
|
-
---
|
200
|
-
|
201
|
-
## 📝 Quick Start - **MODERN** MDL
|
202
|
-
|
203
|
-
Create your first modern MDL project:
|
204
|
-
|
205
|
-
```mdl
|
206
|
-
// modern_pack.mdl
|
207
|
-
pack "Modern Pack" description "A modern example" pack_format 82;
|
208
|
-
|
209
|
-
namespace "example";
|
210
|
-
|
211
|
-
// Number variables with expressions
|
212
|
-
var num counter = 0;
|
213
|
-
var num health = 20;
|
214
|
-
var num level = 1;
|
215
|
-
var num experience = 0;
|
216
|
-
|
217
|
-
function "init" {
|
218
|
-
say Initializing...;
|
219
|
-
counter = 0;
|
220
|
-
health = 20;
|
221
|
-
level = 1;
|
222
|
-
experience = 0;
|
223
|
-
}
|
224
|
-
|
225
|
-
function "tick" {
|
226
|
-
counter = counter + 1;
|
227
|
-
|
228
|
-
// Full if/else if/else control structure
|
229
|
-
if "$health$ < 10" {
|
230
|
-
say Health is low!;
|
231
|
-
health = health + 5;
|
232
|
-
effect give @a minecraft:regeneration 10 1;
|
233
|
-
} else if "$level$ > 5" {
|
234
|
-
say High level player!;
|
235
|
-
effect give @a minecraft:strength 10 1;
|
236
|
-
} else {
|
237
|
-
say Normal player;
|
238
|
-
effect give @a minecraft:speed 10 0;
|
239
|
-
}
|
240
|
-
|
241
|
-
// Variable substitution in strings
|
242
|
-
say Counter: $counter$;
|
243
|
-
|
244
|
-
// While loop with method selection
|
245
|
-
while "$counter$ < 10" {
|
246
|
-
counter = $counter$ + 1;
|
247
|
-
say Counter: $counter$;
|
248
|
-
}
|
249
|
-
|
250
|
-
// Expressions with arithmetic
|
251
|
-
experience = $level$ * 100 + $counter$;
|
252
|
-
say Experience: $experience$;
|
253
|
-
}
|
254
|
-
|
255
|
-
// Lifecycle hooks
|
256
|
-
on_load "example:init";
|
257
|
-
on_tick "example:tick";
|
258
|
-
```
|
259
|
-
|
260
|
-
Build and test:
|
261
|
-
```bash
|
262
|
-
mdl build --mdl modern_pack.mdl -o dist
|
263
|
-
# → dist/modern_pack/... and dist/modern_pack.zip
|
264
|
-
```
|
265
|
-
|
266
|
-
---
|
267
|
-
|
268
|
-
## 📁 Multi-file Support
|
269
|
-
|
270
|
-
MDL supports building datapacks from multiple `.mdl` files. This is useful for organizing large projects into logical modules.
|
271
|
-
|
272
|
-
### How it works
|
273
|
-
- **Directory scanning**: When you pass a directory to `--mdl`, MDL recursively finds all `.mdl` files
|
274
|
-
- **File merging**: Each file is parsed into a `Pack` object, then merged into a single datapack
|
275
|
-
- **Conflict resolution**: Duplicate function names within the same namespace will cause an error
|
276
|
-
- **Pack metadata**: Only the **first file** should have a pack declaration (name, description, format)
|
277
|
-
- **Module files**: Subsequent files should **not** have pack declarations - they are treated as modules
|
278
|
-
- **Single file compilation**: When compiling a single file, it **must** have a pack declaration
|
279
|
-
|
280
|
-
### Best practices
|
281
|
-
- **One pack declaration per project**: Only the **first file** should have a pack declaration
|
282
|
-
- **Module files**: All other files should **not** have pack declarations - they are treated as modules
|
283
|
-
- **Single file requirement**: When compiling a single file, it **must** have a pack declaration
|
284
|
-
- **Organize by namespace**: Consider splitting files by namespace or feature
|
285
|
-
- **Use descriptive filenames**: `core.mdl`, `combat.mdl`, `ui.mdl` etc.
|
286
|
-
- **Avoid conflicts**: Ensure function names are unique within each namespace
|
287
|
-
|
288
|
-
### Example project structure
|
289
|
-
```
|
290
|
-
my_datapack/
|
291
|
-
├── core.mdl # ✅ HAS pack declaration
|
292
|
-
├── combat/
|
293
|
-
│ ├── weapons.mdl # ❌ NO pack declaration (module)
|
294
|
-
│ └── armor.mdl # ❌ NO pack declaration (module)
|
295
|
-
├── ui/
|
296
|
-
│ └── hud.mdl # ❌ NO pack declaration (module)
|
297
|
-
└── data/
|
298
|
-
└── recipes.mdl # ❌ NO pack declaration (module)
|
299
|
-
```
|
300
|
-
|
301
|
-
**Important**: Only `core.mdl` should have a `pack "Name"` declaration. All other files are modules that merge into the main pack.
|
302
|
-
|
303
|
-
### Usage Examples
|
304
|
-
|
305
|
-
**Build from directory:**
|
306
|
-
```bash
|
307
|
-
mdl build --mdl my_datapack/ -o dist
|
308
|
-
```
|
309
|
-
|
310
|
-
**Build from specific files:**
|
311
|
-
```bash
|
312
|
-
mdl build --mdl "core.mdl combat.mdl ui.mdl" -o dist
|
313
|
-
```
|
314
|
-
|
315
|
-
**Check entire project:**
|
316
|
-
```bash
|
317
|
-
mdl check my_datapack/
|
318
|
-
```
|
319
|
-
|
320
|
-
**Check with verbose output:**
|
321
|
-
```bash
|
322
|
-
mdl build --mdl my_datapack/ -o dist --verbose
|
323
|
-
```
|
324
|
-
|
325
|
-
### Complete Multi-File Example
|
326
|
-
|
327
|
-
Here's a complete example showing how to organize a datapack across multiple files:
|
328
|
-
|
329
|
-
**`core.mdl`** (main file with pack declaration):
|
330
|
-
```mdl
|
331
|
-
// core.mdl - Main pack and core systems
|
332
|
-
pack "Adventure Pack" description "Multi-file example datapack" pack_format 82;
|
333
|
-
|
334
|
-
namespace "core";
|
335
|
-
|
336
|
-
// Number variables with expressions
|
337
|
-
var num system_version = 1;
|
338
|
-
var num player_count = 0;
|
339
|
-
var num total_experience = 0;
|
340
|
-
|
341
|
-
function "init" {
|
342
|
-
say [core:init] Initializing Adventure Pack...;
|
343
|
-
tellraw @a {"text":"Adventure Pack loaded!","color":"green"};
|
344
|
-
system_version = 1;
|
345
|
-
player_count = 0;
|
346
|
-
total_experience = 0;
|
347
|
-
}
|
348
|
-
|
349
|
-
function "tick" {
|
350
|
-
say [core:tick] Core systems running...;
|
351
|
-
execute as @a run particle minecraft:end_rod ~ ~ ~ 0.1 0.1 0.1 0.01 1;
|
352
|
-
player_count = player_count + 1;
|
353
|
-
|
354
|
-
// Control structure example
|
355
|
-
if "$player_count$ > 10" {
|
356
|
-
say Many players online!;
|
357
|
-
effect give @a minecraft:glowing 5 0;
|
358
|
-
}
|
359
|
-
}
|
360
|
-
|
361
|
-
// Hook into vanilla lifecycle
|
362
|
-
on_load "core:init";
|
363
|
-
on_tick "core:tick";
|
364
|
-
```
|
365
|
-
|
366
|
-
**`combat/weapons.mdl`** (combat module):
|
367
|
-
```mdl
|
368
|
-
// combat/weapons.mdl - Weapon-related functions
|
369
|
-
namespace "combat";
|
370
|
-
|
371
|
-
var num weapon_damage = 10;
|
372
|
-
var num critical_chance = 5;
|
373
|
-
|
374
|
-
function "weapon_effects" {
|
375
|
-
say [combat:weapon_effects] Applying weapon effects...;
|
376
|
-
execute as @a[nbt={SelectedItem:{id:'minecraft:diamond_sword'}}] run effect give @s minecraft:strength 1 0 true;
|
377
|
-
weapon_damage = weapon_damage + 2;
|
378
|
-
|
379
|
-
// Expression example
|
380
|
-
critical_chance = $weapon_damage$ / 2;
|
381
|
-
}
|
382
|
-
|
383
|
-
function "update_combat" {
|
384
|
-
function core:tick;
|
385
|
-
function combat:weapon_effects;
|
386
|
-
}
|
387
|
-
```
|
388
|
-
|
389
|
-
**`combat/armor.mdl`** (armor module):
|
390
|
-
```mdl
|
391
|
-
// combat/armor.mdl - Armor-related functions
|
392
|
-
namespace "combat";
|
393
|
-
|
394
|
-
var num armor_bonus = 5;
|
395
|
-
var num defense_rating = 0;
|
396
|
-
|
397
|
-
function "armor_bonus" {
|
398
|
-
say [combat:armor_bonus] Checking armor bonuses...;
|
399
|
-
execute as @a[nbt={Inventory:[{Slot:103b,id:"minecraft:diamond_helmet"}]}] run effect give @s minecraft:resistance 1 0 true;
|
400
|
-
armor_bonus = armor_bonus + 1;
|
401
|
-
|
402
|
-
// Expression with multiple variables
|
403
|
-
defense_rating = $armor_bonus$ * 2 + 10;
|
404
|
-
}
|
405
|
-
|
406
|
-
function "update_armor" {
|
407
|
-
function combat:armor_bonus;
|
408
|
-
}
|
409
|
-
```
|
410
|
-
|
411
|
-
**`ui/hud.mdl`** (UI module):
|
412
|
-
```mdl
|
413
|
-
// ui/hud.mdl - User interface functions
|
414
|
-
namespace "ui";
|
415
|
-
|
416
|
-
var num hud_version = 1;
|
417
|
-
var num display_counter = 0;
|
418
|
-
|
419
|
-
function "show_hud" {
|
420
|
-
say [ui:show_hud] Updating HUD...;
|
421
|
-
title @a actionbar {"text":"Adventure Pack Active","color":"gold"};
|
422
|
-
hud_version = hud_version + 1;
|
423
|
-
|
424
|
-
// While loop example
|
425
|
-
while "$display_counter$ < 5" {
|
426
|
-
display_counter = $display_counter$ + 1;
|
427
|
-
say HUD update: $display_counter$;
|
428
|
-
}
|
429
|
-
}
|
430
|
-
|
431
|
-
function "update_ui" {
|
432
|
-
function ui:show_hud;
|
433
|
-
function combat:update_combat;
|
434
|
-
function combat:update_armor;
|
435
|
-
}
|
436
|
-
```
|
437
|
-
|
438
|
-
**Project structure:**
|
439
|
-
```
|
440
|
-
adventure_pack/
|
441
|
-
├── core.mdl # ✅ HAS pack declaration
|
442
|
-
├── combat/
|
443
|
-
│ ├── weapons.mdl # ❌ NO pack declaration (module)
|
444
|
-
│ └── armor.mdl # ❌ NO pack declaration (module)
|
445
|
-
└── ui/
|
446
|
-
└── hud.mdl # ❌ NO pack declaration (module)
|
447
|
-
```
|
448
|
-
|
449
|
-
**Build the project:**
|
450
|
-
```bash
|
451
|
-
mdl build --mdl adventure_pack/ -o dist --verbose
|
452
|
-
```
|
453
|
-
|
454
|
-
This will create a datapack with:
|
455
|
-
- **Core systems** (initialization and tick functions)
|
456
|
-
- **Combat features** (weapon and armor effects)
|
457
|
-
- **UI elements** (HUD display)
|
458
|
-
- **Cross-module calls** (UI calls combat functions)
|
459
|
-
- **Variable optimization** (automatic load function generation)
|
460
|
-
|
461
|
-
### CLI Options for Multi-file Builds
|
462
|
-
|
463
|
-
- `--mdl <path>`: Path to `.mdl` file, directory, or space-separated file list
|
464
|
-
- `--src <path>`: Alias for `--mdl` (same functionality)
|
465
|
-
- `-o, --out <dir>`: Output directory for the built datapack
|
466
|
-
- `--wrapper <name>`: Custom wrapper folder/zip name (default: first namespace or pack name slug)
|
467
|
-
- `--pack-format <N>`: Minecraft pack format (default: 82 for modern syntax)
|
468
|
-
- `-v, --verbose`: Show detailed processing information including file merging
|
469
|
-
- `--py-module <path>`: Alternative: build from Python module with `create_pack()` function
|
470
|
-
|
471
|
-
### Error Handling
|
472
|
-
|
473
|
-
- **Missing pack declaration**: Single files must have a pack declaration
|
474
|
-
- **Duplicate pack declarations**: Only the first file in a multi-file project should have a pack declaration
|
475
|
-
- **Function conflicts**: Duplicate function names within the same namespace will cause an error
|
476
|
-
- **Clear error messages**: Errors include file paths and line numbers for easy debugging
|
477
|
-
|
478
|
-
---
|
479
|
-
|
480
|
-
## 🎯 **Explicit Scope System**
|
481
|
-
|
482
|
-
MDL features a powerful **explicit scope system** that makes variable access clear and unambiguous. Each variable access must specify its scope, eliminating hidden state and making code more readable.
|
483
|
-
|
484
|
-
### **Variable Declaration Scopes**
|
485
|
-
|
486
|
-
```mdl
|
487
|
-
// Player-specific variable (defaults to @s in execution context)
|
488
|
-
var num playerScore = 0;
|
489
|
-
|
490
|
-
// Server-wide variable (stored on server armor stand)
|
491
|
-
var num globalCounter scope<global> = 0;
|
492
|
-
|
493
|
-
// Team-specific variable
|
494
|
-
var num teamScore scope<@a[team=red]> = 0;
|
495
|
-
|
496
|
-
// Custom entity variable
|
497
|
-
var num entityData scope<@e[type=armor_stand,tag=special,limit=1]> = 0;
|
498
|
-
```
|
499
|
-
|
500
|
-
### **Variable Access with Explicit Scopes**
|
501
|
-
|
502
|
-
```mdl
|
503
|
-
// Each variable access must specify the scope
|
504
|
-
playerScore<@s> = 42; // Player scope
|
505
|
-
globalCounter<global> = 100; // Global scope
|
506
|
-
teamScore<@a[team=red]> = 5; // Team scope
|
507
|
-
entityData<@e[type=armor_stand,tag=special,limit=1]> = 10; // Custom entity
|
508
|
-
```
|
509
|
-
|
510
|
-
### **Explicit Scopes in Conditions**
|
511
|
-
|
512
|
-
**NEW!** MDL now supports explicit scope selectors in if/while conditions, allowing you to override declared variable scopes:
|
513
|
-
|
514
|
-
```mdl
|
515
|
-
function "check_scores" {
|
516
|
-
// Check current player's score
|
517
|
-
if "$playerScore<@s>$ > 10" {
|
518
|
-
say "Your score is high!";
|
519
|
-
}
|
520
|
-
|
521
|
-
// Check global counter
|
522
|
-
if "$globalCounter<global>$ > 100" {
|
523
|
-
say "Global milestone reached!";
|
524
|
-
}
|
525
|
-
|
526
|
-
// Check another player's score
|
527
|
-
if "$playerScore<@p[name=Steve]>$ > 20" {
|
528
|
-
say "Steve has a good score!";
|
529
|
-
}
|
530
|
-
|
531
|
-
// Check team score
|
532
|
-
if "$teamScore<@a[team=red]>$ > 50" {
|
533
|
-
say "Red team is winning!";
|
534
|
-
}
|
535
|
-
|
536
|
-
// Use explicit scopes in while loops too
|
537
|
-
while "$globalCounter<global>$ < 10" {
|
538
|
-
globalCounter<global> = globalCounter<global> + 1;
|
539
|
-
say "Counter: $globalCounter$";
|
540
|
-
}
|
541
|
-
}
|
542
|
-
```
|
543
|
-
|
544
|
-
**Benefits:**
|
545
|
-
- **Override declared scopes**: Use different scopes than what was declared
|
546
|
-
- **Check other entities**: Compare scores across different players/teams
|
547
|
-
- **Flexible conditions**: Mix and match scopes as needed
|
548
|
-
- **Clear intent**: Explicit scope makes code more readable and debuggable
|
549
|
-
|
550
|
-
### **Scope Mapping**
|
551
|
-
|
552
|
-
MDL maps scopes to Minecraft selectors:
|
553
|
-
|
554
|
-
| MDL Scope | Minecraft Selector | Description |
|
555
|
-
|-----------|-------------------|-------------|
|
556
|
-
| `scope<global>` | `@e[type=armor_stand,tag=mdl_server,limit=1]` | Server-wide storage |
|
557
|
-
| `scope<@s>` | `@s` | Current player |
|
558
|
-
| `scope<@a>` | `@a` | All players |
|
559
|
-
| `scope<@a[team=red]>` | `@a[team=red]` | Red team players |
|
560
|
-
| `scope<@e[type=armor_stand,tag=something,limit=1]>` | `@e[type=armor_stand,tag=something,limit=1]` | Custom entity |
|
561
|
-
|
562
|
-
---
|
563
|
-
|
564
|
-
## 🎯 **Advanced Multi-File Examples with Namespaces**
|
565
|
-
|
566
|
-
### **Modern Namespace System**
|
567
|
-
|
568
|
-
MDL's namespace system allows you to organize code across multiple files with proper separation:
|
569
|
-
|
570
|
-
**`game.mdl`** - Core Game Logic:
|
571
|
-
```mdl
|
572
|
-
pack "multi_game" "A multi-file game example" 82;
|
573
|
-
|
574
|
-
namespace "game";
|
575
|
-
|
576
|
-
var num player_score = 0;
|
577
|
-
var num game_timer = 0;
|
578
|
-
var num health = 20;
|
579
|
-
|
580
|
-
function "main" {
|
581
|
-
// If-else if-else chain
|
582
|
-
if "$health$ < 10" {
|
583
|
-
say "Health is low: $health$";
|
584
|
-
health = $health$ + 5;
|
585
|
-
} else if "$health$ > 15" {
|
586
|
-
say "Health is good: $health$";
|
587
|
-
} else {
|
588
|
-
say "Health is moderate: $health$";
|
589
|
-
}
|
590
|
-
|
591
|
-
// While loop with counter
|
592
|
-
while "$game_timer$ < 5" {
|
593
|
-
game_timer = $game_timer$ + 1;
|
594
|
-
say "Game Timer: $game_timer$";
|
595
|
-
}
|
596
|
-
}
|
597
|
-
|
598
|
-
function "score_update" {
|
599
|
-
player_score = $player_score$ + 10;
|
600
|
-
say "Score updated: $player_score$";
|
601
|
-
}
|
602
|
-
|
603
|
-
on_tick "game:main";
|
604
|
-
```
|
605
|
-
|
606
|
-
**`ui.mdl`** - User Interface:
|
607
|
-
```mdl
|
608
|
-
namespace "ui";
|
609
|
-
|
610
|
-
var num menu_state = 0;
|
611
|
-
var num selected_option = 1;
|
612
|
-
|
613
|
-
function "main" {
|
614
|
-
// Show menu based on state
|
615
|
-
if "$menu_state$ == 0" {
|
616
|
-
say "=== Main Menu ===";
|
617
|
-
say "1. Start Game";
|
618
|
-
say "2. Options";
|
619
|
-
say "3. Exit";
|
620
|
-
}
|
621
|
-
|
622
|
-
// Handle selection
|
623
|
-
if "$selected_option$ == 1" {
|
624
|
-
say "Starting game...";
|
625
|
-
} else if "$selected_option$ == 2" {
|
626
|
-
say "Opening options...";
|
627
|
-
} else if "$selected_option$ == 3" {
|
628
|
-
say "Exiting...";
|
629
|
-
}
|
630
|
-
}
|
631
|
-
|
632
|
-
function "button_handler" {
|
633
|
-
var num button_id = 0;
|
634
|
-
|
635
|
-
if "$button_id$ == 1" {
|
636
|
-
selected_option = 1;
|
637
|
-
say "Option 1 selected";
|
638
|
-
} else if "$button_id$ == 2" {
|
639
|
-
selected_option = 2;
|
640
|
-
say "Option 2 selected";
|
641
|
-
}
|
642
|
-
}
|
643
|
-
|
644
|
-
on_load "ui:main";
|
645
|
-
```
|
646
|
-
|
647
|
-
**`combat.mdl`** - Combat System:
|
648
|
-
```mdl
|
649
|
-
namespace "combat";
|
650
|
-
|
651
|
-
var num enemy_count = 5;
|
652
|
-
var num damage = 0;
|
653
|
-
|
654
|
-
function "main" {
|
655
|
-
var num total_damage = 0;
|
656
|
-
total_damage = $damage$ * 2;
|
657
|
-
|
658
|
-
if "$total_damage$ > 20" {
|
659
|
-
say "Critical hit! Damage: $total_damage$";
|
660
|
-
} else {
|
661
|
-
say "Normal hit. Damage: $total_damage$";
|
662
|
-
}
|
663
|
-
|
664
|
-
// Variable substitution in tellraw
|
665
|
-
tellraw @a [{"text":"Enemy Count: "},{"score":{"name":"@a","objective":"enemy_count"}}];
|
666
|
-
}
|
667
|
-
|
668
|
-
on_tick "combat:main";
|
669
|
-
```
|
670
|
-
|
671
|
-
### **Build and Generated Structure**
|
672
|
-
|
673
|
-
```bash
|
674
|
-
# Build all files together
|
675
|
-
mdl build --mdl . -o dist
|
676
|
-
|
677
|
-
# Or build specific files
|
678
|
-
mdl build --mdl "game.mdl ui.mdl combat.mdl" -o dist
|
679
|
-
```
|
680
|
-
|
681
|
-
**Generated Structure:**
|
682
|
-
```
|
683
|
-
dist/
|
684
|
-
├── data/
|
685
|
-
│ ├── minecraft/tags/function/
|
686
|
-
│ │ ├── load.json # Contains all load functions
|
687
|
-
│ │ └── tick.json # Contains all tick functions
|
688
|
-
│ ├── game/ # game.mdl namespace
|
689
|
-
│ │ └── function/
|
690
|
-
│ │ ├── main.mcfunction
|
691
|
-
│ │ └── score_update.mcfunction
|
692
|
-
│ ├── ui/ # ui.mdl namespace
|
693
|
-
│ │ └── function/
|
694
|
-
│ │ ├── main.mcfunction
|
695
|
-
│ │ └── button_handler.mcfunction
|
696
|
-
│ └── combat/ # combat.mdl namespace
|
697
|
-
│ └── function/
|
698
|
-
│ └── main.mcfunction
|
699
|
-
└── pack.mcmeta
|
700
|
-
```
|
701
|
-
|
702
|
-
### **Key Benefits of Namespace System**
|
703
|
-
|
704
|
-
- ✅ **No function name conflicts** - Each namespace is completely separate
|
705
|
-
- ✅ **Modular development** - Work on different features in separate files
|
706
|
-
- ✅ **Automatic merging** - All variables and functions are combined intelligently
|
707
|
-
- ✅ **Proper initialization** - Variables are automatically set up in load functions
|
708
|
-
- ✅ **Clean organization** - Each module has its own directory structure
|
709
|
-
- ✅ **Easy maintenance** - Update individual modules without affecting others
|
710
|
-
|
711
|
-
### **Complete Example Project**
|
712
|
-
|
713
|
-
Check out the `examples/multi_file_example/` directory for a complete working example with:
|
714
|
-
- Multiple namespaces (`test`, `other`, `ui`)
|
715
|
-
- Various control structures and expressions
|
716
|
-
- Comprehensive documentation
|
717
|
-
- Ready-to-build files
|
718
|
-
|
719
|
-
---
|
720
|
-
|
721
|
-
## 📝 The **MODERN** `.mdl` Language
|
722
|
-
|
723
|
-
### Grammar you can rely on (based on the parser)
|
724
|
-
- **pack header** (required once):
|
725
|
-
```mdl
|
726
|
-
pack "Name" [description "Desc"] [pack_format N];
|
727
|
-
```
|
728
|
-
- **namespace** (selects a namespace for following blocks):
|
729
|
-
```mdl
|
730
|
-
namespace "example";
|
731
|
-
```
|
732
|
-
- **number variable declarations** (only `num` type supported):
|
733
|
-
```mdl
|
734
|
-
var num counter = 0;
|
735
|
-
var num health = 20;
|
736
|
-
var num level = 1;
|
737
|
-
```
|
738
|
-
- **function** (curly braces + semicolons):
|
739
|
-
```mdl
|
740
|
-
function "hello" {
|
741
|
-
say hi;
|
742
|
-
tellraw @a {"text":"ok","color":"green"};
|
743
|
-
}
|
744
|
-
```
|
745
|
-
- **full conditional blocks** (if/else if/else statements):
|
746
|
-
```mdl
|
747
|
-
function "conditional" {
|
748
|
-
if "$health$ < 10" {
|
749
|
-
say Health is low!;
|
750
|
-
effect give @s minecraft:glowing 5 1;
|
751
|
-
} else if "$level$ > 5" {
|
752
|
-
say High level player!;
|
753
|
-
effect give @s minecraft:speed 5 1;
|
754
|
-
} else {
|
755
|
-
say Normal player;
|
756
|
-
effect give @s minecraft:jump_boost 5 0;
|
757
|
-
}
|
758
|
-
}
|
759
|
-
```
|
760
|
-
- **while loops** (repetitive execution with method selection):
|
761
|
-
```mdl
|
762
|
-
function "countdown" {
|
763
|
-
var num counter = 5;
|
764
|
-
while "$counter$ > 0" {
|
765
|
-
say Counter: $counter$;
|
766
|
-
counter = counter - 1;
|
767
|
-
}
|
768
|
-
|
769
|
-
// Schedule method for performance
|
770
|
-
counter = 10;
|
771
|
-
while "$counter$ > 0" method="schedule" {
|
772
|
-
say Schedule counter: $counter$;
|
773
|
-
counter = $counter$ - 1;
|
774
|
-
}
|
775
|
-
}
|
776
|
-
```
|
777
|
-
- **expressions** (arithmetic operations):
|
778
|
-
```mdl
|
779
|
-
function "expressions" {
|
780
|
-
var num a = 10;
|
781
|
-
var num b = 5;
|
782
|
-
var num result = $a$ + $b$ * 2;
|
783
|
-
say Result: $result$;
|
784
|
-
}
|
785
|
-
```
|
786
|
-
- **function calls** (one function invoking another with fully qualified ID):
|
787
|
-
```mdl
|
788
|
-
function "outer" {
|
789
|
-
say I will call another function;
|
790
|
-
function example:hello;
|
791
|
-
}
|
792
|
-
```
|
793
|
-
- **hooks** (namespaced ids required):
|
794
|
-
```mdl
|
795
|
-
on_load "example:hello";
|
796
|
-
on_tick "example:hello";
|
797
|
-
```
|
798
|
-
- **tags** (supported registries: `function`, `item`, `block`, `entity_type`, `fluid`, `game_event`):
|
799
|
-
```mdl
|
800
|
-
tag function "minecraft:tick" {
|
801
|
-
add "example:hello";
|
802
|
-
}
|
803
|
-
```
|
804
|
-
- **comments** start with `//` or `/* */`. Hashes inside **quoted strings** are preserved.
|
805
|
-
- **whitespace**: empty lines are ignored; **explicit block boundaries** using curly braces `{` and `}`; **statement termination** using semicolons `;`.
|
806
|
-
|
807
|
-
> Inside a function block, **every non-empty line** is emitted almost verbatim as a Minecraft command. Comments are stripped out and multi-line commands are automatically wrapped. See below for details.
|
808
|
-
|
809
|
-
### Comments
|
810
|
-
|
811
|
-
MDL supports modern JavaScript-style comments:
|
812
|
-
|
813
|
-
- **Full-line comments** (a line starting with `//`) are ignored by the parser.
|
814
|
-
- **Block comments** (`/* */`) are supported for multi-line comments.
|
815
|
-
- **Inline `#` characters** are preserved inside function bodies, so you can still use them the way `mcfunction` normally allows.
|
816
|
-
|
817
|
-
Example:
|
818
|
-
|
819
|
-
```mdl
|
820
|
-
// Comment Demo - Testing comments
|
821
|
-
pack "Comment Demo" description "Testing comments";
|
822
|
-
|
823
|
-
namespace "demo";
|
824
|
-
|
825
|
-
function "comments" {
|
826
|
-
// This whole line is ignored by MDL
|
827
|
-
say Hello; // This inline comment is preserved
|
828
|
-
tellraw @a {"text":"World","color":"blue"}; // Inline too!
|
829
|
-
|
830
|
-
/* This is a block comment
|
831
|
-
that spans multiple lines
|
832
|
-
and is ignored by the parser */
|
833
|
-
}
|
834
|
-
```
|
835
|
-
|
836
|
-
When compiled, the resulting function looks like:
|
837
|
-
|
838
|
-
```mcfunction
|
839
|
-
say Hello # This inline comment is preserved
|
840
|
-
tellraw @a {"text":"World","color":"blue"} # Inline too!
|
841
|
-
```
|
842
|
-
|
843
|
-
Notice how the full-line `//` and block comments never make it into the `.mcfunction`, but the inline ones do.
|
844
|
-
|
845
|
-
---
|
846
|
-
|
847
|
-
### **MODERN** Variables and Data Types
|
848
|
-
|
849
|
-
MDL supports **number variables** with **expressions and arithmetic operations**:
|
850
|
-
|
851
|
-
#### Number Variables (`num`)
|
852
|
-
```mdl
|
853
|
-
var num counter = 0;
|
854
|
-
var num health = 20;
|
855
|
-
var num experience = 100;
|
856
|
-
|
857
|
-
// Arithmetic operations
|
858
|
-
counter = counter + 1;
|
859
|
-
health = health - 5;
|
860
|
-
experience = experience * 2;
|
861
|
-
|
862
|
-
// Expressions with multiple variables
|
863
|
-
var num total = $health$ + $experience$;
|
864
|
-
var num average = $total$ / 2;
|
865
|
-
|
866
|
-
// Variable substitution in strings
|
867
|
-
say Health: $health$;
|
868
|
-
say Experience: $experience$;
|
869
|
-
say Total: $total$;
|
870
|
-
```
|
871
|
-
|
872
|
-
**Variable Substitution**: Use `$variable_name$` to read values from scoreboards in strings and conditions.
|
873
|
-
|
874
|
-
**Expressions**: Support for arithmetic operations (`+`, `-`, `*`, `/`) with proper order of operations.
|
875
|
-
|
876
|
-
### **MODERN** Control Flow
|
877
|
-
|
878
|
-
MDL supports full conditional blocks and loops for control flow.
|
879
|
-
|
880
|
-
#### Conditional Blocks
|
881
|
-
|
882
|
-
MDL supports complete if/else if/else statements for conditional execution:
|
883
|
-
|
884
|
-
```mdl
|
885
|
-
function "conditional_example" {
|
886
|
-
var num player_level = 15;
|
887
|
-
var num player_health = 8;
|
888
|
-
var num player_experience = 1000;
|
889
|
-
|
890
|
-
if "$player_level$ >= 10" {
|
891
|
-
if "$player_health$ < 10" {
|
892
|
-
say Advanced player with low health!;
|
893
|
-
effect give @s minecraft:regeneration 10 1;
|
894
|
-
player_health = $player_health$ + 10;
|
895
|
-
} else {
|
896
|
-
say Advanced player with good health;
|
897
|
-
effect give @s minecraft:strength 10 1;
|
898
|
-
}
|
899
|
-
} else if "$player_level$ >= 5" {
|
900
|
-
say Intermediate player;
|
901
|
-
effect give @s minecraft:speed 10 0;
|
902
|
-
} else {
|
903
|
-
say Beginner player;
|
904
|
-
effect give @s minecraft:jump_boost 10 0;
|
905
|
-
}
|
906
|
-
|
907
|
-
// Expression in condition
|
908
|
-
if "$player_experience$ > $player_level$ * 100" {
|
909
|
-
say High experience for level!;
|
910
|
-
}
|
911
|
-
}
|
912
|
-
```
|
913
|
-
|
914
|
-
**Rules:**
|
915
|
-
- Conditions use `$variable$` syntax for variable substitution
|
916
|
-
- **Explicit block boundaries**: Conditional blocks use curly braces `{` and `}`
|
917
|
-
- **Statement termination**: All commands must end with semicolons `;`
|
918
|
-
- You can have multiple `else if` blocks
|
919
|
-
- The `else` block is optional
|
920
|
-
- Conditional blocks are compiled to separate functions and called with `execute` commands
|
921
|
-
- **Proper logic**: `else if` blocks only execute if previous conditions were false
|
922
|
-
- **Expressions in conditions**: Support for arithmetic operations in conditions
|
923
|
-
|
924
|
-
#### While Loops
|
925
|
-
|
926
|
-
MDL supports while loops with method selection for repetitive execution:
|
927
|
-
|
928
|
-
```mdl
|
929
|
-
function "while_example" {
|
930
|
-
var num counter = 5;
|
931
|
-
|
932
|
-
// Default recursion method (immediate execution)
|
933
|
-
while "$counter$ > 0" {
|
934
|
-
say "Counter: $counter$";
|
935
|
-
counter = $counter$ - 1;
|
936
|
-
}
|
937
|
-
|
938
|
-
// Schedule method (spreads across ticks for performance)
|
939
|
-
counter = 10;
|
940
|
-
while "$counter$ > 0" method="schedule" {
|
941
|
-
say "Schedule counter: $counter$";
|
942
|
-
counter = $counter$ - 1;
|
943
|
-
}
|
944
|
-
|
945
|
-
// Expression in loop condition
|
946
|
-
var num max_count = 5;
|
947
|
-
counter = 0;
|
948
|
-
while "$counter$ < $max_count$ * 2" {
|
949
|
-
say "Expression counter: $counter$";
|
950
|
-
counter = $counter$ + 1;
|
951
|
-
}
|
952
|
-
}
|
953
|
-
```
|
954
|
-
|
955
|
-
**Rules:**
|
956
|
-
- Conditions use `$variable$` syntax for variable substitution
|
957
|
-
- **Explicit block boundaries**: While loops use curly braces `{` and `}`
|
958
|
-
- **Statement termination**: All commands must end with semicolons `;`
|
959
|
-
- While loops continue until the condition becomes false
|
960
|
-
- **Method Selection**: Choose `method="recursion"` (default) or `method="schedule"`
|
961
|
-
- **Recursion method**: Executes all iterations immediately (good for small loops)
|
962
|
-
- **Schedule method**: Spreads iterations across ticks (better for long loops, prevents lag)
|
963
|
-
- **Important**: Ensure your loop body modifies the condition to avoid infinite loops
|
964
|
-
- **Expressions in conditions**: Support for arithmetic operations in loop conditions
|
965
|
-
|
966
|
-
**Implementation**: While loops generate separate function files with proper recursive calls to continue execution until the condition becomes false.
|
967
|
-
|
968
|
-
---
|
969
|
-
|
970
|
-
### Multi-line Commands
|
971
|
-
|
972
|
-
Long JSON commands can be split across multiple lines with a trailing backslash `\`.
|
973
|
-
MDL will join them back together before writing the final `.mcfunction`.
|
974
|
-
|
975
|
-
Example:
|
976
|
-
|
977
|
-
```mdl
|
978
|
-
// Multi-line Demo
|
979
|
-
pack "Multi-line Demo";
|
980
|
-
|
981
|
-
namespace "demo";
|
982
|
-
|
983
|
-
function "multiline" {
|
984
|
-
tellraw @a \
|
985
|
-
{"text":"This text is really, really long so we split it",\
|
986
|
-
"color":"gold"};
|
987
|
-
}
|
988
|
-
```
|
989
|
-
|
990
|
-
When compiled, the function is a single line:
|
991
|
-
|
992
|
-
```mcfunction
|
993
|
-
tellraw @a {"text":"This text is really, really long so we split it","color":"gold"}
|
994
|
-
```
|
995
|
-
|
996
|
-
---
|
997
|
-
|
998
|
-
## 🎯 **MODERN** example (control structures + variables + expressions)
|
999
|
-
|
1000
|
-
```mdl
|
1001
|
-
// modern_pack.mdl - modern example for Minecraft Datapack Language
|
1002
|
-
pack "Modern Pack" description "Modern example datapack" pack_format 82;
|
1003
|
-
|
1004
|
-
namespace "example";
|
1005
|
-
|
1006
|
-
// Number variables with expressions
|
1007
|
-
var num counter = 0;
|
1008
|
-
var num health = 20;
|
1009
|
-
var num level = 1;
|
1010
|
-
var num experience = 0;
|
1011
|
-
|
1012
|
-
function "inner" {
|
1013
|
-
say [example:inner] This is the inner function;
|
1014
|
-
tellraw @a {"text":"Running inner","color":"yellow"};
|
1015
|
-
counter = counter + 1;
|
1016
|
-
}
|
1017
|
-
|
1018
|
-
function "hello" {
|
1019
|
-
say [example:hello] Outer says hi;
|
1020
|
-
function example:inner;
|
1021
|
-
tellraw @a {"text":"Back in hello","color":"aqua"};
|
1022
|
-
|
1023
|
-
// Variable operations with expressions
|
1024
|
-
health = health + 5;
|
1025
|
-
level = level + 1;
|
1026
|
-
experience = $level$ * 100 + $counter$;
|
1027
|
-
|
1028
|
-
// Variable substitution
|
1029
|
-
say Health: $health$;
|
1030
|
-
say Level: $level$;
|
1031
|
-
say Experience: $experience$;
|
1032
|
-
|
1033
|
-
// Full control structures
|
1034
|
-
if "$health$ > 15" {
|
1035
|
-
say High health!;
|
1036
|
-
effect give @s minecraft:strength 10 1;
|
1037
|
-
} else if "$level$ > 5" {
|
1038
|
-
say High level!;
|
1039
|
-
effect give @s minecraft:speed 10 1;
|
1040
|
-
} else {
|
1041
|
-
say Normal stats;
|
1042
|
-
effect give @s minecraft:jump_boost 10 0;
|
1043
|
-
}
|
1044
|
-
|
1045
|
-
// While loop with method selection
|
1046
|
-
while "$counter$ < 5" {
|
1047
|
-
say Counter: $counter$;
|
1048
|
-
counter = counter + 1;
|
1049
|
-
}
|
1050
|
-
|
1051
|
-
// Expression in condition
|
1052
|
-
if "$experience$ > $level$ * 50" {
|
1053
|
-
say High experience for level!;
|
1054
|
-
}
|
1055
|
-
}
|
1056
|
-
|
1057
|
-
// Hook the function into load and tick
|
1058
|
-
on_load "example:hello";
|
1059
|
-
on_tick "example:hello";
|
1060
|
-
|
1061
|
-
// Second namespace with a cross-namespace call
|
1062
|
-
namespace "util";
|
1063
|
-
|
1064
|
-
var num helper_count = 0;
|
1065
|
-
var num total_help = 0;
|
1066
|
-
|
1067
|
-
function "helper" {
|
1068
|
-
say [util:helper] Helping out...;
|
1069
|
-
helper_count = helper_count + 1;
|
1070
|
-
total_help = $helper_count$ * 10;
|
1071
|
-
say Helper count: $helper_count$;
|
1072
|
-
say Total help: $total_help$;
|
1073
|
-
}
|
1074
|
-
|
1075
|
-
function "boss" {
|
1076
|
-
say [util:boss] Calling example:hello then util:helper;
|
1077
|
-
function example:hello;
|
1078
|
-
function util:helper;
|
1079
|
-
}
|
1080
|
-
|
1081
|
-
// Run boss every tick as well
|
1082
|
-
on_tick "util:boss";
|
1083
|
-
|
1084
|
-
// Function tag examples
|
1085
|
-
tag function "minecraft:load" {
|
1086
|
-
add "example:hello";
|
1087
|
-
}
|
1088
|
-
|
1089
|
-
tag function "minecraft:tick" {
|
1090
|
-
add "example:hello";
|
1091
|
-
add "util:boss";
|
1092
|
-
}
|
1093
|
-
|
1094
|
-
// Data tag examples across registries
|
1095
|
-
tag item "example:swords" {
|
1096
|
-
add "minecraft:diamond_sword";
|
1097
|
-
add "minecraft:netherite_sword";
|
1098
|
-
}
|
1099
|
-
|
1100
|
-
tag block "example:glassy" {
|
1101
|
-
add "minecraft:glass";
|
1102
|
-
add "minecraft:tinted_glass";
|
1103
|
-
}
|
1104
|
-
```
|
1105
|
-
|
1106
|
-
### What this demonstrates
|
1107
|
-
- **Nested-like function composition** (`function example:inner` inside `function "hello"`).
|
1108
|
-
- **Multiple namespaces** (`example`, `util`) calling each other with fully-qualified IDs.
|
1109
|
-
- **Lifecycle hooks** (`on_load`, `on_tick`) on both `example:hello` and `util:boss`.
|
1110
|
-
- **Function tags** to participate in vanilla tags (`minecraft:load`, `minecraft:tick`).
|
1111
|
-
- **Data tags** (`item`, `block`) in addition to function tags.
|
1112
|
-
- **Number variables** with `$variable$` substitution.
|
1113
|
-
- **Expressions** with arithmetic operations and variable substitution.
|
1114
|
-
- **Full control structures** - `if/else if/else`, `while` loops with method selection.
|
1115
|
-
- **Modern syntax** with curly braces and semicolons.
|
1116
|
-
- **Variable optimization** - automatic load function generation.
|
1117
|
-
|
1118
|
-
---
|
1119
|
-
|
1120
|
-
## 🐍 Python API equivalent
|
1121
|
-
|
1122
|
-
```python
|
1123
|
-
from minecraft_datapack_language import Pack
|
1124
|
-
|
1125
|
-
def build_pack():
|
1126
|
-
p = Pack(name="Modern Pack",
|
1127
|
-
description="Modern example datapack",
|
1128
|
-
pack_format=82)
|
1129
|
-
|
1130
|
-
ex = p.namespace("example")
|
1131
|
-
ex.function("inner",
|
1132
|
-
'say [example:inner] This is the inner function',
|
1133
|
-
'tellraw @a {"text":"Running inner","color":"yellow"}'
|
1134
|
-
)
|
1135
|
-
ex.function("hello",
|
1136
|
-
'say [example:hello] Outer says hi',
|
1137
|
-
'function example:inner',
|
1138
|
-
'tellraw @a {"text":"Back in hello","color":"aqua"}'
|
1139
|
-
)
|
1140
|
-
|
1141
|
-
# Hooks for example namespace
|
1142
|
-
p.on_load("example:hello")
|
1143
|
-
p.on_tick("example:hello")
|
1144
|
-
|
1145
|
-
util = p.namespace("util")
|
1146
|
-
util.function("helper",
|
1147
|
-
'say [util:helper] Helping out...'
|
1148
|
-
)
|
1149
|
-
util.function("boss",
|
1150
|
-
'say [util:boss] Calling example:hello then util:helper',
|
1151
|
-
'function example:hello',
|
1152
|
-
'function util:helper'
|
1153
|
-
)
|
1154
|
-
|
1155
|
-
# Tick hook for util namespace
|
1156
|
-
p.on_tick("util:boss")
|
1157
|
-
|
1158
|
-
# Function tags
|
1159
|
-
p.tag("function", "minecraft:load", values=["example:hello"])
|
1160
|
-
p.tag("function", "minecraft:tick", values=["example:hello", "util:boss"])
|
1161
|
-
|
1162
|
-
# Data tags
|
1163
|
-
p.tag("item", "example:swords", values=["minecraft:diamond_sword", "minecraft:netherite_sword"])
|
1164
|
-
p.tag("block", "example:glassy", values=["minecraft:glass", "minecraft:tinted_glass"])
|
1165
|
-
|
1166
|
-
return p
|
1167
|
-
```
|
1168
|
-
|
1169
|
-
Build it:
|
1170
|
-
```bash
|
1171
|
-
python - <<'PY'
|
1172
|
-
from my_pack_module import build_pack
|
1173
|
-
from minecraft_datapack_language.cli import main as M
|
1174
|
-
# write to dist/ with a wrapper folder name 'mypack'
|
1175
|
-
p = build_pack()
|
1176
|
-
M(['build', '--py-object', 'my_pack_module:build_pack', '-o', 'dist', '--wrapper', 'mypack', '--pack-format', '82'])
|
1177
|
-
PY
|
1178
|
-
```
|
1179
|
-
|
1180
|
-
---
|
1181
|
-
|
1182
|
-
## 🔧 Development System
|
1183
|
-
|
1184
|
-
MDL includes a comprehensive development system that allows you to work with both stable and development versions simultaneously.
|
1185
|
-
|
1186
|
-
### Quick Setup
|
1187
|
-
|
1188
|
-
**Linux/macOS:**
|
1189
|
-
```bash
|
1190
|
-
./scripts/dev_setup.sh
|
1191
|
-
```
|
1192
|
-
|
1193
|
-
**Windows (PowerShell):**
|
1194
|
-
```powershell
|
1195
|
-
.\scripts\dev_setup.ps1
|
1196
|
-
```
|
1197
|
-
|
1198
|
-
### Development Commands
|
1199
|
-
|
1200
|
-
- **`mdl`** - Stable, globally installed version
|
1201
|
-
- **`mdlbeta`** - Local development version for testing changes
|
1202
|
-
|
1203
|
-
### Development Workflow
|
1204
|
-
|
1205
|
-
1. **Make changes** to the code
|
1206
|
-
2. **Rebuild** the development version:
|
1207
|
-
```bash
|
1208
|
-
./scripts/dev_build.sh
|
1209
|
-
```
|
1210
|
-
3. **Test** your changes with `mdlbeta`:
|
1211
|
-
```bash
|
1212
|
-
mdlbeta build --mdl your_file.mdl -o dist
|
1213
|
-
```
|
1214
|
-
4. **Compare** with stable version:
|
1215
|
-
```bash
|
1216
|
-
mdl build --mdl your_file.mdl -o dist_stable
|
1217
|
-
```
|
1218
|
-
|
1219
|
-
### Testing
|
1220
|
-
|
1221
|
-
**Test the development environment:**
|
1222
|
-
```bash
|
1223
|
-
# Linux/macOS
|
1224
|
-
./scripts/test_dev.sh
|
1225
|
-
|
1226
|
-
# Windows (PowerShell)
|
1227
|
-
.\scripts\test_dev.ps1
|
1228
|
-
```
|
1229
|
-
|
1230
|
-
For more details, see [DEVELOPMENT.md](DEVELOPMENT.md).
|
1231
|
-
|
1232
|
-
## 🔧 VS Code Extension
|
1233
|
-
|
1234
|
-
Get syntax highlighting, error checking, and build commands for `.mdl` files in VS Code, Cursor, and other VS Code-based editors.
|
1235
|
-
|
1236
|
-
### Quick Install
|
1237
|
-
|
1238
|
-
1. **Download from [GitHub Releases](https://github.com/aaron777collins/MinecraftDatapackLanguage/releases)**
|
1239
|
-
2. **Install the `.vsix` file**:
|
1240
|
-
- Open VS Code/Cursor
|
1241
|
-
- Go to Extensions (Ctrl+Shift+X)
|
1242
|
-
- Click "..." → "Install from VSIX..."
|
1243
|
-
- Choose the downloaded `.vsix` file
|
1244
|
-
|
1245
|
-
### Features
|
1246
|
-
- **Syntax highlighting** for `.mdl` files
|
1247
|
-
- **Real-time error checking** with error detection
|
1248
|
-
- **Build commands**: `MDL: Build current file` and `MDL: Check Workspace`
|
1249
|
-
- **Workspace validation** for multi-file projects
|
1250
|
-
- **Server function support**: Proper `@a` selector usage for tag-called functions
|
1251
|
-
|
1252
|
-
### Development Setup
|
1253
|
-
```bash
|
1254
|
-
cd vscode-extension/
|
1255
|
-
npm i
|
1256
|
-
# Press F5 to launch the Extension Dev Host
|
1257
|
-
```
|
1258
|
-
|
1259
|
-
---
|
1260
|
-
|
1261
|
-
## 🚀 CI & Releases
|
1262
|
-
|
1263
|
-
- **CI** runs on push/PR across Linux/macOS/Windows and uploads artifacts.
|
1264
|
-
- **Release** is triggered by pushing a tag like `v1.0.0` or via the Release workflow manually.
|
1265
|
-
- Versions are derived from git tags via **setuptools-scm**; tag `vX.Y.Z` → package version `X.Y.Z`.
|
1266
|
-
|
1267
|
-
### Local release helper
|
1268
|
-
```bash
|
1269
|
-
# requires GitHub CLI: gh auth login
|
1270
|
-
./scripts/release.sh patch "Fixes"
|
1271
|
-
./scripts/release.sh minor "Features"
|
1272
|
-
./scripts/release.sh major "Breaking"
|
1273
|
-
./scripts/release.sh v1.2.3 "Exact version"
|
1274
|
-
```
|