mojira.dev
MC-264595

Return command cannot run function when inside another function

When using 

return run function <function>

in a function then the calling function will immediately return 0 instead of executing the called function.

With the attached datapack applied when the bug:nested function is run the function will run a say command and return 1 but when running the bug:main function the function will immediately return 0 without running the say command even though it contains

return run function bug:nested

which should both run the bug:nested function and return the return value of the function.

Code Analysis

net.minecraft.server.ServerFunctionManager

class ExecutionContext {
      // ...
      // This method runs when a function is called while a function is already being executed and then a 0 is returned after calling this method
      void delayFunctionCall(CommandFunction p_179973_, CommandSourceStack p_179974_) {
         // ...
         if (this.commandQueue.size() + this.nestedCalls.size() < i) {
            // This adds the commands in the called function to nestedCalls
            this.nestedCalls.add(new ServerFunctionManager.QueuedCommand(commandsourcestack, this.depth, new CommandFunction.FunctionEntry(p_179973_)));
         }
      }
      // ...
      // This method is called when a function is going to execute and another function is not already executing
      int runTopCommand(CommandFunction p_179978_, CommandSourceStack p_179979_) {
         // ...
         while(!this.commandQueue.isEmpty()) {
            try {
               // ...
               // This will execute the command at the end of the queue which in the case of a function command will run the delayFunctionCall method instead of runTopCommand and return 0
               serverfunctionmanager$queuedcommand.execute(ServerFunctionManager.this, this.commandQueue, i, this.tracer);
               // abortCurrentDepth will be set to true when the return command is run
               if (!this.abortCurrentDepth) {
                  if (!this.nestedCalls.isEmpty()) {
                     // This will add all the commands in the nestedCalls list to the command queue only when the return command wasn't run.
                     Lists.reverse(this.nestedCalls).forEach(this.commandQueue::addFirst);
                  }
               } else {
                  // Clears the commands that were added by the current executing function and resets the abortCurrentDepth field
               }
               // This will empty the nestedCalls list even though when return run function <function> is run this will contain the commands that were in the called function preventing those commands from running
               this.nestedCalls.clear();
            } finally {
               // ...
            }
            // ...
         }
         // ...
    }

Linked issues

Attachments

Comments 3

This is also the case with any form of return run function, even when run from the chat command line.

I think this has something to do with MC-262027, the basic problem is that the result consumer of /return run is executed when the /function command is executed.

coehlrich

boq

Confirmed

Platform

Normal

Commands

23w31a, 23w32a

23w41a

Retrieved