mojira.dev
MC-80856

Command syntax inconsistencies

I don't know if this is a valid report, but I hope so. Else I am pretty much fine with it, if you say it "Invalid" as long as your explanation would be this is a suggestion.

Notes:

It seems like the command syntax suggestions are inconsistent or irritating.

Considering:

  • <arg> = argument

  • text = literal

  • [] = optional

    • [<arg>] = optional argument

    • [<arg1> <arg2>] = optional arguments, either both have to be provided or both have to be omitted

    • [text] = optional literal

  • | as or

    • text1|text2 = either text1 or text2 has to be provided literal

Note: This implies that arguments never use one of these characters

General

achievement

/achievement <give|take> <stat_name|*> [player]
/achievement give|take <stat name>|* [<player>]

Note: The underscore is not needed as it doesn't exactly uses an argument called "stat_name". However something like <stat or achievement> would make more sense as the /achievement command was mainly made to interact with achievements (I guess, see also MC-80826)

ban

/ban <name> [reason ...]
/ban <name> [<reason ...>]

ban-ip

/ban-ip <address|name> [reason ...]
/ban-ip <address|name> [<reason ...>]

clear

/clear [player] [item] [data] [maxCount] [dataTag]
/clear [<player>] [<item>] [<data>] [<maxCount>] [<dataTag>]

clone

/clone <x1> <y1> <z1> <x2> <y2> <z2> <x> <y> <z> [maskMode] [cloneMode]
/clone <x1> <y1> <z1> <x2> <y2> <z2> <x> <y> <z> [<maskMode>] [<cloneMode>]

debug

/debug <start|stop>
/debug start|stop

effect

/effect <player> <effect> [seconds] [amplifier] [hideParticles] OR /effect <player> clear
/effect <player> <effect> [<seconds>] [<amplifier>] [<hideParticles>] OR /effect <player> clear

enchant

/enchant <player> <enchantment ID> [level]
/enchant <player> <enchantment ID> [<level>]

fill (See also MC-80823)

/fill <x1> <y1> <z1> <x2> <y2> <z2> <TileName> [dataValue] [oldBlockHandling] [dataTag]
/fill <x1> <y1> <z1> <x2> <y2> <z2> <TileName> [<dataValue>] [<oldBlockHandling>] [<dataTag>]

gamemode

/gamemode <mode> [player]
/gamemode <mode> [<player>]

gamerule

/gamerule <rule name> [<value>]

give

/give <player> <item> [amount] [data] [dataTag]
/give <player> <item> [<amount>] [<data>] [<dataTag>]

help

/help [page|command name]
/help [<page>|<command name>]

kick

/kick <player> [reason ...]
/kick <player> [<reason ...>]

kill

/kill [player|entity]
/kill [<player|entity>]

particle

/particle <name> <x> <y> <z> <xd> <yd> <zd> <speed> [count] [mode]
/particle <name> <x> <y> <z> <xd> <yd> <zd> <speed> [<count>] [<mode>]

Note: I assume the "d" means delta (or difference), however then it is inconsistent with the arguments dx, dy and dz from selectors

playsound

/playsound <sound> <source> <player> [x] [y] [z] [volume] [pitch] [minimumVolume]
/playsound <sound> <source> <player> [<x>] [<y>] [<z>] [<volume>] [<pitch>] [<minimumVolume>]

recipe

/recipe <give|take> [player] <name|*>
/recipe give|take <player> <name>|*

replaceitem

/replaceitem <entity|block> ...
/replaceitem entity|block ...

scoreboard

/scoreboard <objectives|players|teams> ...
/scoreboard objectives|players|teams ...

setblock

/setblock <x> <y> <z> <TileName> [dataValue] [oldBlockHandling] [dataTag]
/setblock <x> <y> <z> <TileName> [<dataValue>] [<oldBlockHandling>] [<dataTag>]

spawnpoint

/spawnpoint [player] [<x> <y> <z>]
/spawnpoint [<player>] [<x> <y> <z>]

stats

/stats <entity|block> ...
/stats entity|block ...

summon

/summon <EntityName> [x] [y] [z] [dataTag]
/summon <EntityName> [<x> <y> <z>] [<dataTag>]

