2

I'm looking for a way to have eval-like functionality, that is, dynamically run a command that is stored as a string somewhere. I have a working solution, however it cannot run synchronously within a function. I'm using the following test.mcfunction:

data modify block 0 56 0 Command set from entity @s SelectedItem.tag.command
data modify block 0 56 0 auto set value 1b
data modify block 0 56 0 auto set value 0b

say after command!

When placing a command block at 0 56 0, then running the following commands...

/give @p minecraft:paper{command: "say command!"}
/function mufmuf:test

... this is the output:

[MechaRage] after command!
Executed 4 commands from function 'mufmuf:test'
[@] command!

You can see that the command block did not react until after the function has finished. My testing with schedule has shown that it takes 2 ticks to catch up (i.e., schedule <function> 1t will still run before the command block, but schedule <function> 2t will correctly run after it).

This is inconvenient, as I have to split my functions into delayed parts, and need to take care not to overwrite any command block that hasn't run yet, stacking several of them instead.

Is there a better, instantaneous way to eval a command?

0

1 Answer 1

3

You can run the function from a command block and in the function you can modify a command block later in the chain.

For example, I just tested this:

Regular command block that points into the chain command block: function test:test
Function file: data merge block <coordinates> {Command:"say a"} with the coordinates of the chain command block
Chain command block: say test

I activated the regular command block and the output was:

[@: Executed 1 commands from function 'test:test']
[@] a

And since it's a command block chain, everything happened in the same tick.

Note that it's impossible to run a function in a new thread or to do anything else in the middle of a function that you didn't specify in the function itself, because the function (and all the functions it calls) are executed as soon as possible, pausing everything else on the server in the meantime. It's true that some actions, like summoning entities, has effects that can be detected rightaway in the function, but none of those things can execute an arbitrary command instantly:

  • setting a command block to auto:1 (even the same one that ran the function)
  • placing an always active command block
  • summoning a command block minecart on an activator rail
  • setting an activator rail at a command block minecart All these actions are triggered after the function ends (or even later, in the case of the command block minecart). There's also no command that executes an arbitrary command based on a string that is stored somewhere, at least in Vanilla. It was suggested and the developers have considered it, but so far only a mod adds it.

So the best you can currently do is to run the command that changes the chain command block's data as the last command in the function (or function call chain) and then do everything later in another function, triggered by another chain command block after that.

2
  • This answer assumes that you know a bit about how computers and programming works, that's why I used terms like "function call chain", "thread", etc. If anything is unclear, just ask. Jan 8, 2020 at 23:53
  • Your answer is clear as day, and the solution to the latency issue is pretty nice -- it also looks better than my auto-flipping kludge. I hope someday a proper implementation will land in vanilla to solve the function splitting and arbitrary number of commands issues, but in the meantime this should do. Thanks a lot!
    – Quentin
    Jan 9, 2020 at 1:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .