Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add mkdocs for documentation to deploy to gh-pages #171

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .github/workflows/gh_pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: 📑 GitHub Pages
on:
push:
branches:
- "master"
- "3.4"
- "4.1"

permissions:
contents: write

jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: 3.x
- run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
- uses: actions/cache@v3
with:
key: mkdocs-material-${{ env.cache_id }}
path: .cache
restore-keys: |
mkdocs-material-
- run: pip install mkdocs-material
- run: mkdocs gh-deploy --force
285 changes: 21 additions & 264 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# JavaScript language binding for Godot game engine
# GodotJS - JavaScript language binding for Godot game engine

This module implements JavaScript/TypeScript language support for the Godot game engine using [QuickJS](https://bellard.org/quickjs/) as the JavaScript engine.

Expand All @@ -13,275 +13,32 @@ This module implements JavaScript/TypeScript language support for the Godot game
- Full code completion support for all Godot APIs including signals and enumerations
- Debug in Visual Studio Code with the [plugin](https://marketplace.visualstudio.com/items?itemName=geequlim.godot-javascript-debug) - currently not available for 4.x

## Installation
### Getting started

No installation or setup necessary. The binaries for download are the complete, usable Godot editor and engine with JavaScript/TypeScript language support.

## Download

You can try the pre-compiled binaries from the [release page](https://github.com/GodotExplorer/ECMAScript/releases) or get the binaries with the latest commits from the [GitHub build action result](https://github.com/GodotExplorer/ECMAScript/actions).

## Compilation

1. Clone the source code of [godot](https://github.com/godotengine/godot)
2. Clone this module and put it into `godot/modules/` and make sure the folder name of this module is `javascript`
3. [Recompile the godot engine](https://docs.godotengine.org/en/4.1/development/compiling/index.html) - Use ``scons`` with those additional options ``warnings=extra werror=yes module_text_server_fb_enabled=yes`` to show all potential errors

![Build Godot with ECMAScript](https://github.com/GodotExplorer/ECMAScript/workflows/Build%20Godot%20with%20ECMAScript/badge.svg)

## Usage

### How to export script class to Godot

1. Define your JavaScript class and inherit from a Godot class, then export it as the **default** entry:

```js
// The default export entry is treated as an exported class to Godot
export default class MySprite extends godot.Sprite {
// this is _init() in GDScript
constructor() {
super();
}

_ready() {}

_process(delta) {}
}
```

2. Save the script with extension `.mjs`
3. Attach the script file to the node or resource object like you do with GDScript

### How to export signals

```js
export default class MySprite extends godot.Sprite {}
// register game_over signal to MySprite class
godot.register_signal(MySprite, "game_over");
```

### How to export properties

```js
export default class MySprite extends godot.Sprite {
_process(delta) {
// Yes! We can use operators in JavaScript like GDScript
this.position += this.direction * delta;
}
}
// export 'direction' properties to MySprite Godot inspector
godot.register_property(MySprite, "direction", new godot.Vector2(1, 0));
```

There are 2 ways of using the `godot.register_property`. The third parameter can either be a default value for the property you're trying to export or an object giving a more detailed description of how the editor should show it.

```js
function register_property(target: GodotClass | godot.Object, name: string, value: any);
function register_property(target: GodotClass | godot.Object, name: string, info: PropertyInfo);
```

So calling the `register_property` like this:

```js
godot.register_property(MyClass, "number_value", 3.14);
```

Is the simplified version of:

```js
godot.register_property(MyClass, "number_value", {
type: godot.TYPE_REAL,
hint: godot.PropertyHint.PROPERTY_HINT_NONE,
hint_string: "",
default: 3.14,
});
```

For more detail on how to use it, [click here](https://github.com/Geequlim/ECMAScript/issues/24#issuecomment-655584829).

### About the API
Read the [getting-started](https://geequlim.github.io/ecmascript/getting-started).

All of Godot's APIs are defined within the `godot` namespace.
## Getting the engine

No API names have been renamed or changed, so you shouldn't need to change your habits.

| GDScript | JavaScript |
| ---------------------- | ---------------------------- |
| null | null |
| int | number |
| float | number |
| String | string |
| Array | Array |
| Dictionary | Object |
| NodePath | string |
| Object | godot.Object |
| Resource | godot.Resource |
| Vector2 | godot.Vector2 |
| 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 |

#### API specification:

- Keys of Dictionary are converted to String in JavaScript
- Signals are defined as constants to their classes
```
godot.Control.resized === 'resized' // true
```
- Additional functions
- `godot.register_signal(cls, signal_name)` to register signals
- `godot.register_property(cls, name, default_value)` to define and export properties
- `godot.register_class(cls, name)` to register named class manually
- `godot.set_script_tooled(cls, tooled)` to set `tooled` of the class
- `godot.set_script_icon(cls, path)` to set icon of the class
- `godot.get_type(val)` Returns the internal type of the given `Variant` object, using the `godot.TYPE_*`
- `godot.yield(target, signal)` Returns a Promise which will be resolved when the signal emitted
- `requestAnimationFrame(callback)` registers a callback function to be called every frame, returns a request ID.
- `cancelAnimationFrame(request_id)` to cancel a previously scheduled frame request
- `require(module_id)` to load a CommonJS module or load a resource file
- `$` is the alias of `Node.get_node`
- Using signals in the ECMAScript way
- Allow passing functions for `godot.Object.connect`, `godot.Object.disconnect`, and `godot.Object.is_connected`
```js
this.panel.connect(godot.Control.resized, (size) => {
console.log("The size of the panel changed to:", size);
});
```
- Using `await` to wait for signals
```js
await godot.yield(
this.get_tree().create_timer(1),
godot.SceneTreeTimer.timeout
);
console.log("After one second to show");
```
- Preload resources with ECMAScript import statement
```js
import ICON from "res://icon.png";
```
- Multi-threading with minimal [Worker API](https://developer.mozilla.org/en-US/docs/Web/API/Worker) (**This is an experimental feature**)

- Start a new thread with Worker
```js
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] received message from worker thread:", msg);
};
```
- Transfer value in different thread context with `godot.abandon_value` and `godot.adopt_value`

```js
// In worker thread
let id = godot.abandon_value(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 = godot.adopt_value(msg.id);
}
};
```

### TypeScript support

- Run the menu command `Project > Tools > JavaScript > Generate TypeScript Project` from the Godot editor to generate a TypeScript project
- Run `tsc -w -p .` under your project folder in the terminal to compile scripts

#### Code completion

- Code completion in TS will automatically work once the TypeScript project is generated by the above steps.
- Code completion in VSCode is achieved by the property `"types": "./godot.d.ts"` in the generated package.json file of the TypeScript project. The `godot.d.ts` file can be generated alone via the `Project > Tools > ECMAScript > Generate TypeScript Declaration File` editor menu option and added to a `package.json` file manually to achieve this without a full TypeScript project.

#### Example TypeScript Usage

Compile your `ts` script to a `.mjs` file then we can attach it to a node in godot editor.

Most of the `register` functions are available as various decorators as seen below.

```ts
import { signal, property, tool, onready, node } from "./decorators";

@tool // make the script runnable in godot editor
export default class InputLine extends godot.HBoxContainer {
// define a signal
@signal
static readonly OnTextChanged: string;

// expose a node property
@node
icon: godot.Sprite;

// register offset property with the godot inspector with default value of Vector2(0, 0)
@property({ default: godot.Vector2.ZERO })
offset: godot.Vector2;

// register properties for godot editor inspector
@property({ type: godot.VariantType.TYPE_STRING })
get title() {
return this._title;
}
set title(v: string) {
this._title = v;
if (this._label) {
this._label.text = v;
}
}
private _title: string;

@property({ default: "Input text here" })
get hint() {
return this._hint;
}
set hint(v: string) {
this._hint = v;
if (this.edit) {
this.edit.hint_tooltip = v;
this.edit.placeholder_text = v;
}
}
private _hint: string;

get label(): godot.Label {
return this._label;
}
protected _label: godot.Label;

// call get_node('LineEdit') and assign the returned value to 'this.edit' automatically when the node is ready
@onready("LineEdit")
edit: godot.LineEdit;

get text(): string {
return this.edit?.text;
}

_ready() {
// get first child with the type of godot.Label
this._label = this.get_node(godot.Label);
No installation or setup necessary. The binaries for download are the complete, usable Godot editor and engine with JavaScript/TypeScript language support.

// Apply the inspector filled values with property setters
this.title = this.title;
this.hint = this.hint;
### Binary downloads
Download the binaries from the [release page](https://github.com/GodotExplorer/ECMAScript/releases).

this.edit.connect(godot.LineEdit.text_changed, (text: string) => {
this.emit_signal(InputLine.OnTextChanged, text);
});
}
}
```
### Compiling from source
- Clone the source code of [godot](https://github.com/godotengine/godot):
- ``git clone git@github.com:godotengine/godot.git`` or
- ``git clone https://github.com/godotengine/godot.git``
- Clone this module and put it into `godot/modules/javascript`:
- ``git clone git@github.com:Geequlim/ECMAScript.git godot/modules/javascript`` or
- ``git clone https://github.com/Geequlim/ECMAScript.git godot/modules/javascript``
- [Recompile the godot engine](https://docs.godotengine.org/en/4.1/development/compiling/index.html)
- Use ``scons`` with those additional options ``warnings=extra werror=yes module_text_server_fb_enabled=yes`` to show all potential errors

## Demo
## Documentation, Tutorials & Demos

You can try demos in the [ECMAScriptDemos](https://github.com/Geequlim/ECMAScriptDemos)
Read this [documentation](https://geequlim.github.io/ecmascript/getting-started) or look at the tutorials or demos:

## Developer notes

- This package is not compatible with MSVC, you will get build errors in quickjs.
- The script also build the `on_tag.yml` script which automates the github release publishing.
\*\* The `on_tag.yml` functionality tries to sleep until all jobs with the same `sha` are completed. It should be fine to run whenever, but depending on how github actions culls long running jobs you might want to make sure that all/(most of) the builds look good before tagging.
- They should definitely be fixed & enabled at some point, **so please submit a PR if you have any ideas of how to do that!**
- [ECMAScriptDemos](https://github.com/Geequlim/ECMAScriptDemos) - Demos
- [godot-ECMAScript-cookbook](https://github.com/why-try313/godot-ECMAScript-cookbook/wiki) - Tutorial
- [godot-typescript-starter](https://github.com/citizenll/godot-typescript-starter) - Template
Loading
Loading