← go back

Seems like there’s an interest in script I made, so here’s a documenting example that took me 2 days to write:

[* this is a comment *]
[*
	These are the available variable types of this language.

	$objective is a scoreboard objective
	:tag       is the value of minecraft:tag on world storage (from /data ... storage)
	:tag.foo   is the value of key foo in minecraft:tag
	           (in general it uses minecraft:nbt_path)
	           (you can also change the default "minecraft" namespace to something else 
                using the "namespace" command)
    mod:tag    is the value of mod:tag on world storage
	!boss^10   is a bossbar with maximum value of 10
	!boss      is a bossbar value
	!boss^     is a bossbar's maximum value
	.          is the entity's data
	.NoAI      is the value of key NoAI of the entity's data
	.Pos[0]    is the first value of the list of key Pos of the entity's data
	           (in general it uses minecraft:nbt_path)

	These may be prefixed with these object types:
	@a         are all the players in the world
	@e         are all the entities in the world
               ... you get the drill. It's just minecraft:entity.
	Alice      is a player named Alice (default for names without a sigil)
	#(0 1 2)   is a block in x: 0 y: 1 z: 2
	#(~ ~ ~)   is a block at the entity's coordinates
*]

[* namespace example *] [* would set a namespace if it's not commented *]
[* use path/to/other/file *] [* would effectively append the contents of the file here *]

dummy $foo  [* creates an objective of type dummy *]
health $bar [* creates an objective of type health *]

repeat (
	[* these commands are run every tick *]

	$foo += 1 [* by default this is applied to the current entity *]
	@s$foo += 1 [* this line functions identically to the line above *]

	[* Supported operations are +, -, *, / (integer division), // (float division if possible), and % *]
)

function roll_call (
	[* all subcommands on /execute (except "store" and "summon") are put as their own command *]
	as @a (
		say I'm present
	)
	[* 
		These lines function identically:
		as @a run say I'm present
		as @a /say I'm present
	*]
)

function tell_time (
	dummy $time $time_min $time_hour

	:time.ticks = /time query daytime [* stores into minecraft:time *]
	$time = :time.ticks * 0.06 [* ticks to Minecraft minutes *]
	$time_min = $time % 60
	$time_hour = ($time / 60) + 6 % 24
	
	if ($time_min >= 10) /tellraw @s c"It's $($time_hour):$($time_min)"
	if ($time_min <  10) /tellraw @s c"It's $($time_hour):0$($time_min)"
)

function tell_time_compiled (
	[* This might be what the function tell_time will be compiled to. *]

	scoreboard objectives add time dummy
	scoreboard objectives add time_min dummy
	scoreboard objectives add time_hour dummy
	scoreboard objectives add const_24 dummy
	scoreboard objectives add const_60 dummy
	scoreboard objectives add const_6 dummy
	scoreboard players set @s const_24 24
	scoreboard players set @s const_60 60
	scoreboard players set @s const_6 6

	execute store result storage time ticks long 1 run time query daytime
	execute store result score @s time run data get storage time 0.06
	execute store result score @s time_min run scoreboard players get @s time
	scoreboard players operation @s time_min %= @s const_60
	execute store result score @s time_hour run scoreboard players get @s time
	scoreboard players operation @s time_hour /= @s const_60
	scoreboard players operation @s time_hour += @s const_6
	scoreboard players operation @s time_hour %= @s const_24

	execute if score @s time_min matches 10.. run tellraw @s [{"text": "It's "}, {"score": {"name": "*", "objective": "time_hour"}}, {"text": ":"}, {"score": {"name": "*", "objective": "time_min"}}]
	execute if score @s time_min matches ..9 run tellraw @s [{"text": "It's "}, {"score": {"name": "*", "objective": "time_hour"}}, {"text": ":0"}, {"score": {"name": "*", "objective": "time_min"}}]
)

function conditionals #example ( [* tagged under #minecraft:example *]
	[* 
		The following are a list of syntatic sugars using the "if" command, and their equivalent commands. 
		These also apply to "unless" as well.
	*]
	if #(^ ^ ^1) = #planks /say pointing a plank
	if block ^ ^ ^1 #planks run say pointing a plank

	if #(^ ^ ^1) = furnace and #(^ ^ ^1).Items[{Slot: 2b}] /say there's output in the furnace
	if block ^ ^ ^1 furnace if data block ^ ^ ^1 Items[{Slot: 2b}] run say there's output in the furnace

	if (@a.foodLevel = 20) /say I'm not hungry                     [* brackets are optional *]
	as @a if data entity @s {foodLevel: 20} run say I'm not hungry [* "if entity" only allows a single entity *]

	if :foo.bar /say okay
	if storage foo bar run say okay

	if :time.ticks = 20l /say okay
	if storage time {ticks: 20l} run say okay

	if @e /say I'm not alone
	if entity @e run say I'm not alone

	[* Note the dot. *]
	if @e. /say I have data
	as @e if data entity @s {} run say I have data

	if $foo > $bar /say wow
	if score @s foo > @s bar run say wow

	if $bar <= 1 /say Peril!
	if score @s bar matches ..1 run say Peril!

	[* Implementation note: These commands (and probably more) would need temporary objectives or functions to work. *]
	[* Example 1a: Comparing inequalities between different variable types *]
	if $foo > :foo.bar /say wow
	execute store result score @s temp1 run data get storage foo bar
	execute if score @s foo > @s temp1 run say wow
	
	[* Example 1b: Comparing inequalities between variable types other than objectives *]
	if :foo.bar > :foo.baz /say wow
	execute store result score @s temp1 run data get storage foo bar
	execute store result score @s temp2 run data get storage foo baz
	execute if score @s temp1 > @s temp2 run say wow

	[* Example 2: Comparing variables other than objectives with a constant number *]
	if :foo.bar = 10 /say wow
	execute store result score @s temp1 run data get storage foo bar
	scoreboard players set @s temp2 10
	execute if score @s temp1 = @s temp2 run say wow
	[* 
		Exceptions to this example are:
		1. Equality of a NBT value
			if @a.foodLevel = 20 /say I'm not hungry 
			as @a if data entity @s {foodLevel: 20} run say I'm not hungry
		2. 
	*]

	[* Example 3: Executing a code block *]
	if $foo = 10 (
		say Hello
		say world
	)
	if score @s foo matches 10 run function temp1
	[* where the function minecraft:temp1 contains the code inside the block *]
)

function arguments #example (
	[* Unlike .mcfunction, you can add $(...) without prefixing your function with $ *]
	say Argument is $(arg1)

	[* To output the placeholders instead of interpolating them, you can escape them: *]
	say Argument is \$(arg1)
)