Note: For summon the current help is anyways incorrect as you cannot set only one coordinate, or at least it will have no impact on where the entity gets spawned

testfor

/testfor <player> [dataTag]
/testfor <player> [<dataTag>]

testforblock

/testforblock <x> <y> <z> <TileName> [dataValue] [dataTag]
/testforblock <x> <y> <z> <TileName> [<dataValue>] [<dataTag>]

testforblocks

/testforblocks <x1> <y1> <z1> <x2> <y2> <z2> <x> <y> <z> [mode]
/testforblocks <x1> <y1> <z1> <x2> <y2> <z2> <x> <y> <z> [<mode>]

time

/time <set|add|query> <value>
/time set|add|query <value>

title

/title <player> <title|subtitle|clear|reset|times> ...
/title <player> title|subtitle|clear|reset|times ...

tp

/tp [target player] <destination player> OR /tp [target player] <x> <y> <z> [<y-rot> <x-rot>]
/tp [<target player>] <destination player> OR /tp [<target player>] <x> <y> <z> [<y-rot> <x-rot>]

trigger

/trigger <objective> <add|set> <value>
/trigger <objective> add|set <value>

weather

/weather <clear|rain|thunder> [duration in seconds]
/weather clear|rain|thunder [<duration in seconds>]

worldborder

/worldborder <set|center|damage|warning|get|add> ...
/worldborder set|center|damage|warning|get|add ...

xp

/xp <amount> [player] OR /xp <amount>L [player]
/xp <amount> [<player>] OR /xp <amount>L [<player>]

spreadplayers

/spreadplayers <x> <z> <spreadDistance> <maxRange> <respectTeams true|false> <player ...>

<respectTeams true|false> would mean either respectTeams true or false as value. That is not correct. Maybe something like this would make more sense:

/spreadplayers <x> <z> <spreadDistance> <maxRange> <respectTeams> <player ...>

See for example effect as there hideParticles is an argument as well

Proof for the inconsistency

For example the /execute command has this syntax:

/execute <entity> <x> <y> <z> detect <x> <y> <z> <block> <data> <command>

According to all the other commands it should look like this instead:

/execute <entity> <x> <y> <z> <detect> <x> <y> <z> <block> <data> <command>

Another example is the /achievement command:

/achievement <give|take> <stat_name|*> [player]

This would imply that the second argument is either stat_name or * which is not correct. It is a stat name or "*"

Other problems

Some arguments use "...". While that makes sense for commands like scoreboard as after each possible argument follow different other arguments, it does certainly not make sense for

  • /me

  • /tell

The "..." have rather the function to indicate that multiple kinds of this argument can follow as used already for spreadplayers:

/spreadplayers <x> <z> <spreadDistance> <maxRange> <respectTeams true|false> <player ...>
/spreadplayers ~ ~ 1 2 false @p @e[type=!Player]

This means however that the help for scoreboard teams join is incomplete:

/scoreboard teams join <team> [player]
/scoreboard teams join <team> [<player ...>]

and

/tell <player> <private message ...>
/tell <player ...> <private message>

Linked issues

Comments 19

Thank you, I wasn't aware of the fact that there is a standard...

Still in 1.9.1-pre3

You suggest a kinda new syntax, with some new rules, but the question is : "Is the current syntax inconsistent?". Mojang apparently never pretended to follow any kind of known command syntax specifications. So I looked at all the current command usage syntax, and I tried to understand the current rules.

Here are the rules I find :

  • text = required literal

  • <arg> = required argument

  • <text1|text2> = required one of the literal

  • [arg] = optional argument

  • [arg1|arg2] = optional argument (arg1 and arg2 are a different type of input)

  • [<arg1> <arg2>] = optional arguments, either both have to be provided or both have to be omitted

  • /cmd ... = command continue

  • [arg ...] OR <arg ...> = multiple argument can be specified

  • /cmd1 OR /cmd2 = Different command syntax

