Uploaded image for project: 'Minecraft: Java Edition'
  1. Minecraft: Java Edition
  2. MC-264595

Return command cannot run function when inside another function

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • 23w41a
    • 23w31a, 23w32a
    • None
    • Confirmed
    • Commands
    • Normal
    • Platform

      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 {
                     // ...
                  }
                  // ...
               }
               // ...
          }
      

            boq [Mojang] Bartosz Bok
            coehlrich coehlrich
            Votes:
            31 Vote for this issue
            Watchers:
            21 Start watching this issue

              Created:
              Updated:
              Resolved:
              CHK: