0 votes

Hi all,

I'm trying to make an extension system for my game so that lightweight custom scripts can be loaded at runtime, passed as strings, using GDScript.setsourcecode. This is an simple example of how I use it

extends Node

var runner = null

func _ready():
   runner = Reference.new()

func _dostuff():
    var script = GDScript.new()
    script.set_source_code("""
extends Reference
var label = null
func change_text():
    label.text = "Hello world"
    """)
    script.reload()
    runner.set_script(script)
    runner.label = get_node("../Label")
    runner.change_text()

When calling dostuff() on the Node that has this script, the runner reference will get a script attached given by the text. This text can define custom behaviour that can be called from the outside (runner.changetext()). It actually works really well for what I want, so that's great.

My only concern is that there seems to be no error control at all in Godot, and I would like to deal with the case that the extension contains invalid code. When running during the tests, it gives an error, of course. I do not want fancy exception handling, just - is there any way to at least ignore the contents of the script gracefully?

Thanks in advance!

asked Feb 15 in Engine by niohiki (15 points)

1 Answer

+1 vote
Best answer

So you are basically doing open modding (with all privileges trust and no sandboxing). There is no error handling of that sort in GDScript that you can catch, because so far it is beyond the scope of what GDScript was built for. So if there is an error in your dynamic script, it will fail just as if it was part of your own scripts.

The Expression class is a building block which can help you building a modding system with error checking, but for actual GDScript you will have to deal with it.

There were a few topics discussed on Github on this subject, all closed:

https://github.com/godotengine/godot/issues/3516

https://github.com/godotengine/godot/issues/7643

You can try explain your use case to them (as everyone had slightly different reasons to want this) but so far things like "exceptions" are not considered. Ignoring errors is probably slightly different as well, I'm not sure what can be done properly about that.

answered Feb 15 by Zylann (19,038 points)
selected Feb 16 by niohiki

Yes, there'd be no sandboxing at all like this, but it is a small project with an educational purpose - I'm not afraid of players hacking the game or anything like that.

I had indeed seen those links, but they seem more concerned about an actual exception system. I thought maybe there could be some option to "ignore" errors for a specific script, or rather something with a "safe" execution context where erroneous state can be checked later. Which is exactly what Expression does, so thanks a lot for that! It does not seem to be able to process conditionals or any other flow control, but it may just do.

Unfortunately, in 3.0.6, when testing the example from the docs I get an error saying Parser Error: Identifier not found: Expression. Not sure if it is a bug or I'm doing something wrong, so I'll look a bit more into it.

Since you mention it, do you know of a good solution for a proper sandboxed scripting engine (language more or less irrelevant)? I guess I'd need to connect something via C#.

The Expression class is only available starting from Godot 3.1.
On the other hand, C# can be an alternative to embed another scripting language, there are implementations of Python and Lua as libraries, although you will have to bind the whole API yourself (which would be the only way to sandbox such a modding environment).

Oh, I see, thanks! I'll probably download the beta then.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.