minecraft-datapack-language 15.4.36__py3-none-any.whl → 15.4.38__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/_version.py +2 -2
- minecraft_datapack_language/cli.py +3 -1
- minecraft_datapack_language/mdl_compiler.py +58 -15
- minecraft_datapack_language/python_api.py +18 -4
- {minecraft_datapack_language-15.4.36.dist-info → minecraft_datapack_language-15.4.38.dist-info}/METADATA +1 -1
- {minecraft_datapack_language-15.4.36.dist-info → minecraft_datapack_language-15.4.38.dist-info}/RECORD +10 -10
- {minecraft_datapack_language-15.4.36.dist-info → minecraft_datapack_language-15.4.38.dist-info}/WHEEL +0 -0
- {minecraft_datapack_language-15.4.36.dist-info → minecraft_datapack_language-15.4.38.dist-info}/entry_points.txt +0 -0
- {minecraft_datapack_language-15.4.36.dist-info → minecraft_datapack_language-15.4.38.dist-info}/licenses/LICENSE +0 -0
- {minecraft_datapack_language-15.4.36.dist-info → minecraft_datapack_language-15.4.38.dist-info}/top_level.txt +0 -0
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
28
28
|
commit_id: COMMIT_ID
|
29
29
|
__commit_id__: COMMIT_ID
|
30
30
|
|
31
|
-
__version__ = version = '15.4.
|
32
|
-
__version_tuple__ = version_tuple = (15, 4,
|
31
|
+
__version__ = version = '15.4.38'
|
32
|
+
__version_tuple__ = version_tuple = (15, 4, 38)
|
33
33
|
|
34
34
|
__commit_id__ = commit_id = None
|
@@ -145,8 +145,10 @@ def build_command(args):
|
|
145
145
|
if args.verbose:
|
146
146
|
print(f"Compiling to {output_dir}...")
|
147
147
|
|
148
|
+
# Support optional wrapper directory
|
149
|
+
if getattr(args, 'wrapper', None):
|
150
|
+
output_dir = output_dir / args.wrapper
|
148
151
|
compiler = MDLCompiler()
|
149
|
-
# Note: --wrapper is currently accepted for compatibility but not required by compiler
|
150
152
|
output_path = compiler.compile(final_ast, str(output_dir))
|
151
153
|
|
152
154
|
print(f"Successfully built datapack: {output_path}")
|
@@ -63,13 +63,13 @@ class MDLCompiler:
|
|
63
63
|
if ast.namespace:
|
64
64
|
self.current_namespace = ast.namespace.name
|
65
65
|
|
66
|
-
# Create namespace directory
|
66
|
+
# Create namespace directory (for default/current)
|
67
67
|
namespace_dir = data_dir / self.current_namespace
|
68
68
|
namespace_dir.mkdir(parents=True, exist_ok=True)
|
69
69
|
|
70
70
|
# Compile all components
|
71
71
|
self._compile_variables(ast.variables, namespace_dir)
|
72
|
-
self._compile_functions(ast.functions,
|
72
|
+
self._compile_functions(ast.functions, data_dir)
|
73
73
|
self._compile_hooks(ast.hooks, namespace_dir)
|
74
74
|
self._compile_statements(ast.statements, namespace_dir)
|
75
75
|
self._compile_tags(ast.tags, source_dir)
|
@@ -123,15 +123,17 @@ class MDLCompiler:
|
|
123
123
|
self.variables[var.name] = objective_name
|
124
124
|
print(f"Variable: {var.name} -> scoreboard objective '{objective_name}'")
|
125
125
|
|
126
|
-
def _compile_functions(self, functions: List[FunctionDeclaration],
|
126
|
+
def _compile_functions(self, functions: List[FunctionDeclaration], data_dir: Path):
|
127
127
|
"""Compile function declarations into .mcfunction files."""
|
128
|
-
if self.dir_map:
|
129
|
-
functions_dir = namespace_dir / self.dir_map.function
|
130
|
-
else:
|
131
|
-
functions_dir = namespace_dir / "functions"
|
132
|
-
functions_dir.mkdir(parents=True, exist_ok=True)
|
133
|
-
|
134
128
|
for func in functions:
|
129
|
+
# Ensure namespace directory per function
|
130
|
+
ns_dir = data_dir / func.namespace
|
131
|
+
ns_dir.mkdir(parents=True, exist_ok=True)
|
132
|
+
if self.dir_map:
|
133
|
+
functions_dir = ns_dir / self.dir_map.function
|
134
|
+
else:
|
135
|
+
functions_dir = ns_dir / "functions"
|
136
|
+
functions_dir.mkdir(parents=True, exist_ok=True)
|
135
137
|
func_file = functions_dir / f"{func.name}.mcfunction"
|
136
138
|
content = self._generate_function_content(func)
|
137
139
|
|
@@ -200,13 +202,18 @@ class MDLCompiler:
|
|
200
202
|
tag_dir = self.output_dir / "data" / "minecraft" / self.dir_map.tags_item
|
201
203
|
elif tag.tag_type == "structure":
|
202
204
|
tag_dir = self.output_dir / "data" / "minecraft" / self.dir_map.tags_item
|
205
|
+
elif tag.tag_type == "item":
|
206
|
+
# Namespace item tags (e.g., data/<ns>/tags/items/<name>.json)
|
207
|
+
ns_dir = self.output_dir / "data" / self.current_namespace / "tags"
|
208
|
+
# Prefer plural 'items' for compatibility
|
209
|
+
tag_dir = ns_dir / "items"
|
203
210
|
else:
|
204
211
|
continue
|
205
212
|
|
206
213
|
tag_dir.mkdir(parents=True, exist_ok=True)
|
207
214
|
tag_file = tag_dir / f"{tag.name}.json"
|
208
215
|
|
209
|
-
if source_path:
|
216
|
+
if source_path and tag.tag_type != "item":
|
210
217
|
source_json = source_path / tag.file_path
|
211
218
|
if source_json.exists():
|
212
219
|
shutil.copy2(source_json, tag_file)
|
@@ -217,10 +224,15 @@ class MDLCompiler:
|
|
217
224
|
json.dump(tag_data, f, indent=2)
|
218
225
|
print(f"Tag {tag.tag_type}: {tag.name} -> {tag_file} (placeholder)")
|
219
226
|
else:
|
220
|
-
|
227
|
+
# Write simple values list
|
228
|
+
values = [f"{self.current_namespace}:{tag.name}"]
|
229
|
+
# For item tags, the TagDeclaration.name may include namespace:name; use as-is
|
230
|
+
if ":" in tag.name:
|
231
|
+
values = [tag.name]
|
232
|
+
tag_data = {"values": values}
|
221
233
|
with open(tag_file, 'w') as f:
|
222
234
|
json.dump(tag_data, f, indent=2)
|
223
|
-
print(f"Tag {tag.tag_type}: {tag.name} -> {tag_file} (
|
235
|
+
print(f"Tag {tag.tag_type}: {tag.name} -> {tag_file} (generated)")
|
224
236
|
|
225
237
|
def _create_hook_functions(self, hooks: List[HookDeclaration], namespace_dir: Path):
|
226
238
|
"""Create load.mcfunction and tick.mcfunction for hooks."""
|
@@ -229,17 +241,19 @@ class MDLCompiler:
|
|
229
241
|
else:
|
230
242
|
functions_dir = namespace_dir / "functions"
|
231
243
|
|
232
|
-
#
|
244
|
+
# Always create load function to initialize objectives; add tag only if on_load hooks exist
|
245
|
+
has_on_load = any(h.hook_type == "on_load" for h in hooks)
|
233
246
|
load_content = self._generate_load_function(hooks)
|
234
247
|
load_file = functions_dir / "load.mcfunction"
|
235
248
|
with open(load_file, 'w') as f:
|
236
249
|
f.write(load_content)
|
237
|
-
# Ensure minecraft load tag points to namespace:load
|
250
|
+
# Ensure minecraft load tag points to namespace:load when needed
|
238
251
|
tags_fn_dir = self.output_dir / "data" / "minecraft" / self.dir_map.tags_function
|
239
252
|
tags_fn_dir.mkdir(parents=True, exist_ok=True)
|
240
253
|
load_tag_file = tags_fn_dir / "load.json"
|
254
|
+
values = [f"{self.current_namespace}:load"] if has_on_load else [f"{self.current_namespace}:load"]
|
241
255
|
with open(load_tag_file, 'w') as f:
|
242
|
-
json.dump({"values":
|
256
|
+
json.dump({"values": values}, f, indent=2)
|
243
257
|
|
244
258
|
# Create tick function if needed
|
245
259
|
tick_hooks = [h for h in hooks if h.hook_type == "on_tick"]
|
@@ -299,6 +313,8 @@ class MDLCompiler:
|
|
299
313
|
"""Convert an AST statement to a Minecraft command."""
|
300
314
|
if isinstance(statement, VariableAssignment):
|
301
315
|
return self._variable_assignment_to_command(statement)
|
316
|
+
elif isinstance(statement, VariableDeclaration):
|
317
|
+
return self._variable_declaration_to_command(statement)
|
302
318
|
elif isinstance(statement, SayCommand):
|
303
319
|
return self._say_command_to_command(statement)
|
304
320
|
elif isinstance(statement, RawBlock):
|
@@ -329,6 +345,24 @@ class MDLCompiler:
|
|
329
345
|
# Simple value - use direct assignment
|
330
346
|
value = self._expression_to_value(assignment.value)
|
331
347
|
return f"scoreboard players set {scope} {objective} {value}"
|
348
|
+
|
349
|
+
def _variable_declaration_to_command(self, decl: VariableDeclaration) -> str:
|
350
|
+
"""Handle var declarations appearing inside function bodies.
|
351
|
+
Ensure objective is registered and optionally set initial value.
|
352
|
+
"""
|
353
|
+
objective = self.variables.get(decl.name, decl.name)
|
354
|
+
# Register objective so load function adds it
|
355
|
+
self.variables[decl.name] = objective
|
356
|
+
# If there is an initial value, set it in current context
|
357
|
+
scope = decl.scope.strip("<>")
|
358
|
+
init = None
|
359
|
+
try:
|
360
|
+
init = self._expression_to_value(decl.initial_value)
|
361
|
+
except Exception:
|
362
|
+
init = None
|
363
|
+
if init is not None:
|
364
|
+
return f"scoreboard players set {scope} {objective} {init}"
|
365
|
+
return f"# var {decl.name} declared"
|
332
366
|
|
333
367
|
def _say_command_to_command(self, say: SayCommand) -> str:
|
334
368
|
"""Convert say command to tellraw command with JSON formatting."""
|
@@ -406,6 +440,9 @@ class MDLCompiler:
|
|
406
440
|
if isinstance(stmt, VariableAssignment):
|
407
441
|
cmd = self._variable_assignment_to_command(stmt)
|
408
442
|
if_body_lines.append(cmd)
|
443
|
+
elif isinstance(stmt, VariableDeclaration):
|
444
|
+
cmd = self._variable_declaration_to_command(stmt)
|
445
|
+
if_body_lines.append(cmd)
|
409
446
|
elif isinstance(stmt, SayCommand):
|
410
447
|
cmd = self._say_command_to_command(stmt)
|
411
448
|
if_body_lines.append(cmd)
|
@@ -454,6 +491,9 @@ class MDLCompiler:
|
|
454
491
|
if isinstance(stmt, VariableAssignment):
|
455
492
|
cmd = self._variable_assignment_to_command(stmt)
|
456
493
|
else_body_lines.append(cmd)
|
494
|
+
elif isinstance(stmt, VariableDeclaration):
|
495
|
+
cmd = self._variable_declaration_to_command(stmt)
|
496
|
+
else_body_lines.append(cmd)
|
457
497
|
elif isinstance(stmt, SayCommand):
|
458
498
|
cmd = self._say_command_to_command(stmt)
|
459
499
|
else_body_lines.append(cmd)
|
@@ -499,6 +539,9 @@ class MDLCompiler:
|
|
499
539
|
if isinstance(stmt, VariableAssignment):
|
500
540
|
cmd = self._variable_assignment_to_command(stmt)
|
501
541
|
loop_body_lines.append(cmd)
|
542
|
+
elif isinstance(stmt, VariableDeclaration):
|
543
|
+
cmd = self._variable_declaration_to_command(stmt)
|
544
|
+
loop_body_lines.append(cmd)
|
502
545
|
elif isinstance(stmt, SayCommand):
|
503
546
|
cmd = self._say_command_to_command(stmt)
|
504
547
|
loop_body_lines.append(cmd)
|
@@ -65,9 +65,11 @@ class Pack:
|
|
65
65
|
|
66
66
|
def tag(self, registry: str, name: str, values: Optional[List[str]] = None, replace: bool = False):
|
67
67
|
values = values or []
|
68
|
-
#
|
69
|
-
|
70
|
-
|
68
|
+
# For namespace item tags, store values in file_path for compiler to consume
|
69
|
+
file_path = name
|
70
|
+
if registry == "item" and values:
|
71
|
+
file_path = "values=" + ",".join(values)
|
72
|
+
self._tags.append(TagDeclaration(tag_type=registry, name=name, file_path=file_path))
|
71
73
|
|
72
74
|
def declare_var(self, name: str, scope: str, initial_value: Union[int, float]) -> None:
|
73
75
|
self._variables.append(
|
@@ -95,9 +97,21 @@ class Pack:
|
|
95
97
|
HookDeclaration(hook_type=hook_type, namespace=ns_name, name=fn_name, scope=scope)
|
96
98
|
)
|
97
99
|
|
100
|
+
# Determine default namespace if none explicitly added
|
101
|
+
default_namespace = None
|
102
|
+
if namespace_nodes:
|
103
|
+
default_namespace = namespace_nodes[0]
|
104
|
+
elif self._tags:
|
105
|
+
# Derive from first tag name if namespaced (e.g., test:swords)
|
106
|
+
first = self._tags[0].name
|
107
|
+
if ":" in first:
|
108
|
+
default_namespace = NamespaceDeclaration(name=first.split(":",1)[0])
|
109
|
+
else:
|
110
|
+
default_namespace = NamespaceDeclaration(name="mdl")
|
111
|
+
|
98
112
|
program = Program(
|
99
113
|
pack=self._pack,
|
100
|
-
namespace=
|
114
|
+
namespace=default_namespace,
|
101
115
|
tags=self._tags,
|
102
116
|
variables=self._variables,
|
103
117
|
functions=function_nodes,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: minecraft-datapack-language
|
3
|
-
Version: 15.4.
|
3
|
+
Version: 15.4.38
|
4
4
|
Summary: Compile MDL language with explicit scoping into a Minecraft datapack (1.21+ ready). Features variables, control flow, error handling, and VS Code extension.
|
5
5
|
Project-URL: Homepage, https://www.mcmdl.com
|
6
6
|
Project-URL: Documentation, https://www.mcmdl.com/docs
|
@@ -1,18 +1,18 @@
|
|
1
1
|
minecraft_datapack_language/__init__.py,sha256=0KVXBE4ScRaRUrf83aA2tVB-y8A_jplyaxVvtHH6Uw0,1199
|
2
|
-
minecraft_datapack_language/_version.py,sha256
|
2
|
+
minecraft_datapack_language/_version.py,sha256=QAeBw9GSywEaOdZ4hbATpOk5n3gIFmL460R-trSWONI,708
|
3
3
|
minecraft_datapack_language/ast_nodes.py,sha256=nbWrRz137MGMRpmnq8QkXNzrtlaCgyPEknytbkrS_M8,3899
|
4
|
-
minecraft_datapack_language/cli.py,sha256
|
4
|
+
minecraft_datapack_language/cli.py,sha256=Vk35mPYm8saMUbBNRDTeoqKiLq9_do_ZeRatFWN2EQs,9824
|
5
5
|
minecraft_datapack_language/dir_map.py,sha256=HmxFkuvWGkzHF8o_GFb4BpuMCRc6QMw8UbmcAI8JVdY,1788
|
6
|
-
minecraft_datapack_language/mdl_compiler.py,sha256=
|
6
|
+
minecraft_datapack_language/mdl_compiler.py,sha256=9ut6cmUMmioQNiiHyNDiqiViimZzgStMzRUDXddPpRI,40802
|
7
7
|
minecraft_datapack_language/mdl_errors.py,sha256=r0Gu3KhoX1YLPAVW_iO7Q_fPgaf_Dv9tOGSOdKNSzmw,16114
|
8
8
|
minecraft_datapack_language/mdl_lexer.py,sha256=CjbEUpuuF4eU_ucA_WIhw6wSMcHGk2BchtQ0bLAGvwg,22033
|
9
9
|
minecraft_datapack_language/mdl_linter.py,sha256=z85xoAglENurCh30bR7kEHZ_JeMxcYaLDcGNRAl-RAI,17253
|
10
10
|
minecraft_datapack_language/mdl_parser.py,sha256=aQPKcmATM9BOMzO7vCXmMdxU1qjOJNLCSAKJopu5h3g,23429
|
11
|
-
minecraft_datapack_language/python_api.py,sha256=
|
11
|
+
minecraft_datapack_language/python_api.py,sha256=ImYULwBvJ0Qb0Tf6LFyXv-gTPGZ8njX7_La0HJKuk-o,8677
|
12
12
|
minecraft_datapack_language/utils.py,sha256=Aq0HAGlXqj9BUTEjaEilpvzEW0EtZYYMMwOqG9db6dE,684
|
13
|
-
minecraft_datapack_language-15.4.
|
14
|
-
minecraft_datapack_language-15.4.
|
15
|
-
minecraft_datapack_language-15.4.
|
16
|
-
minecraft_datapack_language-15.4.
|
17
|
-
minecraft_datapack_language-15.4.
|
18
|
-
minecraft_datapack_language-15.4.
|
13
|
+
minecraft_datapack_language-15.4.38.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
14
|
+
minecraft_datapack_language-15.4.38.dist-info/METADATA,sha256=RqCxGwctWsW8p2HD-hdw-hYYgyEPYNJ8cVn7Vn1Ut_M,8360
|
15
|
+
minecraft_datapack_language-15.4.38.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
16
|
+
minecraft_datapack_language-15.4.38.dist-info/entry_points.txt,sha256=c6vjBeCiyQflvPHBRyBk2nJCSfYt3Oc7Sc9V87ySi_U,108
|
17
|
+
minecraft_datapack_language-15.4.38.dist-info/top_level.txt,sha256=ADtFI476tbKLLxEAA-aJQAfg53MA3k_DOb0KTFiggfw,28
|
18
|
+
minecraft_datapack_language-15.4.38.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|