Some inconsistencies you describe are not :

  • In the /execute command (and in the second OR branch), detect is a required literal, so it must be written a plain text, and not <detect>

  • About <name|*>, this one is a special case. It should be interpreted as 2 required literals, but it's not because * mean "all the possible argument".

  • ... is not inconsistent, it just has different meaning depending if it's at the end of the command, or inside [] or <>

  • /tell <player> <private message ...> This syntax is correct, your suggested one is not. What is not specified is that you can use selectors as a message argument

Your syntax replace all [arg] into [<arg>] just to make room for a [text] as optional literal, but this syntax is almost never used. That's what the big OR is used to.

You also replace all <text1|text2> by text1|text2, and this suggestion make sense, but the current syntax is still valid and consistent.

Instead of changing 90% of the command usages as you suggest, we just need to change some few ones:

Here ips and players are literal, so they can't be in the same []

/banlist [ips|players]
/banlist OR /banlist <ips|players>

In this case, address and name are arguments, so they can't be in the same <> as they will be interpreted a literals

/ban-ip <address|name> [reason ...]
/ban-ip <address> [reason ...] OR /ban-ip <name> [reason ...]
or
/ban-ip <address OR name> [reason ...]

As you noted, the following ones are real inconsistancies or mistakes (+from related issues):

/spreadplayers <x> <z> <spreadDistance> <maxRange> <respectTeams true|false> <player ...>
/spreadplayers <x> <z> <spreadDistance> <maxRange> <respectTeams> <player ...>
/summon <EntityName> [x] [y] [z] [dataTag]
/summon <EntityName> [<x> <y> <z>] [dataTag]
/scoreboard teams join <team> [player]
/scoreboard teams join <team> [player ...]

... can also solve this syntax problem, but it's less convinient to see and understand how the command is working

/scoreboard players tag <player> <add|remove|list> <tagName> [dataTag]
/scoreboard players tag <player> <add|remove> <tagName> [dataTag] OR /scoreboard players tag <player> list
/fill <x1> <y1> <z1> <x2> <y2> <z2> <TileName> [dataValue] [oldBlockHandling] [dataTag]
/fill <x1> <y1> <z1> <x2> <y2> <z2> <TileName> [dataValue] [oldBlockHandling] [dataTag] OR /fill <x1> <y1> <z1> <x2> <y2> <z2> <TileName> [dataValue] replace <TileName> [dataValue]

I agree that the current syntax is weird when it comes to know if an argument is a literal are not. But despite what you can think, it is consistent. Changing the syntax as you suggest is not totally justified. Seeing the related issues, you have to keep in mind that the command usage is just an indication, complex commands can't be explained in a single line, and Mojang probably want the indication as simple as possible, instead of being complex but complete, as long as the tab completion is correct, the command usage can omit some detail to make things easier ([oldBlockHandling] could be replaced by [destroy|hollow|keep|outline|replace], but it's not needed thanks to tab completion)

9 more comments

There is /tp [target entity] <destination entity> and /tp [target entity] <x> <y> <z> .... In both cases an optional argument is left out in between. This is not exactly what you are searching for but similar.

In my opinion these cases should not exist since you either need to use the command length to determine which argument is which or you will have to guess. Maybe it should rather be like /give or /replaceitem where you always have to specify the target player.

A list of commands that should be changed as you described is in MC-108965. That would also automatically "fix" MC-79677 by making it impossible to encounter.

I think these cases are fine since there the optional argument is not in between.

In 1.13 all usage text is automatically generated based on context (how far in a command you got), your permissions, and your language. Argument names are translated, literals are not.

Examples for syntax are as follows:

literal
[optionalLiteral]
<argument>
[<optionalArgument>]
(literal|otherLiteral)
(literal|<argument>)

This isn't complete yet though so I'm keeping this issue open for now.

marcono1234

Nathan Adams

Confirmed

/help, command, inconsistent, syntax

Minecraft 1.8.6, Minecraft 15w35b, Minecraft 1.9, Minecraft 1.9.1 Pre-Release 3, Minecraft 1.9.4, ..., Minecraft 17w14a, Minecraft 17w15a, Minecraft 17w17a, Minecraft 17w17b, Minecraft 1.12 Pre-Release 2

Minecraft 17w45a

Retrieved