function json_quotes #example (
	[* JSON quotes are prefixed with c and provides basic formatting for commands using raw JSON text format. *]
	[* The following are examples of them and their equivalent commands. *]

	tellraw @s c"This is plain text."
	tellraw @s {"text": "This is plain text."}

	tellraw @s c"It's not *that* obvious..."
	tellraw @s [{"text": "It's not "}, {"text": "that", "italic": true}, {"text": " obvious..."}]

	tellraw @s c"It's not \*that* obvious..."
	tellraw @s {"text": "It's not \*that* obvious..."}

	tellraw @s c"It's not **that** obvious..."
	tellraw @s [{"text": "It's not "}, {"text": "that", "bold": true}, {"text": " obvious..."}]

	tellraw @s c"It's not ***that*** obvious..."
	tellraw @s [{"text": "It's not "}, {"text": "that", "bold": true, "italic": true}, {"text": " obvious..."}]

	tellraw @s c"Fill in the blanks: _But I've already done that!_"
	tellraw @s [{"text": "Fill in the blanks: "}, {"text": "But I've already done that!", "underline": true}]

	tellraw @s c"Son of a ||birch||!" [* Sorry. *]
	tellraw @s [{"text": "Son of a "}, {"text": "birch", "obfuscated": true}, {"text": "!"}]

	tellraw @s c"#blue(I am blue.)"
	tellraw @s {"text": "I am blue.", "color": "blue"}

	tellraw @s c"#FE1F6F(Uh oh.)"
	tellraw @s {"text": "Uh oh.", "color": "#FE1F6F"}

	tellraw @s c"!https://example.com(Click me!)"
	tellraw @s {"text": "Click me!", "clickAction": {"action": "open_url": "value": "https://example.com"}}

	tellraw @s c"![say You clicked me!](Click me!)" [* this is the normal behaviour for values without any sigils *]
	tellraw @s {"text": "Click me!", "clickAction": {"action": "run_command": "value": "say You clicked me!"}}

	tellraw @s c"![?say You clicked me!](Click me!)"
	tellraw @s {"text": "Click me!", "clickAction": {"action": "suggest_command": "value": "say You clicked me!"}}

	tellraw @s c"![@You clicked me!](Click me)"
	tellraw @s {"text": "Click me!", "clickAction": {"action": "copy_to_clipboard": "value": "You clicked me!"}}

	tellraw @s c'Press "%(key.inventory)" to check your inventory!'
	tellraw @s [{"text": "Press \""}, {"keybind": "key.inventory"}, {"text": "\" to check your inventory!"}]

	tellraw @s c'Your score is $($foo)'
	tellraw @s [{"text": "Your score is "}, {"score": {"name": "*", "objective": "foo"}}]

	tellraw @s c'Alice\'s score is $(Alice$foo)'
	tellraw @s [{"text": "Your score is "}, {"score": {"name": "Alice", "objective": "foo"}}]

	tellraw @s c'minecraft:foo.bar = $(:foo.bar)'
	tellraw @s [{"text": "minecraft:foo.bar = "}, {"source": "storage, "nbt": "bar"}]
)

function extended_syntax #appendix (
	[*
		These are some officially unofficial extended syntax for this language.
		If these were implemented, it should be as a dialect and not as the main language.

		These extended syntax might be official if I feel like it.
	*]

	[* Statements in JSON quotes *]
	tellraw @s c'Your score + 1 is $($score + 1)'

	[* One of these for content matching *]
	if foo.Inventory[] # {Slot: -106b} /say foo is holding something in the offhand
	if foo.Inventory[] contains {Slot: -106b} /say foo is holding something in the offhand
	if foo.Inventory[Slot] = -106b /say foo is holding something in the offhand
	[* They're equivalent to this: *]
	if foo.Inventory[{Slot: -106b}] /say foo is holding something in the offhand

	[* Command repetitions *]
	for i in 1 3 2 5 4 (
		if $foo > $(i) /say wow $(i)
		if $foo < $(i) /say boo $(i)
	)
	for i from 1 to 11 step 2 ( [* forcibly inclusive *]
		if $foo > $(i) /say wow $(i)
		if $foo < $(i) /say boo $(i)
	)
	repeat 5 (
		say this line will be said 5 times
	)
)

And using the compiler:

$ compile .code.tio -o datapack/       # saves as a data pack
$ compile .code.tio -o this.structure  # saves as a .structure containing command blocks
[!] warning: cannot compile function `roll_call' to a structure
 @ .code.tio:27:63: 
 | function roll_call (
 | ...
[!] warning: cannot compile function `tell_time' to a structure
 @ .code.tio:27:63: 
 | function tell_time (
 | ...
[!] warning: cannot compile function `tell_time_compiled' to a structure
 @ .code.tio:27:63: 
 | function tell_time_compiled (
 | ...
...
$ # Not that you should call the compiler "compile".

I don’t have any plans to implement this language (it would be too hard to do it myself) but if someone wants it go ahead. I’m open to suggestions I guess.

Now what should I call this language…

Jan 7, 2024, 1:10 PM
3 0 0

Comments