Hey!
With the 1.13 and the addition of datapacks, the number of possibilities for map makers or simply datapack makers has been greatly increased.
But with these many additions a lack begins in my opinion to appear: the excessive lack of interaction between the player and the packs.
Indeed, the only way for the latter to interact with is via sign, redstone or tellraw. But in each it remains very bit, it is hardly possible for example to ask the player for a value. We can of course go through the tellraw, simulating a numeric keypad, then multiplying each value clicked by 10 at each click and adding the different numbers to reconstruct the entry but it is very tedious.
Here is the reason for my suggestion, a new data for datapack allowing to create simple commands through JSON.
I propose you to illustrate all this with a simple example.
Suppose that in my datapack, I want to give a certain number of cookies to the player, but that I want to let him choose the number, we can imagine this command:
/cookie 128
which will give 128 cookies to the player executing the command. Here's from a JSON perspective what it might look like:
{
"cookie": {
"description": "Allow to give a number of cookies at yourself",
"only_op": false,
"arguments": [
{
"number": {
"type": "integer",
"set_in_score": {
"objective": "Cookie",
"selector": "@s"
}
}
}
],
"execute": {
"commands": [
"function foo:cookie"
]
}
}
}
To explain, "cookie" at line 2 corresponds to the command itself, "description" is pretty self explanatory, and "only_op" corresponds to the fact that the command is only executable by operator players. "number" at line 7 correpond to the value being free to be chosen by player (the keyword is free too), and "type", the type, is an integer to grasp.
We will save the entered integer in the Cookie scoreboard to the player @s (so the executor) by the key "set_in_score".
Once done, we execute the commands that are in value of the keyword "commands", ie "foo:cookie".
And here is the content of foo: cookie:
execute if score @s Cookie > 0 give @s cookie
execute if score @s Cookie > 0 scoreboard players remove @s Cookie 1
execute if score @s Cookie > 0 run function foo:cookie
There are plenty of possibilities with that, like the simple alias of a command /function, because this command can very quickly become very big on a big datapack and it would allow to "secure" a little bit by being able to ask the user to type a command that affects the pack while maintaining control over the entered values.
But also as seen here, the ability to create simple commands to promote interaction for example.
All of that would be very good, but we can see even further!
Let's repeat the same example, but this time, we want to limit the number of cookies that the player can give himself (a negative number for example does not really make sense) while leaving him the opportunity to choose another player that himself:
{
"cookie": {
"description": "Allow to give a number of cookies at a player",
"only_op": false,
"arguments": [
{
"number": {
"type": "integer",
"conditions": {
"matches": "0..150",
"error_message": "Invalid value entered."
},
"set_in_score": {
"objective": "Cookie",
"selector": "@s"
},
"arguments": [
{
"player": {
"optional": true,
"default": "@s",
"type": "selector",
"conditions": {
"type": ["players"],
"limit": 1,
"error_message": "Invalid selector entered."
}
}
}
]
}
}
],
"execute": {
"commands": [
"execute as %player% run function foo:cookie"
]
}
}
}
Corresponding to the following syntax:
/cookie (number) [player]
For the explanations, one can already see the addition of the key "conditions" which makes it possible to restrict the value entered, in the case of number for example, the value must be between 0 and 150, after a tag "error_message" corresponding to the returned message if this condition is not met.
Then, the add the key "arguments", simply representing the element that will follow the one in which the key is present. Here, as the key is in "number", the values specified in "arguments" will be added afterwards.
There is then a key "player" (key whose name is again chosen by the creator).
The "optional" key allows to define the argument as not being obligatory, one then specifies that the type is a selector and one adds there for condition a restriction of type (thus the target entity must be a player) and a number restriction (only one person), I do not think more restrictions are needed, these are really the most important in my opinion.
These two restrictions would work in the same way as "limit" in the /data command.
Last difference in the command executed: at the end where we can see a %player% in the command.
This %player% tag directly refers to the "player" key of the command, so the tag will be replaced by what has been entered by the player. This is where the key "default" takes its meaning, it is the value that will take the tag if the user has decided to leave the argument empty (as the latter is optional).
To finish, An example a bit more complex.
Suppose a command like this:
/cookie (number) entity (selector)
/cookie (number) block (x y z)
Where the first command set the item in the inventory of the entity and the second place a chest at the coordinates with the cookie(s) inside.
The JSON syntax:
{
"gift": {
"description": "Do a gift",
"only_op": false,
"arguments": [
{
"number": {
"type": "integer",
"set_in_score": {
"objective": "Cookie",
"selector": "@s"
},
"arguments": [
{
"entity": {
"type": "keyworld",
"save_in_score": {
"objective": "Gift",
"entity": "@s",
"operation": "=",
"value": 0
},
"arguments": [
{
"selector": {
"type": "selector",
"condition": {
"type": ["player", "skeleton", "zombie", "wither_skeleton", "stray", "zombie_villager", "husk", "villager"],
"error_message": "Invalid selector entered."
}
}
}
]
},
"block": {
"type": "keyworld",
"save_in_score": {
"objective": "Gift",
"selector": "@s",
"operation": "=",
"value": 1
},
"arguments": [
{
"selector": {
"type": "player"
}
}
]
}
}
]
}
}
],
"execute": {
"commands": [
"execute if score @s Gift match 0 as %selector% run function foo:gift_entity",
"execute if score @s Gift match 1 positioned %selector% run function foo:gift_entity"
]
}
}
}
So in this part, we introduct keywords like some Minecraft commands to propose a variant to the command. This keyword can be represented by a score that will be used in the executed commands (last key) to separate the different branches. So the key "save_in_score" allows to add a new value to the specified entity, in the specified objective. The "operation" key represents the operation (yes yes) that will be realised in the specified score, here, @s Gift will be worth 1.
In short, as you can see, there are plenty of possibilities and this feature could be really useful! Here, I only show examples with selectors and numbers, but we could imagine that with blocks, entities and even items!
For the possible problems of already existing commands (in the case where the creator wishes for example to make a command / help), it will be enough to play on the order of the datapacks, the command called by default being that of the highest datapack. But despite the order, if you want to run the command of a datapack lower, we can always do that through a /foo:bar!
Here for my proposal, of course, all these are just ideas, whether in JSON formatting or otherwise. But I hope to have your opinion and your ideas for improvement!
Please sign in to leave a comment.
13 Comments