diff --git a/docs/documentation/getting-started.md b/docs/documentation/getting-started.md index 331847d..674668b 100644 --- a/docs/documentation/getting-started.md +++ b/docs/documentation/getting-started.md @@ -18,19 +18,6 @@ godot --version ## Create a new project -### Automatically with [godot-ts](https://github.com/godotjs/godot-ts) - -1. Run `npx -y @godot-js/godot-ts init` (new project will be crated at your current terminal path) -2. Follow the prompts -3. Run `cd ` -4. Run `npm i` -5. Run `npm run dev` - this will enable typescript watch mode and opens the editor -6. Inside the editor [install preset files](#install-preset-files) via `Project > Tools > GodotJS > Install Preset files` -7. Click `OK` to confirm a list of files will be generated in the project. -8. Attach the `example.ts` script to a node and run the project - -### Manually - 1. Run `godot -p` and create a new project 2. Inside the editor [install preset files](#install-preset-files) via `Project > Tools > GodotJS > Install Preset files` 3. Click `OK` to confirm a list of files will be generated in the project. @@ -58,7 +45,7 @@ Open the project folder in you IDE, you should see full TypeScript support! ![Type Hint](images/tsproj_type_hint.png) -## Compile TypeScript Sources without [godot-ts](https://github.com/godotjs/godot-ts) +## Compile TypeScript Sources Before your scripts runnable in _Godot_, run `tsc` to compile typescript sources into javascript. diff --git a/docs/documentation/godot-js-scripts/annotations.md b/docs/documentation/godot-js-scripts/annotations.md new file mode 100644 index 0000000..cd25ba0 --- /dev/null +++ b/docs/documentation/godot-js-scripts/annotations.md @@ -0,0 +1,169 @@ +# Annotations + +There are several annotations to help you define properties, signals, and other metadata for Godot objects. + +All annotations are accessed through the `createClassBinder` function: + +```ts +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); +``` + +## Signal annotation + +You can define signals in your script using the `@bind.signal()` decorator: + +```ts +import { Node, Signal } from "godot"; +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); + +@bind() +export default class MyJSNode extends Node { + @bind.signal() + accessor test!: Signal<(param1: string) => void>; +} +``` + +For more information about signals, check this [link](signals.md). + +## Tool annotation + +If a GodotJS class is annotated with `@bind.tool()`, it'll be instantiated in the editor. + +```ts +import { Node } from "godot"; +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); + +@bind() +@bind.tool() +export default class MyTool extends Node { + _ready() { + // This code will run in the editor + console.log("MyTool is running in the editor"); + } +} +``` + +For more information about running code in editor, check this [link](code-in-editor.md). + +## Icon annotation + +An icon can be used as node icon in the editor scene hierarchy with the annotation `@bind.icon()`. + +```ts +import { Sprite2D } from "godot"; +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); + +@bind() +@bind.icon("res://icon/affiliate.svg") +export default class MySprite extends Sprite2D {} +``` + +![icon annotation](images/script_icon_annotation.png) + +## Export Annotation + +In `GodotJS`, class member properties/variables can be exported. +This means their value gets saved along with the resource +(such as the scene) they're attached to. +They will also be available for editing in the property editor. +Exporting is done by using the `@bind.export()` decorator. + +```ts +import { Variant } from "godot"; +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); + +@bind() +export default class Shooter extends Sprite2D { + @bind.export(Variant.Type.TYPE_FLOAT) + accessor speed: number = 0; + + // ... +} +``` + +In this example the value `0` will be saved and visible in the property editor. + +The retrieval of default value is implemented through `Class Default Object (CDO)`. +`GodotJS` will instantiate a pure javascript instance of the script class +(`Shooter` in this example) as `CDO`, then the property value is read from +`CDO` as `default value` in the property editor. + +> **NOTE:** Be cautious when coding within `constructor`, as it is probably called for initializing `CDO`. + +### Basic Use + +```ts +@bind.export(Variant.Type.TYPE_STRING) +accessor address: string = "somewhere"; + +@bind.export(Variant.Type.TYPE_INT) +accessor age: number = 0; +``` + +If there's no default value, `default value` of the given type will be used (`0` in this case). + +```ts +@bind.export(Variant.Type.TYPE_INT) +accessor age: number; +``` + +### Exported Enum Properties + +Enum value properties can be exported with the built-in support in the property editor. + +> **NOTE:** So far, only `int` is supported as enum value. + +```ts +@bind.exportEnum(MyColor) +accessor color: MyColor = MyColor.White; +``` + +The value can be easily chosen from a dropdown list in the editor. + +![enum_prop](images/export_enum_inspector.png) + +## Documentation comments + +You can use [documentation comments](https://docs.godotengine.org/en/stable/tutorials/scripting/gdscript/gdscript_documentation_comments.html) +with custom GodotJS annotations: + +- ``@bind.help("...")`` +- ``@bind.experimental("...")`` +- ``@bind.deprecated("...")`` + +```ts +import { Variant } from "godot"; +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); + +@bind() +@bind.help("This will be shown in the editor when creating a new node of this type.") +export default class TestNode extends Node { + + @bind.experimental("Alternative to [method TestNode.doNewStuff].") + doNewStuff(){ + // ... + } + + doStuff(){ + // ... + } + + @bind.deprecated("Use [method TestNode.doNewStuff] instead.") + doOldStuff(){ + // ... + } + +} +``` \ No newline at end of file diff --git a/docs/documentation/godot-js-scripts/code-in-editor.md b/docs/documentation/godot-js-scripts/code-in-editor.md index 558a757..2ea6697 100644 --- a/docs/documentation/godot-js-scripts/code-in-editor.md +++ b/docs/documentation/godot-js-scripts/code-in-editor.md @@ -4,21 +4,24 @@ > **NOTE:** Read [Godot Docs](https://docs.godotengine.org/en/stable/tutorials/plugins/running_code_in_the_editor.html#what-is-tool) for more details about `@tool`. -If a GodotJS class is annotated with `@Tool()`, it'll be instantiated in the editor. +If a GodotJS class is annotated with `@bind.tool()`, it'll be instantiated in the editor. Call `Engine.is_editor_hint()` in the script to check if it's running in the editor. It's also possible to show warnings on a `Node` on `Scene` panel with `_get_configuration_warnings` defined. Here is a simple example: ```ts import { Engine, PackedStringArray, Sprite2D, Variant } from "godot"; -import { Export, Tool } from "godot.annotations"; +import { createClassBinder } from "godot.annotations"; -@Tool() +const bind = createClassBinder(); + +@bind() +@bind.tool() export default class MyEditorSprite extends Sprite2D { /** * get/set property for `export` (both must be defined) */ - @Export(Variant.Type.TYPE_FLOAT) + @bind.export(Variant.Type.TYPE_FLOAT) get speed(): number { return this._speed; } set speed(value: number) { if (this._speed != value) { @@ -30,8 +33,8 @@ export default class MyEditorSprite extends Sprite2D { /** * plain field for `export` */ - @Export(Variant.Type.TYPE_INT) - unused_int = 0; + @bind.export(Variant.Type.TYPE_INT) + accessor unused_int = 0; private _clockwise = false; private _speed = 0; @@ -82,9 +85,12 @@ This is available in Godot by extending `EditorScript` in a script. This provide ```ts import { EditorScript } from "godot"; -import { Tool } from "godot.annotations"; +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); -@Tool() +@bind() +@bind.tool() export default class MyEditorScript1 extends EditorScript { _run() { console.log("my editor script run"); diff --git a/docs/documentation/godot-js-scripts/decorators.md b/docs/documentation/godot-js-scripts/decorators.md deleted file mode 100644 index 1ea57fd..0000000 --- a/docs/documentation/godot-js-scripts/decorators.md +++ /dev/null @@ -1,114 +0,0 @@ -# Decorators - -There are several decorators to help you define properties, signals, and other metadata for Godot objects. - -## Signal annotation - -You can define signals in your script using the `@ExportSignal` annotation: - -```ts -import { Node, Signal } from "godot"; -import { ExportSignal } from "godot.annotations"; - -export default class MyJSNode extends Node { - @ExportSignal() - test!: Signal<(param1: string) => void>; -} -``` - -For more information about signals, check this [link](signals.md). - -## Tool annotation - -If a GodotJS class is annotated with `tool()`, it'll be instantiated in the editor. - -```ts -import { Node } from "godot"; -import { Tool } from "godot.annotations"; - -@Tool() -export default class MyTool extends Node { - _ready() { - // This code will run in the editor - console.log("MyTool is running in the editor"); - } -} -``` - -For more information about running code in editor, check this [link](code-in-editor.md). - -## Icon annotation - -An icon can be used as node icon in the editor scene hierarchy with the annotation `@icon`. - -```ts -import { Sprite2D } from "godot"; -import { Icon } from "godot.annotations"; - -@Icon("res://icon/affiliate.svg") -export default class MySprite extends Sprite2D {} -``` - -![icon annotation](images/script_icon_annotation.png) - -## Export Annotation - -In `GodotJS`, class member properties/variables can be exported. -This means their value gets saved along with the resource -(such as the scene) they're attached to. -They will also be available for editing in the property editor. -Exporting is done by using the `@Export` annotation. - -```ts -import { Export } from "godot.annotations"; - -export default class Shooter extends Sprite2D { - // type must be explicitly provided as the first parameter of @Export - // cuz static type is actually a phantom in typescript - @Export(Variant.Type.TYPE_FLOAT) - speed: number = 0; - - // ... -} -``` - -In this example the value `0` will be saved and visible in the property editor. - -The retrieval of default value is implemented through `Class Default Object (CDO)`. -`GodotJS` will instantiate a pure javascript instance of the script class -(`Shooter` in this example) as `CDO`, then the property value is read from -`CDO` as `default value` in the property editor. - -> **NOTE:** Be cautious when coding within `constructor`, as it is probably called for initializing `CDO`. - -### Basic Use - -```ts -@Export(Variant.Type.TYPE_STRING) -address: string = "somewhere"; // `:string` can be omitted here - -@Export(Variant.Type.TYPE_INT) -age: number = 0; // `:number` can be omitted here -``` - -If there's no default value, `default value` of the give type will be used (`0` in this case). - -```ts -@Export(Variant.Type.TYPE_INT) -age: number; -``` - -### Exported Enum Properties - -Enum value properties can be exported with the built-in support in the property editor. - -> **NOTE:** So far, only `int` is supported as enum value. - -```ts -@ExportEnum(MyColor) -color: MyColor = MyColor.White; -``` - -The value can be easily chosen from a dropdown list in the editor. - -![enum_prop](images/export_enum_inspector.png) diff --git a/docs/documentation/godot-js-scripts/intro.md b/docs/documentation/godot-js-scripts/intro.md index ff3b0bb..2d5457a 100644 --- a/docs/documentation/godot-js-scripts/intro.md +++ b/docs/documentation/godot-js-scripts/intro.md @@ -64,10 +64,17 @@ export default class MyJSNode extends Node { ## Annotations Annotations are used to define properties, signals, and other metadata for Godot objects. -They are similar to decorators in TypeScript and can be used to enhance the functionality of your scripts. -Check out [decorators](decorators.md) for more information. +They are similar to annotations in TypeScript and can be used to enhance the functionality of your scripts. +Check out [annotations](annotations.md) for more information. ## Auto-Completion and Codegen By default, GodotJS wil auto generate some TypeScript files based on you project. -Check out [auto-completion](auto-completion.md) for more information. +Check out [auto-completion](auto-completion-and-codegen.md) for more information. + +## NPM Dependencies + +Currently, `GodotJS` doesn't provide full support for using code from npm packages. +Because many factors are involved in it, such as: + +- Scripts depend on functionalities of node.js which is not supported \ No newline at end of file diff --git a/docs/documentation/godot-js-scripts/npm-dependencies.md b/docs/documentation/godot-js-scripts/npm-dependencies.md deleted file mode 100644 index 9e2db73..0000000 --- a/docs/documentation/godot-js-scripts/npm-dependencies.md +++ /dev/null @@ -1,30 +0,0 @@ -# NPM Dependencies - -Currently, `GodotJS` doesn't provide sufficient support for using code from npm packages. Because many factors are involved in it, such as: - -- Scripts depend on functionalities of node.js which is not supported -- How the typescript/javascript project is packaged (archive into a single script file or not) -- Javascript modular standard variants may be involved - -## Workaround as bundle - -Try to bundle npm dependencies to an own file to avoid potential conflicts. - -If you use [godot-ts](https://github.com/godotjs/godot-ts) you can create a `*.bundle.ts` file like this: - -```ts npm.bundle.ts -export { default as dayjs } from "dayjs"; -``` - -```ts example.ts -import { Label, Node } from "godot"; -import { dayjs } from "./npm.bundle"; - -export default class Example extends Node { - _ready(): void { - const label: Label = this.get_node("Label"); - - label.text = dayjs().toString(); - } -} -``` diff --git a/docs/documentation/godot-js-scripts/signals.md b/docs/documentation/godot-js-scripts/signals.md index 229aedf..3b4a24a 100644 --- a/docs/documentation/godot-js-scripts/signals.md +++ b/docs/documentation/godot-js-scripts/signals.md @@ -4,17 +4,20 @@ You can define signals based on the amount of arguments you want to pass: ```ts import { Node, Signal } from "godot"; -import { ExportSignal } from "godot.annotations"; +import { createClassBinder } from "godot.annotations"; +const bind = createClassBinder(); + +@bind() export default class MyNode extends Node { - @ExportSignal() - declare no_arg!: Signal<() => void>; + @bind.signal() + accessor no_arg!: Signal<() => void>; - @ExportSignal() - declare one_arg!: Signal<(param1: string) => void>; + @bind.signal() + accessor one_arg!: Signal<(param1: string) => void>; - @ExportSignal() - declare two_args!: Signal<(param1: number, param2: string) => void>; + @bind.signal() + accessor two_args!: Signal<(param1: number, param2: string) => void>; } ``` @@ -75,12 +78,15 @@ export default class MyClass extends Node { A `Signal` can be awaitable in javascript by calling `as_promise()`: ```ts -import { Node, Signal1 } from "godot"; -import { signal } from "godot.annotations"; +import { Node, Signal } from "godot"; +import { createClassBinder } from "godot.annotations"; + +const bind = createClassBinder(); +@bind() class ExampleClass extends Node { - @signal() - declare test_signal!: Signal1; + @bind.signal() + accessor test_signal!: Signal<(value: number) => void>; _ready() { test(); diff --git a/docs/examples/reuse-custom-resources.md b/docs/examples/reuse-custom-resources.md index 7ec1fd1..41b609b 100644 --- a/docs/examples/reuse-custom-resources.md +++ b/docs/examples/reuse-custom-resources.md @@ -7,12 +7,15 @@ This example shows how to create a custom resource and reuse it with different s We create a new file `character-attributes.ts` and add this code to it: ```ts title="character-attributes.ts" -import { Export } from "godot.annotations"; +import { createClassBinder } from "godot.annotations"; import { Resource, Variant } from "godot"; +const bind = createClassBinder(); + +@bind() export default class CharacterAttributes extends Resource { - @Export(Variant.Type.TYPE_INT) - health: number = 5; + @bind.export(Variant.Type.TYPE_INT) + accessor health: number = 5; } ``` @@ -33,15 +36,18 @@ Create a new file `index.ts` and add this code to it: ```ts title="index.ts" import { Node, Variant } from "godot"; -import { Export } from "godot.annotations"; +import { createClassBinder } from "godot.annotations"; import CharacterAttributes from "./character-attributes"; +const bind = createClassBinder(); + +@bind() export default class ResourceExample extends Node { - @Export(Variant.Type.TYPE_OBJECT) - warriorAttributes: CharacterAttributes | undefined = undefined; + @bind.export(Variant.Type.TYPE_OBJECT) + accessor warriorAttributes: CharacterAttributes | undefined = undefined; - @Export(Variant.Type.TYPE_OBJECT) - mageAttributes: CharacterAttributes | undefined = undefined; + @bind.export(Variant.Type.TYPE_OBJECT) + accessor mageAttributes: CharacterAttributes | undefined = undefined; _ready(): void { console.log("warrior health", this.warriorAttributes?.health); diff --git a/mkdocs.yml b/mkdocs.yml index 41d2509..0687d1f 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -12,9 +12,8 @@ nav: - Use External Editor: documentation/use-external-editor.md - Scripting: - Intro: documentation/godot-js-scripts/intro.md - - Decorators: documentation/godot-js-scripts/decorators.md + - Annotations: documentation/godot-js-scripts/annotations.md - Signals: documentation/godot-js-scripts/signals.md - - NPM Dependencies: documentation/godot-js-scripts/npm-dependencies.md - Cyclic Imports: documentation/godot-js-scripts/cyclic-imports.md - Bindings: documentation/godot-js-scripts/bindings.md - Running code in editor: documentation/godot-js-scripts/code-in-editor.md