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?

    • Smorty [she/her]OP
      link
      fedilink
      arrow-up
      10
      ·
      7 months ago

      This is really just an internal tool I want to build. This will not be exposed to the player,

      • pohart@programming.dev
        link
        fedilink
        arrow-up
        5
        ·
        7 months ago

        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.

        • Smorty [she/her]OP
          link
          fedilink
          arrow-up
          7
          ·
          7 months ago

          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

  • sus@programming.dev
    link
    fedilink
    arrow-up
    12
    ·
    edit-2
    7 months ago

    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)
    
    
    • Smorty [she/her]OP
      link
      fedilink
      arrow-up
      4
      ·
      edit-2
      7 months ago

      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.