/execute if|unless function <function>
works normally in chat.
However, if run through a datapack /execute if <function>
always fails regardless of the <function>
's return value and /execute unless <function>
always succeeds.
A succeessful call is defined as a function that:
Uses the return command to return a value
The return value is not 0
Steps to reproduce:
Create two functions, one that always returns 0 and another that always returns something other than 0.
Run these four commands in chat to get correct behaviour:
/execute if function a:return_0
>Test failed
/execute if function a:return_5
>Test passed
/execute unless function a:return_0
>Test passed
/execute unless function a:return_5
>Test failed
✅ The second and third commands are successful.
Create a function to run these commands:
execute if function a:return_0 run say success 1
execute if function a:return_5 run say success 2
execute unless function a:return_0 run say success 3
execute unless function a:return_5 run say success 4
/function a:test
>Executed 12 commands from function 'a:test'
>success 3
>success 4
❌ The third and fourth commands are successful.
Datapack:
[media]Linked issues
Attachments
Comments 2
The main problem about the current implementation is that /execute if|unless function ... assumes that the function being called will be finished after executing ServerFunctionManager.execute(...). This is not the case when in a function because function calls are always postponed by design to prevent infinite recursion. That means that the naive approach of call the function(s), get the result, make a condition, done will not work in the current system. A possible different approach (when it is run in a function) would be to run the function(s) with an added return value consumer (assuming MC-262027 will be fixed). The return value consumer should take note of whether there was a non-zero return value and, if it notices all of the commands have been run, check the condition and potentially run the command. Problem: To my knowledge the current command system (brigadier) doesn't work like that. So essentially you would need to change the command system to make redirects more powerful unless there is a better solution (I mean, this is just a suggestion, after all). Generally, I can say that implementing this command would probably be much more complicated than whoever tried to implement it thought, but it would probably still be worth it: The execute if function command would probably be the easiest way to filter entities if predicates aren't enough.
Seems likea duplicate of MC-264626, however, this is explained a lot better than that one.