How to integrate programming into game

Godot Version

Godot 4.x

Question

I have a game idea there one of the most integral part is to let the player write code.

Are there any good examples how to do that? searching for this is quite difficult.

I do not want to make a own interpreter but would like to integrate a real language like python or typescript. But the user also should not be able to import random modules other than the one provided by the game or the user itself. I imaging it a bit like in Bitburner.

Hello there;

GDScript is compiled to bytecode and run by an interpreter, and that compiler is available at runtime, so you can build a script from a string and load it on the fly:

extends Node2D

class_name script_executer

var helloScript

func _init():
	helloScript = GDScript.new()
	
	# take the source where ever you want
	helloScript.source_code = """
		func run():
			print("Hello")
		""".dedent()
		
	helloScript.reload()

func SayHello():
	var s = helloScript.new()
	s.run()

func _ready() -> void:
	SayHello()

something like this should’ve work. But if you want to interact with the engine, you should’ve implement own engine bridge


If you just need to evaluate one expression (a formula, a condition) rather than a whole script, you can use the Expression class

var e := Expression.new()
e.parse("2 + pow(x, 2)", ["x"])
print(e.execute([5]))   # 27

And of course bring your own, write your own lexer / parser / evaluator in GDScript and also again some godot glue code if you want to interact with the engine and interpret whatever DSL you want.

I wrote an interpreter in GDScript for my own little scripting language. I followed the (very good) Crafting Interpreters book for that, to a degree. My language is pretty simple, so maybe it’s something you could be interested in. I’m open for ideas too.

I do not recommend Kerim’s idea to use GDScript. I looked into that and refrained from it. For example, you can’t put your user’s script in a try…catch block (as GDScript does not have that), so errors in the player’s script are automatically bugs in your own game.

hello there;

I do not recommend Kerim’s idea to use GDScript. I looked into that and refrained from it. For example, you can’t put your user’s script in a try…catch block (as GDScript does not have that), so errors in the player’s script are automatically bugs in your own game.

Yeah, agreed on the try/catch point — that’s exactly why I listed three possible solution rather than recommending just one. Each has its own trade-offs.

Dynamic GDScript is only meant for trusted runtime codegen; for untrusted/moddable input the

third option was to do exactly what you did

write your own lexer/parser/evaluator (+ some engine glue).

So we’re on the same page: custom interpreter is the right call for user-facing scripting.
gompl looks lovely

I think a common language to use in games is LUA, since it has a relative standalone library. as far as I know, it’s only available in C/C++, so you’d need to create a godot extension.

I recently started to implement a compiler/vm for javascript using a port of pegjs to gdscript. I think using your own script, inventing the syntax and the API to your game is a fun undertaking. handling the interaction with your game is a different beast, and it depends on what the “computing bits” of your game is (multiple “computers” (like else.heartbreak), or puzzles like zachtronlcs games, etc.

I would start by identifying what the user would program and how the code interacts with your game world. and you can maybe hack a prototype in one of the languages you want to target, like a mini simulation of your game.

(I need to cleanup my JS project, once I’m finished I can share it here)

Are you the dev of dinosource?

thanks for input. but writing everything completely by my own was something I would like to avoid.

I mean designing a own language definitely is fun - I’ve done that in past for educational reasons - but to make it really usable is an enormous efford. As well for the player that has to learn a language that is of no other use to him.

I was thinking about something like Qt’s QJSEnginewhere you set up the engine. Add “bridge classes” (that expose application-interfaces to the script) to the engine and load a script into it.

The game I have in mind is a bit of a mix of 1988’s Neuromancer’s Matrix vibes and the 2002 Shawn Overcashs Decker but with some kind of automation by user written code like in Bitburner.

So at the end where will be many simultanously running user scripts that may do complex things, so a classic handcrafted interpreter based approach may not fit.

To be honest. The projects concept is not very far atm and its completely unsure if will lead anywhere. But thinking about it and doing little experiments, currently is fun to me.