This module implements the JavaScript script language support for godot game engine.
QuickJS is used as the ECMAScript engine.
QuickJS is a small and embeddable Javascript engine. It supports the ES2020 specification including modules, asynchronous generators and proxies.
It optionally supports mathematical extensions such as big integers (BigInt), big floating point numbers (BigFloat) and operator overloading.
It is also possible to replace the ECMAScript engine like V8 or SpiderMonkey but not in the near plan.
This project is still in development so it may contain bugs.
- Clone the source code of godot
- Clone this module and put it into
godot/modules/
and make sure the folder name of this module isECMAScript
- Recompile godot engine (Only MinGW is supported on Windows for now!)
- Define your ECMAScript class inhirent from godot class and export it as default entry
// The default export entry is treat as exported class to godot
export default class MySprite extends godot.Sprite {
// this is _init() in GDScript
constructor() {
super();
}
_ready() {
}
_process(delta) {
}
}
- Attach the script file to the node or resource object like you did with GDScript
export default class MySprite extends godot.Sprite {};
// register game_over signal to MySprite class
godot.register_signal(MySprite, 'game_over');
export default class MySprite extends godot.Sprite {
_process(delta) {
// Yes! We can use operators in JavaScript like GDScript
this.position += this.direction * new godot.Vector2(delta, delta);
}
};
// export 'direction' properties to MySprite godot inspector
godot.register_property(MySprite, 'direction', new godot.Vector2(1, 0));
All godot api are define in the godot
namespace.
We didn't change any api name so you don't need to change your habbit at all.
GDScript | ECMAScript |
---|---|
null | null |
int | number |
float | number |
String | string |
Array | Array |
Dictionary | Object |
NodePath | string |
Object | godot.Object |
Resource | godot.Resource |
Vector2 | godot.Vecotor2 |
Color | godot.Color |
sin(v) | godot.sin(v) |
print(v) | godot.print(v) |
PI | godot.PI |
Color.black | godot.Color.black |
Control.CursorShape | godot.Control.CursorShape |
Label.Align.ALIGN_LEFT | godot.Label.Align.ALIGN_LEFT |
-
Keys of Dictionary are converted to String in JavaScript
-
Signals are defined as constants to its classes
godot.Control.resized === 'resized' // true
-
Additional functions
godot.register_signal(cls, signal_name)
to register signalsgodot.register_property(cls, name, default_value)
to define and export propertiesgodot.register_class(cls, name)
to register named class manuallygodot.set_script_tooled(cls, tooled)
to settooled
of the classgodot.set_script_icon(cls, path)
to set icon of the classgodot.get_type(val)
Returns the internal type of the givenVariant
object, using thegodot.TYPE_*
requestAnimationFrame(callback)
to add a callback function to be called every framecancelAnimationFrame(request_id)
to cancel an frame request previously scheduled
-
Using signals in the ECMAScript way
- Allow passing functions for
godot.Object.connect
,godot.Object.disconnect
andgodot.Object.is_connected
this.panel.connect(godot.Control.resized, (size) => { console.log('The size of the panel changed to:', size); });
- Using
await
to wait signalsawait godot.yield(this.get_tree().create_timer(1), godot.SceneTreeTimer.timeout); console.log('After one second to show');
- Allow passing functions for
-
Preload resources with ECMAScript import statement
import ICON from 'res://icon.png';
-
Multi-threading with minimal Worker API
- Start a new thread with Worker
const worker = new Worker('worker.js'); // Run worker.js in a new thread context worker.postMessage({type: 'load_dlc', value: 'dlc01.pck'}); worker.onmessage = function(msg) { console.log("[MainThread] recived message from worker thread:", msg); }
- Tansfer value in different thread context with
Worker.abandonValue
andWorker.adoptValue
// In worker thread let id = Worker.abandonValue(object); postMessage({ type: 'return_value', id: id }); // In the host thread worker.onmessage = function(msg) { if (typeof msg === 'object' && msg.type === 'return_value') { let value_from_worker = Worker.adoptValue(msg.id); } }
- Start a new thread with Worker
-
TypeScript support
- Run the menu command
Project > Tools > ECMAScript > Generate TypeScript Declaration
from godot editor to dump the api declearations - Run the menu command
Project > Tools > ECMAScript > Generate TypeScript Project
from godot editor to generate a TypeScript project
- Run the menu command
You can try demos in the ECMAScriptDemos