Open iiMidknightii opened 6 months ago
You suggested lambdas specifically, but I think users would expect this to work with any Callable
. This is problematic because standard Callable
s require an instance and a method name. There is no method pointer concept, so Callable
in GDScript is not a constant expression.
In theory, this could work for GDScriptLambdaCallable
, but not for GDScriptLambdaSelfCallable
(lambdas that access self
, properties, methods and signals). But at the moment this is not supported in core, Callable
and Signal
cannot be serialized. When deserializing, GDScript must compile individual lambdas, which is not currently provided.
Personally, editing code in a small inspector field looks inconvenient. This will also require embedding a script editor into the inspector if we want to get highlighting, autocompletion, etc.
I think the most achievable at the moment is to export the method name as a String
using the existing Select Method dialog. This will not allow you to enter arbitrary code in the inspector, however.
I'm not super familiar with how lambdas vs callables work under the hood, but I knew that since method callables require an instance and method, this feature would probably only work with lambdas.
My intended use case would be for the user to input small, predefined lambdas to tweak what logic gets executed at specific points of time per-instance. For example, say you have a State
node, and you want to customize what happens when the jump
button is pressed. Instead of a script for every possible permutation of that State
, you could export an on_jump_pressed
lambda with parameters self: Node
and return void
. Maybe even provide a default lambda for if the user doesn't want to do anything different. Then in the node's _ready
, the lambda could be connected to a signal or called in _input
with self
as the input argument.
I do like the other option of allowing it to be serialized as a String
. I'd still want it to be something customizable per-instance instead of just pointing to other existing methods. Perhaps method callables would be possible if there was a way to dynamically create a callable using only String
. Like a GDScript method create_callable_from_string
or similar.
Another use case I thought of is the AnimationTreeNode
. The current expressions could be expanded into full lambdas (or scripts) with syntax highlighting and the expression Node
could be passed in as an argument. I think there might be a few places where custom script logic could be inserted into existing Node
and Resource
scripts to customize run-time instance behavior without the need for full scripts and inheritance to get involved.
Describe the project you are working on
Any game that needs dynamic, controlled logic to be customized per-instance and called later.
Describe the problem or limitation you are having in your project
Currently, there is no way to customize callbacks as a way to customize logic per instance. This is something that can be useful in a large number of circumstances, such as state machines, status effects with custom logic processing, or any instance that differs from other instances by only small changes in logic.
Describe the feature / enhancement and how it helps to overcome the problem or limitation
I propose GDScript adds an annotation for exporting a lambda function to the editor. It could be called
@export_lambda
or@export_callable
. The arguments of the callable could be the argument names/types, and the last argument to the callable could be the return type. This would allow for explicit typing to make sure the lambda always fits the expected callback context.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
Currently, when exporting
Callable
, there is a dead button shown. I think it would instead show a code editor with the function definition filled out at the top (greyed out or otherwise to indicate this is not editable in the editor). From there, the user is able to write out the logic of the callable. I think it should probably only allow usage of passed in parameters, constants, or static variables since other local variables are probably not around for capture during the creation of the variable's value. On the other hand, if assigned via script, the callable could probably do whatever is allowed currently when setting callable variables.If this enhancement will not be used often, can it be worked around with a few lines of script?
I don't know of any way to export a callable, lambda, or custom logic to the editor other than modification to the engine.
Is there a reason why this should be core and not an add-on in the asset library?
I don't know if annotations or callable export behavior can be modified by add-on.