Is there any way to run a given string at runtime? I have tried to write something like this by creating a new node and attaching a new script to it, and I have gotten this far:
var new_node:Node = Node.new()
add_child(new_node)
var new_script:GDScript = GDScript.new()
new_script.source_code = "extends Node\nfunc run():\n\t" + script_to_execute
print(new_script.source_code)
new_node.set_script(new_script)
pressed.connect(new_node.call.bind("run"))
This gets an error (but not a crash) when hitting that last line:
emit_signalp: Error calling from signal 'pressed' to callable: 'Node::call': Method not found.
This is pretty weird, as a Node should always have access to the method “call”. Does someone have an idea on how to solve this / their own idea on how to implement runtime code editing and executing?
Are you perhaps looking for an Expression?
I think that is probably as close as you can get to what you want to do.
This seems to be the exact thing I am searching for, thanks! I have run into an interesting hickup tho. One can pass self to the expression so that it uses the node as the base, but the expression doesn’t seem to have access to autoloads. The error I’m getting there looks something like this: Invalid named index ‘ExampleAutoload’ for base type Object EDIT: Turns out I need to pass these individually as arguments essentially.
This sounds like a dangerous idea (arbitrary code execution by an attacker), what is your use case?
This is really just an internal tool I want to build. This will not be exposed to the player,
If it’s connected to a network it’s not enough that it’s an internal tool. Don’t open yourself up to a coworker executing code on your machine as you.
Okay this is reasonable… I should have clarified that i am the only worker (don’t own a company or anything) so i think it’ll be fine
found a few examples of how to do it on a github issue:
var script = GDScript.new() script.source_code = "func say_hello():\n\tprint(\"Hello!\")" script.reload() var script_instance = script.new() script_instance.call("say_hello")
var MyClass = load("myclass.gd") var instance = MyClass.new() assert(instance.get_script() == MyClass)