Cleanups.

This commit is contained in:
Relintai 2024-04-30 20:17:58 +02:00
parent b68153e78d
commit 42ee7816c2
49 changed files with 714 additions and 1258 deletions

View File

@ -1,10 +1,8 @@
Console support in Pandemonium # Console support in Pandemonium
========================
Console publishing process ## Console publishing process
--------------------------
Regardless of the engine used to create the game, the process to publish a game Regardless of the engine used to create the game, the process to publish a game
to a console platform is as follows: to a console platform is as follows:
@ -28,8 +26,7 @@ to a console platform is as follows:
Due to the complexity of the process, the budget to publish a game by yourself on a Due to the complexity of the process, the budget to publish a game by yourself on a
single console often exceeds $1,000 (this is a rough figure). single console often exceeds $1,000 (this is a rough figure).
Official support ## Official support
----------------
Pandemonium supports the Linux-based Steam Deck. The reason other consoles are not Pandemonium supports the Linux-based Steam Deck. The reason other consoles are not
officially supported are: officially supported are:
@ -55,8 +52,7 @@ Note:
they are a licensed console developer. Doing so would violate the console they are a licensed console developer. Doing so would violate the console
manufacturer's NDA. manufacturer's NDA.
Third-party support ## Third-party support
-------------------
Console ports of Pandemonium are offered by third-party companies (which have Console ports of Pandemonium are offered by third-party companies (which have
ported Pandemonium on their own). These companies also offer publishing of ported Pandemonium on their own). These companies also offer publishing of

View File

@ -1,11 +1,9 @@
Mobile rendering limitations # Mobile rendering limitations
============================
See also: See also:
The general `doc_3d_rendering_limitations` also apply to mobile platforms. The general `doc_3d_rendering_limitations` also apply to mobile platforms.
To improve out-of-the-box performance on mobile devices, Pandemonium automatically uses To improve out-of-the-box performance on mobile devices, Pandemonium automatically uses
@ -26,35 +24,23 @@ this has a significant performance cost and won't work on all devices.
The following project settings have mobile-specific overrides: The following project settings have mobile-specific overrides:
+---------------------------------------------------------------------------+-----------------+--------------------+
| Setting | Desktop default | Mobile default | | Setting | Desktop default | Mobile default |
+---------------------------------------------------------------------------+-----------------+--------------------+ |-------------------------------------------------------------------------|-----------------|--------------------|
| `rendering/quality/directional_shadow/size` | 4096 | 2048 | | `rendering/quality/directional_shadow/size` | 4096 | 2048 |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/intended_usage/framebuffer_allocation` | 3D | 3D Without Effects | | `rendering/quality/intended_usage/framebuffer_allocation` | 3D | 3D Without Effects |
+---------------------------------------------------------------------------+-----------------+--------------------+ | `rendering/quality/lightmapping/use_bicubic_sampling` | `true` | `false` |
| `rendering/quality/lightmapping/use_bicubic_sampling` | `true` | `false` | | `rendering/quality/reflections/high_quality_ggx` | `true` | `false` |
+---------------------------------------------------------------------------+-----------------+--------------------+ | `rendering/quality/shading/force_blinn_over_ggx` | `false` | `true` |
| `rendering/quality/reflections/high_quality_ggx` | `true` | `false` | | `rendering/quality/shading/force_lambert_over_burley` | `false` | `true` |
+---------------------------------------------------------------------------+-----------------+--------------------+ | `rendering/quality/shading/force_vertex_shading` | `false` | `true` |
| `rendering/quality/shading/force_blinn_over_ggx` | `false` | `true` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/shading/force_lambert_over_burley` | `false` | `true` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/shading/force_vertex_shading` | `false` | `true` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/shadow_atlas/size` | 4096 | 2048 | | `rendering/quality/shadow_atlas/size` | 4096 | 2048 |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/shadows/filter_mode` | PCF5 | Disabled | | `rendering/quality/shadows/filter_mode` | PCF5 | Disabled |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/gles3/shaders/max_simultaneous_compiles` | 2 | 1 | | *GLES3 only:* `rendering/gles3/shaders/max_simultaneous_compiles` | 2 | 1 |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/gles3/shaders/shader_cache_size_mb` | 512 | 128 | | *GLES3 only:* `rendering/gles3/shaders/shader_cache_size_mb` | 512 | 128 |
+---------------------------------------------------------------------------+-----------------+--------------------+ | *GLES3 only:* `rendering/quality/depth/hdr` | `true` | `false` |
| *GLES3 only:* `rendering/quality/depth/hdr` | `true` | `false` | | *GLES3 only:* `rendering/quality/reflections/texture_array_reflections` | `true` | `false` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/quality/reflections/texture_array_reflections` | `true` | `false` |
+---------------------------------------------------------------------------+-----------------+--------------------+
See the `ProjectSettings class documentation` See the `ProjectSettings class documentation`
for more information on those setting overrides. for more information on those setting overrides.

View File

@ -40,8 +40,8 @@ As a prerequisite, make sure you understand how to set up a `custom build enviro
At its core, a Pandemonium Android plugin is a `Android archive library ( https://developer.android.com/studio/projects/android-library#aar-contents )` (*aar* archive file) At its core, a Pandemonium Android plugin is a `Android archive library ( https://developer.android.com/studio/projects/android-library#aar-contents )` (*aar* archive file)
with the following caveats: with the following caveats:
- The library must have a dependency on the Pandemonium engine library (`pandemonium-lib.<version>.<status>.aar`). A stable version is made available for each Pandemonium release on the `Pandemonium download page ( https://pandemoniumengine.org/download )`. - The library must have a dependency on the Pandemonium engine library (`pandemonium-lib.&lt;version>.&lt;status>.aar`). A stable version is made available for each Pandemonium release on the `Pandemonium download page ( https://pandemoniumengine.org/download )`.
- The library must include a specifically configured `<meta-data )` tag in its manifest file. - The library must include a specifically configured `&lt;meta-data&gt;` tag in its manifest file.
#### Building an Android plugin #### Building an Android plugin
@ -52,7 +52,7 @@ The instructions below assumes that you're using Android Studio.
2. Add the Pandemonium engine library as a dependency to your plugin module: 2. Add the Pandemonium engine library as a dependency to your plugin module:
- Download the Pandemonium engine library (`pandemonium-lib.<version>.<status>.aar`) from the `Pandemonium download page ( https://pandemoniumengine.org/download )` (e.g.: `pandemonium-lib.3.4.2.stable.release.aar`). - Download the Pandemonium engine library (`pandemonium-lib.&lt;version>.&lt;status>.aar`) from the `Pandemonium download page ( https://pandemoniumengine.org/download )` (e.g.: `pandemonium-lib.3.4.2.stable.release.aar`).
- Follow `these instructions ( https://developer.android.com/studio/projects/android-library#AddDependency )` to add - Follow `these instructions ( https://developer.android.com/studio/projects/android-library#AddDependency )` to add
the Pandemonium engine library as a dependency for your plugin. the Pandemonium engine library as a dependency for your plugin.
- In the plugin module's `build.gradle` file, replace `implementation` with `compileOnly` for the dependency line for the Pandemonium engine library. - In the plugin module's `build.gradle` file, replace `implementation` with `compileOnly` for the dependency line for the Pandemonium engine library.
@ -63,8 +63,8 @@ The instructions below assumes that you're using Android Studio.
4. Update the plugin `AndroidManifest.xml` file: 4. Update the plugin `AndroidManifest.xml` file:
- Open the plugin `AndroidManifest.xml` file. - Open the plugin `AndroidManifest.xml` file.
- Add the `<application></application )` tag if it's missing. - Add the `&lt;application>&lt;/application&gt;` tag if it's missing.
- In the `<application )` tag, add a `<meta-data )` tag setup as follow: - In the `&lt;application&gt;` tag, add a `&lt;meta-data&gt;` tag setup as follow:
``` ```
<meta-data <meta-data

View File

@ -1,7 +1,5 @@
# Custom HTML page for Web export
Custom HTML page for Web export
====================================
While Web export templates provide a default HTML page fully capable of launching While Web export templates provide a default HTML page fully capable of launching
the project without any further customization, it may be beneficial to create a custom the project without any further customization, it may be beneficial to create a custom
@ -40,17 +38,17 @@ but the following template can be used as a much simpler example:
</html> </html>
``` ```
Setup ## Setup
-----
As shown by the example above, it is mostly a regular HTML document, with few placeholders As shown by the example above, it is mostly a regular HTML document, with few placeholders
which needs to be replaced during export, an html `<canvas )` element, and some simple which needs to be replaced during export, an html `&lt;canvas&gt;` element, and some simple
JavaScript code that calls the :js:class:`Engine` class. JavaScript code that calls the :js:class:`Engine` class.
The only required placeholders are: The only required placeholders are:
- `$PANDEMONIUM_URL`: - `$PANDEMONIUM_URL`:
The name of the main JavaScript file, which provides the :js:class:`Engine` class required The name of the main JavaScript file, which provides the :js:class:`Engine` class required
to start the engine and that must be included in the HTML as a `<script )`. to start the engine and that must be included in the HTML as a `&lt;script&gt;`.
The name is generated from the *Export Path* during the export process. The name is generated from the *Export Path* during the export process.
- `$PANDEMONIUM_CONFIG`: - `$PANDEMONIUM_CONFIG`:
@ -60,11 +58,11 @@ The only required placeholders are:
The following optional placeholders will enable some extra features in your custom HTML template. The following optional placeholders will enable some extra features in your custom HTML template.
- `$PANDEMONIUM_PROJECT_NAME`: - `$PANDEMONIUM_PROJECT_NAME`:
The project name as defined in the Project Settings. It is a good idea to use it as a `<title )` The project name as defined in the Project Settings. It is a good idea to use it as a `&lt;title&gt;`
in your template. in your template.
- `$PANDEMONIUM_HEAD_INCLUDE`: - `$PANDEMONIUM_HEAD_INCLUDE`:
A custom string to include in the HTML document just before the end of the `<head )` tag. It A custom string to include in the HTML document just before the end of the `&lt;head&gt;` tag. It
is customized in the export options under the *Html / Head Include* section. While you fully is customized in the export options under the *Html / Head Include* section. While you fully
control the HTML page you create, this variable can be useful for configuring parts of the control the HTML page you create, this variable can be useful for configuring parts of the
HTML `head` element from the Pandemonium Editor, e.g. for different Web export presets. HTML `head` element from the Pandemonium Editor, e.g. for different Web export presets.
@ -74,8 +72,8 @@ section.
![](img/html5_export_options.png) ![](img/html5_export_options.png)
Starting the project ## Starting the project
--------------------
To be able to start the game, you need to write a script that initializes the engine — the control To be able to start the game, you need to write a script that initializes the engine — the control
code. This process consists of three steps, though as shown most of them can be skipped depending on code. This process consists of three steps, though as shown most of them can be skipped depending on
how much customization is needed (or be left to a default behavior). how much customization is needed (or be left to a default behavior).
@ -85,7 +83,7 @@ See the `HTML5 shell class reference ( doc_html5_shell_classref )`, for the full
First, the engine must be loaded, then it needs to be initialized, and after this the project First, the engine must be loaded, then it needs to be initialized, and after this the project
can finally be started. You can perform every of these steps manually and with great control. can finally be started. You can perform every of these steps manually and with great control.
However, in the simplest case all you need to do is to create an instance of the :js:class:`Engine` However, in the simplest case all you need to do is to create an instance of the :js:class:`Engine`
class with the exported configuration, and then call the :js:meth:`engine.startGame <Engine.prototype.startGame )` method class with the exported configuration, and then call the :js:meth:`engine.startGame ( Engine.prototype.startGame )` method
optionally overriding any :js:attr:`EngineConfig` parameters. optionally overriding any :js:attr:`EngineConfig` parameters.
``` ```
@ -99,16 +97,16 @@ optionally overriding any :js:attr:`EngineConfig` parameters.
``` ```
This snippet of code automatically loads and initializes the engine before starting the game. This snippet of code automatically loads and initializes the engine before starting the game.
It uses the given configuration to to load the engine. The :js:meth:`engine.startGame <Engine.prototype.startGame )` It uses the given configuration to to load the engine. The :js:meth:`engine.startGame ( )Engine.prototype.startGame )`
method is asynchronous and returns a `Promise`. This allows your control code to track if method is asynchronous and returns a `Promise`. This allows your control code to track if
the game was loaded correctly without blocking execution or relying on polling. the game was loaded correctly without blocking execution or relying on polling.
In case your project needs to have special control over the start arguments and dependency files, In case your project needs to have special control over the start arguments and dependency files,
the :js:meth:`engine.start <Engine.prototype.start )` method can be used instead. Note, that this method do not the :js:meth:`engine.start ( Engine.prototype.start )` method can be used instead. Note, that this method do not
automatically preload the `pck` file, so you will probably want to manually preload it automatically preload the `pck` file, so you will probably want to manually preload it
(and any other extra file) via the :js:meth:`engine.preloadFile <Engine.prototype.preloadFile )` method. (and any other extra file) via the :js:meth:`engine.preloadFile ( Engine.prototype.preloadFile )` method.
Optionally, you can also manually :js:meth:`engine.init <Engine.prototype.init )` to perform specific actions after Optionally, you can also manually :js:meth:`engine.init ( Engine.prototype.init )` to perform specific actions after
the module initialization, but before the engine starts. the module initialization, but before the engine starts.
This process is a bit more complex, but gives you full control over the engine startup process. This process is a bit more complex, but gives you full control over the engine startup process.
@ -139,8 +137,8 @@ Note:
to unload the engine manually afterwards by calling the :js:meth:`Engine.unload` static method. Unloading the engine to unload the engine manually afterwards by calling the :js:meth:`Engine.unload` static method. Unloading the engine
frees browser memory by unloading files that are no longer needed once the instance is initialized. frees browser memory by unloading files that are no longer needed once the instance is initialized.
Customizing the behavior ## Customizing the behavior
------------------------
In the Web environment several methods can be used to guarantee that the game will work as intended. In the Web environment several methods can be used to guarantee that the game will work as intended.
If you target a specific version of WebGL, or just want to check if WebGL is available at all, If you target a specific version of WebGL, or just want to check if WebGL is available at all,
@ -153,8 +151,8 @@ filename formed from the base name of loaded engine files. This value affects th
the automatically started main pack. The :js:attr:`executable` override option can be the automatically started main pack. The :js:attr:`executable` override option can be
used to override this value. used to override this value.
Customizing the presentation ## Customizing the presentation
----------------------------
Several configuration options can be used to further customize the look and behavior of the game on your page. Several configuration options can be used to further customize the look and behavior of the game on your page.
By default, the first canvas element on the page is used for rendering. To use a different canvas By default, the first canvas element on the page is used for rendering. To use a different canvas
@ -187,8 +185,8 @@ force a specific locale, provided you have a valid language code string. It may
logic to determine which languages a user may prefer. This way the language code can be taken from the logic to determine which languages a user may prefer. This way the language code can be taken from the
`Accept-Language` HTTP header, or determined by a GeoIP service. `Accept-Language` HTTP header, or determined by a GeoIP service.
Debugging ## Debugging
---------
To debug exported projects, it may be useful to read the standard output and error streams generated To debug exported projects, it may be useful to read the standard output and error streams generated
by the engine. This is similar to the output shown in the editor console window. By default, standard by the engine. This is similar to the output shown in the editor console window. By default, standard
`console.log` and `console.warn` are used for the output and error streams respectively. This `console.log` and `console.warn` are used for the output and error streams respectively. This

View File

@ -1,7 +1,5 @@
# HTML5 shell class reference
HTML5 shell class reference
===========================
Projects exported for the Web expose the :js:class:`Engine` class to the JavaScript environment, that allows Projects exported for the Web expose the :js:class:`Engine` class to the JavaScript environment, that allows
fine control over the engine's start-up process. fine control over the engine's start-up process.
@ -9,40 +7,32 @@ fine control over the engine's start-up process.
This API is built in an asynchronous manner and requires basic understanding This API is built in an asynchronous manner and requires basic understanding
of `Promises ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises )`. of `Promises ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises )`.
Engine ## Engine
------
The `Engine` class provides methods for loading and starting exported projects on the Web. For default export The `Engine` class provides methods for loading and starting exported projects on the Web. For default export
settings, this is already part of the exported HTML page. To understand practical use of the `Engine` class, settings, this is already part of the exported HTML page. To understand practical use of the `Engine` class,
see `Custom HTML page for Web export ( doc_customizing_html5_shell )`. see `Custom HTML page for Web export ( doc_customizing_html5_shell )`.
Static Methods #### Static Methods
^^^^^^^^^^^^^^
+---------+-----------------------------------------------------------------------------------------------+ | | |
| Promise | :js:attr:`load <Engine.load )` **(** string basePath **)** | |---------|------------------------------------------------------------------------------------------------|
+---------+-----------------------------------------------------------------------------------------------+ | Promise | :js:attr:`load ( Engine.load )` **(** string basePath **)** |
| void | :js:attr:`unload <Engine.unload )` **(** **)** | | void | :js:attr:`unload ( Engine.unload )` **(** **)** |
+---------+-----------------------------------------------------------------------------------------------+ | boolean | :js:attr:`isWebGLAvailable ( Engine.isWebGLAvailable )` **(** *[ number majorVersion=1 ]* **)** |
| boolean | :js:attr:`isWebGLAvailable <Engine.isWebGLAvailable )` **(** *[ number majorVersion=1 ]* **)** |
+---------+-----------------------------------------------------------------------------------------------+
Instance Methods
^^^^^^^^^^^^^^^^
+---------+---------------------------------------------------------------------------------------------------------------+ #### Instance Methods
| Promise | :js:attr:`init <Engine.prototype.init )` **(** *[ string basePath ]* **)** |
+---------+---------------------------------------------------------------------------------------------------------------+ | | |
| Promise | :js:attr:`preloadFile <Engine.prototype.preloadFile )` **(** string\|ArrayBuffer file *[, string path ]* **)** | |---------|----------------------------------------------------------------------------------------------------------------|
+---------+---------------------------------------------------------------------------------------------------------------+ | Promise | :js:attr:`init ( Engine.prototype.init )` **(** *[ string basePath ]* **)** |
| Promise | :js:attr:`start <Engine.prototype.start )` **(** EngineConfig override **)** | | Promise | :js:attr:`preloadFile ( Engine.prototype.preloadFile )` **(** string\|ArrayBuffer file *[, string path ]* **)** |
+---------+---------------------------------------------------------------------------------------------------------------+ | Promise | :js:attr:`start ( Engine.prototype.start )` **(** EngineConfig override **)** |
| Promise | :js:attr:`startGame <Engine.prototype.startGame )` **(** EngineConfig override **)** | | Promise | :js:attr:`startGame ( Engine.prototype.startGame )` **(** EngineConfig override **)** |
+---------+---------------------------------------------------------------------------------------------------------------+ | void | :js:attr:`copyToFS ( Engine.prototype.copyToFS )` **(** string path, ArrayBuffer buffer **)** |
| void | :js:attr:`copyToFS <Engine.prototype.copyToFS )` **(** string path, ArrayBuffer buffer **)** | | void | :js:attr:`requestQuit ( Engine.prototype.requestQuit )` **(** **)** |
+---------+---------------------------------------------------------------------------------------------------------------+
| void | :js:attr:`requestQuit <Engine.prototype.requestQuit )` **(** **)** |
+---------+---------------------------------------------------------------------------------------------------------------+
.. js:class:: Engine( initConfig ) .. js:class:: Engine( initConfig )
@ -123,9 +113,9 @@ Instance Methods
.. js:function:: prototype.start( override ) .. js:function:: prototype.start( override )
Start the engine instance using the given override configuration (if any). Start the engine instance using the given override configuration (if any).
:js:meth:`startGame <Engine.prototype.startGame )` can be used in typical cases instead. :js:meth:`startGame ( Engine.prototype.startGame )` can be used in typical cases instead.
This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init )`. This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init ( Engine.prototype.init )`.
The engine must be loaded beforehand. The engine must be loaded beforehand.
Fails if a canvas cannot be found on the page, or not specified in the configuration. Fails if a canvas cannot be found on the page, or not specified in the configuration.
@ -142,7 +132,7 @@ Instance Methods
Start the game instance using the given configuration override (if any). Start the game instance using the given configuration override (if any).
This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init <Engine.prototype.init )`. This will initialize the instance if it is not initialized. For manual initialization, see :js:meth:`init ( Engine.prototype.init )`.
This will load the engine if it is not loaded, and preload the main pck. This will load the engine if it is not loaded, and preload the main pck.
@ -174,42 +164,28 @@ Instance Methods
This is akin the user pressing the close button in the window manager, and will This is akin the user pressing the close button in the window manager, and will
have no effect if the engine has crashed, or is stuck in a loop. have no effect if the engine has crashed, or is stuck in a loop.
Engine configuration ## Engine configuration
--------------------
An object used to configure the Engine instance based on pandemonium export options, and to override those in custom HTML An object used to configure the Engine instance based on pandemonium export options, and to override those in custom HTML
templates if needed. templates if needed.
Properties #### Properties
^^^^^^^^^^
| type | name |
|----------------------|-------------------------------|
| boolean | :js:attr:`unloadAfterInit` |
| HTMLCanvasElement | :js:attr:`canvas` |
| string | :js:attr:`executable` |
| string | :js:attr:`mainPack` |
| string | :js:attr:`locale` |
| number | :js:attr:`canvasResizePolicy` |
| Array.&lt;string&gt; | :js:attr:`args` |
| function | :js:attr:`onExecute` |
| function | :js:attr:`onExit` |
| function | :js:attr:`onProgress` |
| function | :js:attr:`onPrint` |
| function | :js:attr:`onPrintError` |
+-------------------+-------------------------------+
| type | name |
+-------------------+-------------------------------+
| boolean | :js:attr:`unloadAfterInit` |
+-------------------+-------------------------------+
| HTMLCanvasElement | :js:attr:`canvas` |
+-------------------+-------------------------------+
| string | :js:attr:`executable` |
+-------------------+-------------------------------+
| string | :js:attr:`mainPack` |
+-------------------+-------------------------------+
| string | :js:attr:`locale` |
+-------------------+-------------------------------+
| number | :js:attr:`canvasResizePolicy` |
+-------------------+-------------------------------+
| Array.<string> | :js:attr:`args` |
+-------------------+-------------------------------+
| function | :js:attr:`onExecute` |
+-------------------+-------------------------------+
| function | :js:attr:`onExit` |
+-------------------+-------------------------------+
| function | :js:attr:`onProgress` |
+-------------------+-------------------------------+
| function | :js:attr:`onPrint` |
+-------------------+-------------------------------+
| function | :js:attr:`onPrintError` |
+-------------------+-------------------------------+
.. js:attribute:: EngineConfig .. js:attribute:: EngineConfig
@ -285,9 +261,9 @@ Properties
See `command line tutorial ( doc_command_line_tutorial )`. See `command line tutorial ( doc_command_line_tutorial )`.
**Note**: :js:meth:`startGame <Engine.prototype.startGame )` will always add the `--main-pack` argument. **Note**: :js:meth:`startGame ( Engine.prototype.startGame )` will always add the `--main-pack` argument.
:type: Array.<string> :type: Array.&lt;string&gt;
:value: `[]` :value: `[]`
@ -300,7 +276,7 @@ Properties
:param string path: :param string path:
The path that Pandemonium's wants executed. The path that Pandemonium's wants executed.
:param Array.<string> args: :param Array.&lt;string&gt; args:
The arguments of the "command" to execute. The arguments of the "command" to execute.
.. js:function:: onExit( status_code ) .. js:function:: onExit( status_code )

View File

@ -1,10 +1,8 @@
Using Viewports # Using Viewports
===============
Introduction ## Introduction
------------
Think of a `Viewport` as a screen onto which the game is projected. In order Think of a `Viewport` as a screen onto which the game is projected. In order
to see the game, we need to have a surface on which to draw it; that surface is to see the game, we need to have a surface on which to draw it; that surface is
@ -34,8 +32,7 @@ What all these use cases have in common is that you are given the ability to
draw objects to a texture as if it were another screen and can then choose draw objects to a texture as if it were another screen and can then choose
what to do with the resulting texture. what to do with the resulting texture.
Input ## Input
-----
`Viewports` are also responsible for delivering properly adjusted and `Viewports` are also responsible for delivering properly adjusted and
scaled input events to all their children nodes. Typically, input is received by the scaled input events to all their children nodes. Typically, input is received by the
@ -47,8 +44,7 @@ the input.
For more information on how Pandemonium handles input, please read the `Input Event Tutorial( doc_inputevent )`. For more information on how Pandemonium handles input, please read the `Input Event Tutorial( doc_inputevent )`.
Listener ## Listener
--------
Pandemonium supports 3D sound (in both 2D and 3D nodes); more on this can be Pandemonium supports 3D sound (in both 2D and 3D nodes); more on this can be
found in the `Audio Streams Tutorial( doc_audio_streams )`. For this type of sound to be found in the `Audio Streams Tutorial( doc_audio_streams )`. For this type of sound to be
@ -56,8 +52,7 @@ audible, the `Viewport` needs to be enabled as a listener (for 2D or 3D).
If you are using a custom `Viewport`, don't forget If you are using a custom `Viewport`, don't forget
to enable this! to enable this!
Cameras (2D & 3D) ## Cameras (2D & 3D)
-----------------
When using a `Camera` / When using a `Camera` /
`Camera2D`, cameras will always display on the `Camera2D`, cameras will always display on the
@ -85,8 +80,7 @@ By default, cameras will render all objects in their world. In 3D, cameras can u
`VisualInstance's` `VisualInstance's`
property to restrict which objects are rendered. property to restrict which objects are rendered.
Scale & stretching ## Scale & stretching
------------------
`Viewports` `Viewports`
in pixels. For `Viewports`, in pixels. For `Viewports`,
@ -103,8 +97,7 @@ different from the one specified in size, by calling:
The root `Viewport` uses this for the stretch options in the project The root `Viewport` uses this for the stretch options in the project
settings. For more information on scaling and stretching visit the `Multiple Resolutions Tutorial ( doc_multiple_resolutions )` settings. For more information on scaling and stretching visit the `Multiple Resolutions Tutorial ( doc_multiple_resolutions )`
Worlds ## Worlds
------
For 3D, a `Viewport`. This For 3D, a `Viewport`. This
is basically the universe that links physics and rendering together. is basically the universe that links physics and rendering together.
@ -129,8 +122,7 @@ is possible to do so by setting the `Viewport's` manually.
For an example of how this works, see the demo projects `3D in 2D ( https://github.com/Relintai/pandemonium_engine-demo-projects/tree/master/viewport/3d_in_2d )` and `2D in 3D ( https://github.com/Relintai/pandemonium_engine-demo-projects/tree/master/viewport/2d_in_3d )` respectively. For an example of how this works, see the demo projects `3D in 2D ( https://github.com/Relintai/pandemonium_engine-demo-projects/tree/master/viewport/3d_in_2d )` and `2D in 3D ( https://github.com/Relintai/pandemonium_engine-demo-projects/tree/master/viewport/2d_in_3d )` respectively.
Capture ## Capture
-------
It is possible to query a capture of the `Viewport` contents. For the root It is possible to query a capture of the `Viewport` contents. For the root
`Viewport`, this is effectively a screen capture. This is done with the `Viewport`, this is effectively a screen capture. This is done with the
@ -159,8 +151,7 @@ it using (for example):
# You can get the image after this. # You can get the image after this.
``` ```
Viewport Container ## Viewport Container
------------------
If the `Viewport`, it will become active and display anything it has inside. The layout looks like this: If the `Viewport`, it will become active and display anything it has inside. The layout looks like this:
@ -170,8 +161,7 @@ The `Viewport` completely
if `Stretch( viewportcontainer_property_stretch )` is set to `true` in `ViewportContainer`. if `Stretch( viewportcontainer_property_stretch )` is set to `true` in `ViewportContainer`.
Note: The size of the `ViewportContainer`. Note: The size of the `ViewportContainer`.
Rendering ## Rendering
---------
Due to the fact that the `Viewport` is an entryway into another rendering surface, it exposes a few Due to the fact that the `Viewport` is an entryway into another rendering surface, it exposes a few
rendering properties that can be different from the project settings. The first is MSAA; you can rendering properties that can be different from the project settings. The first is MSAA; you can
@ -217,8 +207,7 @@ Note:
The effects of the Wireframe mode are only visible in the editor, not while the project is running. The effects of the Wireframe mode are only visible in the editor, not while the project is running.
Render target ## Render target
-------------
When rendering to a `Viewport`, whatever is inside will not be When rendering to a `Viewport`, whatever is inside will not be
visible in the scene editor. To display the contents, you have to draw the `Viewport's` somewhere. visible in the scene editor. To display the contents, you have to draw the `Viewport's` somewhere.

View File

@ -1,10 +1,8 @@
Multiple resolutions # Multiple resolutions
====================
The problem of multiple resolutions ## The problem of multiple resolutions
-----------------------------------
Developers often have trouble understanding how to best support multiple Developers often have trouble understanding how to best support multiple
resolutions in their games. For desktop and console games, this is more or less resolutions in their games. For desktop and console games, this is more or less
@ -33,8 +31,7 @@ Since layouts, aspect ratios, resolutions, and pixel densities can change so
much, it is no longer possible to design UIs for every specific screen. much, it is no longer possible to design UIs for every specific screen.
Another method must be used. Another method must be used.
One size fits all ## One size fits all
-----------------
The most common approach is to use a single *base* resolution and The most common approach is to use a single *base* resolution and
then fit it to everything else. This resolution is how most players are expected then fit it to everything else. This resolution is how most players are expected
@ -48,8 +45,7 @@ handle scaling for different sizes and aspect ratios.
Pandemonium provides several useful tools to do this easily. Pandemonium provides several useful tools to do this easily.
Base size ## Base size
---------
A base size for the window can be specified in the Project Settings under A base size for the window can be specified in the Project Settings under
**Display → Window**. **Display → Window**.
@ -85,8 +81,7 @@ Note:
out of a game much slower since the monitor has to change resolutions every out of a game much slower since the monitor has to change resolutions every
time this is done. time this is done.
Resizing ## Resizing
--------
There are several types of devices, with several types of screens, which There are several types of devices, with several types of screens, which
in turn have different pixel density and resolutions. Handling all of in turn have different pixel density and resolutions. Handling all of
@ -102,15 +97,13 @@ most flexible way to deal with the problem, it can be a lot of work,
code and guessing, so Pandemonium provides a simple set of parameters in the code and guessing, so Pandemonium provides a simple set of parameters in the
project settings to handle multiple resolutions. project settings to handle multiple resolutions.
Stretch settings ## Stretch settings
----------------
Stretch settings are located in the project settings and provide several options: Stretch settings are located in the project settings and provide several options:
![](img/stretchsettings.png) ![](img/stretchsettings.png)
Stretch Mode #### Stretch Mode
^^^^^^^^^^^^
The **Stretch Mode** setting defines how the base size is stretched to fit The **Stretch Mode** setting defines how the base size is stretched to fit
the resolution of the window or screen. the resolution of the window or screen.
@ -152,8 +145,7 @@ demonstrate the effect of different stretch modes. A single sprite, also
![](img/stretch_viewport_expand.gif) ![](img/stretch_viewport_expand.gif)
Stretch Aspect #### Stretch Aspect
^^^^^^^^^^^^^^
The second setting is the stretch aspect. Note that this only takes effect if The second setting is the stretch aspect. Note that this only takes effect if
**Stretch Mode** is set to something other than **Disabled**. **Stretch Mode** is set to something other than **Disabled**.
@ -230,8 +222,7 @@ Tip:
To allow the user to choose their preferred screen orientation at run-time, To allow the user to choose their preferred screen orientation at run-time,
remember to set **Display > Window > Handheld > Orientation** to `sensor`. remember to set **Display > Window > Handheld > Orientation** to `sensor`.
Stretch Shrink #### Stretch Shrink
^^^^^^^^^^^^^^
The **Shrink** setting allows you to add an extra scaling factor on top of The **Shrink** setting allows you to add an extra scaling factor on top of
what the **Stretch** options above already provide. The default value of 1 what the **Stretch** options above already provide. The default value of 1
@ -247,21 +238,18 @@ in the output are scaled up by the same amount. This is rarely useful for
2D games, but can be used to increase performance in 3D games 2D games, but can be used to increase performance in 3D games
by rendering them at a lower resolution. by rendering them at a lower resolution.
From scripts #### From scripts
^^^^^^^^^^^^
To configure stretching at runtime from a script, use the To configure stretching at runtime from a script, use the
`get_tree().set_screen_stretch()` method (see `get_tree().set_screen_stretch()` method (see
`SceneTree.set_screen_stretch()`). `SceneTree.set_screen_stretch()`).
Common use case scenarios ## Common use case scenarios
-------------------------
The following settings are recommended to support multiple resolutions and aspect The following settings are recommended to support multiple resolutions and aspect
ratios well. ratios well.
Desktop game #### Desktop game
^^^^^^^^^^^^
**Non-pixel art:** **Non-pixel art:**
@ -307,8 +295,7 @@ Note:
final window size is not a multiple of the base window size. final window size is not a multiple of the base window size.
To fix this, use an add-on such as the `Integer Resolution Handler ( https://github.com/Yukitty/pandemonium-addon-integer_resolution_handler )`. To fix this, use an add-on such as the `Integer Resolution Handler ( https://github.com/Yukitty/pandemonium-addon-integer_resolution_handler )`.
Mobile game in landscape mode #### Mobile game in landscape mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Pandemonium is configured to use landscape mode by default. This means you don't need Pandemonium is configured to use landscape mode by default. This means you don't need
to change the display orientation project setting. to change the display orientation project setting.
@ -328,8 +315,7 @@ to change the display orientation project setting.
and makes better use of tall smartphone displays (such as 18:9 or 19:9 aspect ratios). and makes better use of tall smartphone displays (such as 18:9 or 19:9 aspect ratios).
- Configure Control nodes' anchors to snap to the correct corners using the **Layout** menu. - Configure Control nodes' anchors to snap to the correct corners using the **Layout** menu.
Mobile game in portrait mode #### Mobile game in portrait mode
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- Set the base window width to `720` and window height to `1080`. - Set the base window width to `720` and window height to `1080`.
- Alternatively, if you're targeting high-end devices primarily, set the base - Alternatively, if you're targeting high-end devices primarily, set the base
@ -347,8 +333,7 @@ Mobile game in portrait mode
and makes better use of tall smartphone displays (such as 18:9 or 19:9 aspect ratios). and makes better use of tall smartphone displays (such as 18:9 or 19:9 aspect ratios).
- Configure Control nodes' anchors to snap to the correct corners using the **Layout** menu. - Configure Control nodes' anchors to snap to the correct corners using the **Layout** menu.
Non-game application #### Non-game application
^^^^^^^^^^^^^^^^^^^^
- Set the base window width and height to the smallest window size that you intend to target. - Set the base window width and height to the smallest window size that you intend to target.
This is not required, but this ensures that you design your UI with small window sizes in mind. This is not required, but this ensures that you design your UI with small window sizes in mind.
@ -367,8 +352,7 @@ Note:
is recommended to leave **Allow Hidpi** disabled in non-game applications to is recommended to leave **Allow Hidpi** disabled in non-game applications to
allow for the OS to use its low-DPI fallback. allow for the OS to use its low-DPI fallback.
hiDPI support ## hiDPI support
-------------
By default, Pandemonium projects aren't considered DPI-aware by the operating system. By default, Pandemonium projects aren't considered DPI-aware by the operating system.
This is done to improve performance on low-end systems, since the operating This is done to improve performance on low-end systems, since the operating
@ -392,8 +376,7 @@ Note:
Reducing aliasing on downsampling ## Reducing aliasing on downsampling
---------------------------------
If the game has a very high base resolution (e.g. 3840×2160), aliasing might If the game has a very high base resolution (e.g. 3840×2160), aliasing might
appear when downsampling to something considerably lower like 1280×720. appear when downsampling to something considerably lower like 1280×720.
@ -409,16 +392,14 @@ Alternatively, you can also enable mipmaps on all your 2D textures. However,
enabling mipmaps will increase memory usage which may be problematic on low-end enabling mipmaps will increase memory usage which may be problematic on low-end
mobile devices. mobile devices.
Handling aspect ratios ## Handling aspect ratios
----------------------
Once scaling for different resolutions is accounted for, make sure that Once scaling for different resolutions is accounted for, make sure that
your *user interface* also scales for different aspect ratios. This can be your *user interface* also scales for different aspect ratios. This can be
done using `anchors ( doc_size_and_anchors )` and/or `containers done using `anchors ( doc_size_and_anchors )` and/or `containers
( doc_gui_containers )`. ( doc_gui_containers )`.
Field of view scaling ## Field of view scaling
---------------------
The 3D Camera node's **Keep Aspect** property defaults to the **Keep Height** The 3D Camera node's **Keep Aspect** property defaults to the **Keep Height**
scaling mode (also called *Hor+*). This is usually the best value for desktop scaling mode (also called *Hor+*). This is usually the best value for desktop
@ -430,8 +411,7 @@ more sense to use **Keep Width** instead (also called *Vert-*). This way,
smartphones with an aspect ratio taller than 16:9 (e.g. 19:9) will use a smartphones with an aspect ratio taller than 16:9 (e.g. 19:9) will use a
*taller* field of view, which is more logical here. *taller* field of view, which is more logical here.
Scaling 2D and 3D elements differently using Viewports ## Scaling 2D and 3D elements differently using Viewports
------------------------------------------------------
Using multiple Viewport nodes, you can have different scales for various Using multiple Viewport nodes, you can have different scales for various
elements. For instance, you can use this to render the 3D world at a low elements. For instance, you can use this to render the 3D world at a low

View File

@ -1,17 +1,14 @@
Fixing jitter and stutter # Fixing jitter and stutter
=========================
What are jitter and stutter? ## What are jitter and stutter?
----------------------------
*Jitter* and *stutter* are two different alterations to visible motion of objects on screen that may affect a game, *Jitter* and *stutter* are two different alterations to visible motion of objects on screen that may affect a game,
even when running at full speed. These effects are mostly visible in games where the world moves at a constant speed even when running at full speed. These effects are mostly visible in games where the world moves at a constant speed
in a fixed direction, like runners or platformers. in a fixed direction, like runners or platformers.
Distinguishing between them ## Distinguishing between them
---------------------------
A game running at a normal framerate without exhibiting any effect will appear smooth: A game running at a normal framerate without exhibiting any effect will appear smooth:
@ -26,8 +23,7 @@ Finally, a game exhibiting *stutter* will appear smooth, but appear to *stop* or
![](img/motion_stutter.gif) ![](img/motion_stutter.gif)
Jitter ## Jitter
------
There can be many causes of jitter, the most typical one happens when the game *physics frequency* (usually 60 Hz) runs There can be many causes of jitter, the most typical one happens when the game *physics frequency* (usually 60 Hz) runs
at a different resolution than the monitor refresh rate. Check whether your monitor refresh rate is different from 60 Hz. at a different resolution than the monitor refresh rate. Check whether your monitor refresh rate is different from 60 Hz.
@ -47,8 +43,7 @@ Note:
See `lawnjelly's smoothing-addon ( https://github.com/lawnjelly/smoothing-addon )` See `lawnjelly's smoothing-addon ( https://github.com/lawnjelly/smoothing-addon )`
for an add-on that can be dropped into any project to enable physics interpolation. for an add-on that can be dropped into any project to enable physics interpolation.
Stutter ## Stutter
-------
Stutter may happen due to two different reasons. The first, and most obvious one, is the game not being able to keep full Stutter may happen due to two different reasons. The first, and most obvious one, is the game not being able to keep full
framerate performance. Solving this is game specific and will require optimization. framerate performance. Solving this is game specific and will require optimization.
@ -56,8 +51,7 @@ framerate performance. Solving this is game specific and will require optimizati
The second is more complicated, because it is often not associated to the engine or game but the underlying operating system. The second is more complicated, because it is often not associated to the engine or game but the underlying operating system.
Here is some information regarding stutter on different OSs. Here is some information regarding stutter on different OSs.
Windows #### Windows
^^^^^^^
Windows is known to cause stutter in windowed games. This mostly depends on the hardware installed, drivers version and Windows is known to cause stutter in windowed games. This mostly depends on the hardware installed, drivers version and
processes running in parallel (e.g. having many browser tabs open may cause stutter in a running game). To avoid this, processes running in parallel (e.g. having many browser tabs open may cause stutter in a running game). To avoid this,
@ -71,8 +65,7 @@ won't play games windowed (games that are played in a window, e.g. puzzle games,
For fullscreen, Windows gives special priority to the game so stutter is no longer visible and very rare. For fullscreen, Windows gives special priority to the game so stutter is no longer visible and very rare.
This is how most games are played. This is how most games are played.
Linux (X11) #### Linux (X11)
^^^^^^^^^^^
Stutter may be visible on Desktop Linux, but this is usually associated with different video drivers and compositors. Stutter may be visible on Desktop Linux, but this is usually associated with different video drivers and compositors.
Nouveau drivers often exhibit this, while AMD or NVidia proprietary don't. Some compositors may also trigger this problem Nouveau drivers often exhibit this, while AMD or NVidia proprietary don't. Some compositors may also trigger this problem
@ -81,26 +74,22 @@ Nouveau drivers often exhibit this, while AMD or NVidia proprietary don't. Some
There is no workaround for driver or compositor stuttering other than reporting it as an issue to the driver or compositor There is no workaround for driver or compositor stuttering other than reporting it as an issue to the driver or compositor
developers. developers.
macOS #### macOS
^^^^^
Generally, macOS is stutter-free, although recently some bugs were reported when running on fullscreen (this is a macOS bug). Generally, macOS is stutter-free, although recently some bugs were reported when running on fullscreen (this is a macOS bug).
If you have a machine exhibiting this behavior, please let us know. If you have a machine exhibiting this behavior, please let us know.
Android #### Android
^^^^^^^
Generally, Android is stutter and jitter-free because the running activity gets all the priority. That said, there may be Generally, Android is stutter and jitter-free because the running activity gets all the priority. That said, there may be
problematic devices (older Kindle Fire is known to be one). If you see this problem on Android, please let us know. problematic devices (older Kindle Fire is known to be one). If you see this problem on Android, please let us know.
iOS #### iOS
^^^
iOS devices are generally stutter-free, but older devices running newer versions of the operating system may exhibit problems. iOS devices are generally stutter-free, but older devices running newer versions of the operating system may exhibit problems.
This is generally unavoidable. This is generally unavoidable.
Reporting stutter or jitter problems ## Reporting stutter or jitter problems
------------------------------------
If you are reporting a stutter or jitter problem (opening an issue) not caused by any of the above reasons, please specify very If you are reporting a stutter or jitter problem (opening an issue) not caused by any of the above reasons, please specify very
clearly all the information possible about device, operating system, driver versions, etc. This may help to better troubleshoot it. clearly all the information possible about device, operating system, driver versions, etc. This may help to better troubleshoot it.

View File

@ -1,7 +1,6 @@
Idle and Physics Processing # Idle and Physics Processing
===========================
Games run in a loop. Each frame, you need to update the state of your game world Games run in a loop. Each frame, you need to update the state of your game world
before drawing it on screen. Pandemonium provides two virtual methods in the Node before drawing it on screen. Pandemonium provides two virtual methods in the Node

View File

@ -1,7 +1,6 @@
Groups # Groups
======
Groups in Pandemonium work like tags in other software. You can add a node to as many Groups in Pandemonium work like tags in other software. You can add a node to as many
groups as you want. Then, in code, you can use the SceneTree to: groups as you want. Then, in code, you can use the SceneTree to:
@ -13,8 +12,7 @@ groups as you want. Then, in code, you can use the SceneTree to:
This is a useful feature to organize large scenes and decouple code. This is a useful feature to organize large scenes and decouple code.
Managing groups ## Managing groups
---------------
Groups are created by adding a node to a new group name, and likewise they are Groups are created by adding a node to a new group name, and likewise they are
removed by removing all nodes from a given group. removed by removing all nodes from a given group.
@ -26,8 +24,7 @@ There are two ways to add/remove nodes to groups:
or `Node.remove_from_group()`. or `Node.remove_from_group()`.
Using the Node dock ### Using the Node dock
~~~~~~~~~~~~~~~~~~~
You can add nodes in the current scene to groups using the Groups tab in the You can add nodes in the current scene to groups using the Groups tab in the
Node dock. Node dock.
@ -68,8 +65,7 @@ Note:
in a different scene and you cannot edit it here. This happens on in a different scene and you cannot edit it here. This happens on
scene instances in particular. scene instances in particular.
Using code ### Using code
~~~~~~~~~~
You can also manage groups from scripts. The following code adds the node to You can also manage groups from scripts. The following code adds the node to
which you attach the script to the `guards` group as soon as it enters the which you attach the script to the `guards` group as soon as it enters the

View File

@ -1,13 +1,11 @@
Nodes and scene instances # Nodes and scene instances
=========================
This guide explains how to get nodes, create nodes, add them as a child, and This guide explains how to get nodes, create nodes, add them as a child, and
instantiate scenes from code. instantiate scenes from code.
Getting nodes ## Getting nodes
-------------
You can get a reference to a node by calling the `Node.get_node() You can get a reference to a node by calling the `Node.get_node()
( Node_method_get_node )` method. For this to work, the child node must be ( Node_method_get_node )` method. For this to work, the child node must be
@ -42,8 +40,7 @@ line that gets the node to `get_node("Skin")` in the script.
![](img/nodes_and_scene_instances_sprite_node_renamed.png) ![](img/nodes_and_scene_instances_sprite_node_renamed.png)
Node paths ## Node paths
----------
When getting a reference to a node, you're not limited to getting a direct child. The `get_node()` function When getting a reference to a node, you're not limited to getting a direct child. The `get_node()` function
supports paths, a bit like when working with a file browser. Add a slash to supports paths, a bit like when working with a file browser. Add a slash to
@ -72,8 +69,7 @@ Note:
slash to make it absolute, in which case your topmost node would be slash to make it absolute, in which case your topmost node would be
"/root", the application's predefined root viewport. "/root", the application's predefined root viewport.
Syntactic sugar ### Syntactic sugar
~~~~~~~~~~~~~~~
You can use two shorthands to shorten your code in GDScript. Firstly, putting the You can use two shorthands to shorten your code in GDScript. Firstly, putting the
`onready` keyword before a member variable makes it initialize right before `onready` keyword before a member variable makes it initialize right before
@ -91,8 +87,7 @@ place it before the name or path of the node you want to get.
onready var tween = $ShieldBar/Tween onready var tween = $ShieldBar/Tween
``` ```
Creating nodes ## Creating nodes
--------------
To create a node from code, call its `new()` method like for any other To create a node from code, call its `new()` method like for any other
class-based datatype. class-based datatype.
@ -139,8 +134,7 @@ When you free a node, it also frees all its children. Thanks to this, to delete
an entire branch of the scene tree, you only have to free the topmost parent an entire branch of the scene tree, you only have to free the topmost parent
node. node.
Instancing scenes ## Instancing scenes
-----------------
Scenes are templates from which you can create as many reproductions as you'd Scenes are templates from which you can create as many reproductions as you'd
like. This operation is called instancing, and doing it from code happens in two like. This operation is called instancing, and doing it from code happens in two
@ -164,7 +158,7 @@ gdscript GDScript
``` ```
var scene = preload("res://MyScene.tscn") var scene = preload("res://MyScene.tscn")
``` ```
At that point, `scene` is a packed scene resource, not a node. To create the At that point, `scene` is a packed scene resource, not a node. To create the
actual node, you need to call `PackedScene.instance() actual node, you need to call `PackedScene.instance()

View File

@ -1,7 +1,6 @@
Overridable functions # Overridable functions
=====================
Pandemonium's Node class provides virtual functions you can override to update nodes Pandemonium's Node class provides virtual functions you can override to update nodes
every frame or on specific events, like when they enter the scene tree. every frame or on specific events, like when they enter the scene tree.
@ -76,7 +75,7 @@ every key press, mouse click, etc. that have not been handled already in an
gameplay input in general. The `input()` callback allows you to intercept and gameplay input in general. The `input()` callback allows you to intercept and
process input events before `unhandled_input()` gets them. process input events before `unhandled_input()` gets them.
To learn more about inputs in Pandemonium, see the `Input section <toc-learn-features-inputs )`. To learn more about inputs in Pandemonium, see the `Input section ( toc-learn-features-inputs )`.
gdscript GDScript gdscript GDScript

View File

@ -1,7 +1,6 @@
Cross-language scripting # Cross-language scripting
========================
Pandemonium allows you to mix and match scripting languages to suit your needs. Pandemonium allows you to mix and match scripting languages to suit your needs.
This means a single project can define nodes in both C# and GDScript. This means a single project can define nodes in both C# and GDScript.
@ -33,14 +32,12 @@ gdscript GDScript
print(msg) print(msg)
``` ```
Instantiating nodes ## Instantiating nodes
-------------------
If you're not using nodes from the scene tree, you'll probably want to If you're not using nodes from the scene tree, you'll probably want to
instantiate nodes directly from the code. instantiate nodes directly from the code.
Instantiating C# nodes from GDScript ### Instantiating C# nodes from GDScript
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Using C# from GDScript doesn't need much work. Once loaded Using C# from GDScript doesn't need much work. Once loaded
(see `doc_gdscript_classes_as_resources`), the script can be instantiated (see `doc_gdscript_classes_as_resources`), the script can be instantiated
@ -65,8 +62,7 @@ Warning:
You also need to check your `.cs` file is referenced in the project's You also need to check your `.cs` file is referenced in the project's
`.csproj` file. Otherwise, the same error will occur. `.csproj` file. Otherwise, the same error will occur.
Instantiating GDScript nodes from C# ### Instantiating GDScript nodes from C#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
From the C# side, everything work the same way. Once loaded, the GDScript can From the C# side, everything work the same way. Once loaded, the GDScript can
be instantiated with `GDScript.New()`. be instantiated with `GDScript.New()`.
@ -79,11 +75,9 @@ be instantiated with `GDScript.New()`.
Here we are using an `Object`, but you can use type conversion like Here we are using an `Object`, but you can use type conversion like
explained in `doc_c_sharp_features_type_conversion_and_casting`. explained in `doc_c_sharp_features_type_conversion_and_casting`.
Accessing fields ## Accessing fields
----------------
Accessing C# fields from GDScript ### Accessing C# fields from GDScript
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Accessing C# fields from GDScript is straightforward, you shouldn't have Accessing C# fields from GDScript is straightforward, you shouldn't have
anything to worry about. anything to worry about.
@ -101,8 +95,7 @@ Note that it doesn't matter if the field is defined as a property or an
attribute. However, trying to set a value on a property that does not define attribute. However, trying to set a value on a property that does not define
a setter will result in a crash. a setter will result in a crash.
Accessing GDScript fields from C# ### Accessing GDScript fields from C#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As C# is statically typed, accessing GDScript from C# is a bit more As C# is statically typed, accessing GDScript from C# is a bit more
convoluted, you will have to use `Object.Get()` convoluted, you will have to use `Object.Get()`
@ -121,11 +114,9 @@ Keep in mind that when setting a field value you should only use types the
GDScript side knows about. GDScript side knows about.
Essentially, you want to work with built-in types as described in `doc_gdscript` or classes extending `Object`. Essentially, you want to work with built-in types as described in `doc_gdscript` or classes extending `Object`.
Calling methods ## Calling methods
---------------
Calling C# methods from GDScript ### Calling C# methods from GDScript
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Again, calling C# methods from GDScript should be straightforward. The Again, calling C# methods from GDScript should be straightforward. The
marshalling process will do its best to cast the arguments to match marshalling process will do its best to cast the arguments to match
@ -142,8 +133,7 @@ If that's impossible, you'll see the following error: `Invalid call. Nonexistent
my_csharp_node.PrintArray([1, 2, 3]) # 1, 2, 3 my_csharp_node.PrintArray([1, 2, 3]) # 1, 2, 3
``` ```
Calling GDScript methods from C# ### Calling GDScript methods from C#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To call GDScript methods from C# you'll need to use To call GDScript methods from C# you'll need to use
`Object.Call()`. The first argument is the `Object.Call()`. The first argument is the
@ -173,8 +163,7 @@ Warning:
Otherwise, each element of your array will be treated as a single argument Otherwise, each element of your array will be treated as a single argument
and the function signature won't match. and the function signature won't match.
Inheritance ## Inheritance
-----------
A GDScript file may not inherit from a C# script. Likewise, a C# script may not A GDScript file may not inherit from a C# script. Likewise, a C# script may not
inherit from a GDScript file. Due to how complex this would be to implement, inherit from a GDScript file. Due to how complex this would be to implement,

View File

@ -1,7 +1,6 @@
Creating script templates # Creating script templates
=========================
Pandemonium provides a way to use script templates as seen in the Pandemonium provides a way to use script templates as seen in the
`Script Create Dialog` while creating a new script: `Script Create Dialog` while creating a new script:
@ -11,13 +10,11 @@ Pandemonium provides a way to use script templates as seen in the
A set of default script templates is provided by default, but it's also possible A set of default script templates is provided by default, but it's also possible
to modify existing and create new ones, both per project and the editor. to modify existing and create new ones, both per project and the editor.
Locating the templates ## Locating the templates
----------------------
There are two places where templates can be managed. There are two places where templates can be managed.
Editor-defined templates ### Editor-defined templates
~~~~~~~~~~~~~~~~~~~~~~~~
These are available globally throughout any project. The location of these These are available globally throughout any project. The location of these
templates are determined per each OS: templates are determined per each OS:
@ -30,8 +27,7 @@ If no `script_templates` is detected, Pandemonium will create a default set of
built-in templates automatically, so this logic can be used to reset the default built-in templates automatically, so this logic can be used to reset the default
templates in case you've accidentally overwritten them. templates in case you've accidentally overwritten them.
Project-defined templates ### Project-defined templates
~~~~~~~~~~~~~~~~~~~~~~~~~
The default path to search for templates is the The default path to search for templates is the
`res://script_templates/` directory. The path can be changed by configuring `res://script_templates/` directory. The path can be changed by configuring
@ -41,8 +37,7 @@ the `editor/script_templates_search_path` setting in the
If no `script_templates` directory is found within a project, it is simply If no `script_templates` directory is found within a project, it is simply
ignored. ignored.
Language support and overriding behavior ## Language support and overriding behavior
----------------------------------------
Depending on whether a particular language implements a way to generate scripts Depending on whether a particular language implements a way to generate scripts
out of templates, it's possible to create a template which can be recognized by out of templates, it's possible to create a template which can be recognized by
@ -60,8 +55,7 @@ Note:
The built-in editor templates are automatically shadowed by the project-specific The built-in editor templates are automatically shadowed by the project-specific
templates given both scripts have the same filename. templates given both scripts have the same filename.
Default template ## Default template
----------------
The `Default` template is always generated dynamically per language and cannot The `Default` template is always generated dynamically per language and cannot
be configured nor overridden, but you can use these as the base for creating be configured nor overridden, but you can use these as the base for creating
@ -89,45 +83,37 @@ gdscript GDScript
# pass # pass
``` ```
List of template placeholders ## List of template placeholders
-----------------------------
The following describes the complete list of built-in template placeholders The following describes the complete list of built-in template placeholders
which are currently implemented. which are currently implemented.
Base placeholders ### Base placeholders
~~~~~~~~~~~~~~~~~
+-------------+----------------------------------------------------------------+
| Placeholder | Description | | Placeholder | Description |
+=============+================================================================+ |-------------|----------------------------------------------------------------|
| `%CLASS%` | The name of the new class (used in C# only). | | `%CLASS%` | The name of the new class (used in C# only). |
+-------------+----------------------------------------------------------------+ | `%BASE%` | The base type a new script inherits from. |
| `%BASE%` | The base type a new script inherits from. | | `%TS%` | Indentation placeholder. The exact type and number of |
+-------------+----------------------------------------------------------------+
| `%TS%` | Indentation placeholder. The exact type and number of |
| | whitespace characters used for indentation is determined by | | | whitespace characters used for indentation is determined by |
| | the `text_editor/indent/type` and `text_editor/indent/size`| | | the `text_editor/indent/type` and `text_editor/indent/size` |
| | settings in the `EditorSettings` | | | settings in the `EditorSettings` |
| | respectively. | | | respectively. |
+-------------+----------------------------------------------------------------+
Type placeholders
~~~~~~~~~~~~~~~~~ ### Type placeholders
These are only relevant for GDScript with static typing. Whether these These are only relevant for GDScript with static typing. Whether these
placeholders are actually replaced is determined by the placeholders are actually replaced is determined by the
`text_editor/completion/add_type_hints` setting in the `text_editor/completion/add_type_hints` setting in the
`EditorSettings`. `EditorSettings`.
+-------------------+--------------+
| Placeholder | Value | | Placeholder | Value |
+===================+==============+ |-------------------|--------------|
| `%INT_TYPE%` | `: int` | | `%INT_TYPE%` | `: int` |
+-------------------+--------------+ | `%STRING_TYPE%` | `: String` |
| `%STRING_TYPE%` | `: String` | | `%FLOAT_TYPE%` | `: float` |
+-------------------+--------------+ | `%VOID_RETURN%` | `-> void` |
| `%FLOAT_TYPE%` | `: float` |
+-------------------+--------------+
| `%VOID_RETURN%` | `-> void` |
+-------------------+--------------+

View File

@ -1,7 +1,6 @@
Evaluating expressions # Evaluating expressions
======================
Pandemonium provides an `Expression` class you can use to evaluate expressions. Pandemonium provides an `Expression` class you can use to evaluate expressions.
@ -19,8 +18,7 @@ Note:
The Expression class is independent from GDScript. The Expression class is independent from GDScript.
It's available even if you compile Pandemonium with the GDScript module disabled. It's available even if you compile Pandemonium with the GDScript module disabled.
Basic usage ## Basic usage
-----------
To evaluate a mathematical expression, use: To evaluate a mathematical expression, use:
@ -33,22 +31,18 @@ To evaluate a mathematical expression, use:
The following operators are available: The following operators are available:
+------------------------+-------------------------------------------------------------------------------------+
| Operator | Notes | | Operator | Notes |
+========================+=====================================================================================+ |------------------------|-------------------------------------------------------------------------------------|
| Addition `+` | Can also be used to concatenate strings and arrays: | | Addition `+` | Can also be used to concatenate strings and arrays: |
| | - `"hello" + " world"` = `hello world` | | | - `"hello" + " world"` = `hello world` |
| | - `[1, 2] + [3, 4]` = `[1, 2, 3, 4]` | | | - `[1, 2] + [3, 4]` = `[1, 2, 3, 4]` |
+------------------------+-------------------------------------------------------------------------------------+ | Subtraction (`-`) | |
| Subtraction (`-`) | | | Multiplication (`*`) | |
+------------------------+-------------------------------------------------------------------------------------+ | Division (`/`) | Performs and integer division if both operands are integers. |
| Multiplication (`*`) | |
+------------------------+-------------------------------------------------------------------------------------+
| Division (`/`) | Performs and integer division if both operands are integers. |
| | If at least one of them is a floating-point number, returns a floating-point value. | | | If at least one of them is a floating-point number, returns a floating-point value. |
+------------------------+-------------------------------------------------------------------------------------+ | Modulo (`%`) | Returns the remainder of an integer division. |
| Modulo (`%`) | Returns the remainder of an integer division. |
+------------------------+-------------------------------------------------------------------------------------+
Spaces around operators are optional. Also, keep in mind the usual Spaces around operators are optional. Also, keep in mind the usual
`order of operations ( https://en.wikipedia.org/wiki/Order_of_operations )` `order of operations ( https://en.wikipedia.org/wiki/Order_of_operations )`
@ -75,8 +69,7 @@ Arrays and dictionaries can be indexed like in GDScript:
Vector3(5, 6, 7).z Vector3(5, 6, 7).z
``` ```
Passing variables to an expression ## Passing variables to an expression
----------------------------------
You can pass variables to an expression. These variables will then You can pass variables to an expression. These variables will then
become available in the expression's "context" and will be substituted when used become available in the expression's "context" and will be substituted when used
@ -96,8 +89,7 @@ in the expression:
Both the variable names and variable values **must** be specified as an array, Both the variable names and variable values **must** be specified as an array,
even if you only define one variable. Also, variable names are **case-sensitive**. even if you only define one variable. Also, variable names are **case-sensitive**.
Setting a base instance for the expression ## Setting a base instance for the expression
------------------------------------------
By default, an expression has a base instance of `null`. This means the By default, an expression has a base instance of `null`. This means the
expression has no base instance associated to it. expression has no base instance associated to it.
@ -140,8 +132,7 @@ Warning:
cheating in your game, or may even introduce security vulnerabilities if you cheating in your game, or may even introduce security vulnerabilities if you
allow arbitrary clients to run expressions on other players' devices. allow arbitrary clients to run expressions on other players' devices.
Example script ## Example script
--------------
The script below demonstrates what the Expression class is capable of: The script below demonstrates what the Expression class is capable of:
@ -209,8 +200,7 @@ The output from the script will be:
0 0
``` ```
Built-in functions ## Built-in functions
------------------
Most methods available in the `@GDScript` scope are available in the Most methods available in the `@GDScript` scope are available in the
Expression class, even if no base instance is bound to the expression. Expression class, even if no base instance is bound to the expression.

View File

@ -1,7 +1,6 @@
Change scenes manually # Change scenes manually
======================
Sometimes it helps to have more control over how one swaps scenes around. Sometimes it helps to have more control over how one swaps scenes around.
As mentioned above, a `Viewport`'s child nodes As mentioned above, a `Viewport`'s child nodes
@ -27,8 +26,7 @@ balancing operation speed and memory consumption as well as balancing data
access and integrity. access and integrity.
1. **We can delete the existing scene.** 1. **We can delete the existing scene.**
`SceneTree.change_scene()` and `SceneTree.change_scene()` and `SceneTree.change_scene_to()`
`SceneTree.change_scene_to()`
will delete the current scene immediately. Developers can also delete the will delete the current scene immediately. Developers can also delete the
main scene though. Assuming the root node's name is "Main", one could do main scene though. Assuming the root node's name is "Main", one could do
`get_node("/root/Main").free()` to delete the whole scene. `get_node("/root/Main").free()` to delete the whole scene.

View File

@ -1,10 +1,5 @@
.. meta::
:keywords: Signal
# Instancing with signals
Instancing with signals
=======================
Signals provide a way to decouple game objects, allowing you to avoid forcing a Signals provide a way to decouple game objects, allowing you to avoid forcing a
fixed arrangement of nodes. One sign that a signal might be called for is when fixed arrangement of nodes. One sign that a signal might be called for is when
@ -15,8 +10,7 @@ and may want to place them in an arbitrary location in the running scene tree.
Below we'll consider an example of such a situation: firing bullets. Below we'll consider an example of such a situation: firing bullets.
Shooting example ## Shooting example
----------------
Consider a player character that can rotate and shoot towards the mouse. Every Consider a player character that can rotate and shoot towards the mouse. Every
time the mouse button is clicked, we create an instance of the bullet at the time the mouse button is clicked, we create an instance of the bullet at the

View File

@ -1,10 +1,8 @@
Pausing games and process mode # Pausing games and process mode
==============================
Introduction ## Introduction
------------
In most games it is desirable to, at some point, interrupt the In most games it is desirable to, at some point, interrupt the
game to do something else, such as taking a break or changing options. game to do something else, such as taking a break or changing options.
@ -12,8 +10,7 @@ Implementing a fine-grained control for what can be paused (and what cannot)
is a lot of work, so a simple framework for pausing is provided in is a lot of work, so a simple framework for pausing is provided in
Pandemonium. Pandemonium.
How pausing works ## How pausing works
-----------------
To pause the game the pause state must be set. This is done by assigning To pause the game the pause state must be set. This is done by assigning
`true` to the `SceneTree.paused` property: `true` to the `SceneTree.paused` property:
@ -32,8 +29,7 @@ Note:
The physics servers can be made active while the game is The physics servers can be made active while the game is
paused by using their `set_active` methods. paused by using their `set_active` methods.
Process Modes ## Process Modes
-------------
Each node in Pandemonium has a "Pause Mode" that defines when it processes. It can Each node in Pandemonium has a "Pause Mode" that defines when it processes. It can
be found and changed under a node's `Node` properties in the inspector. be found and changed under a node's `Node` properties in the inspector.
@ -78,8 +74,7 @@ paused physics will **NOT** work for it by default. As stated earlier this is
because the physics servers are turned off. The physics servers can be made because the physics servers are turned off. The physics servers can be made
active while the game is paused by using their `set_active` methods. active while the game is paused by using their `set_active` methods.
Pause Menu Example ## Pause Menu Example
------------------
Here is an example of a pause menu. Create a popup or panel with controls Here is an example of a pause menu. Create a popup or panel with controls
inside, and set its pause mode to "Process" then hide it. By setting the inside, and set its pause mode to "Process" then hide it. By setting the

View File

@ -1,18 +1,15 @@
File system # File system
===========
Introduction ## Introduction
------------
A file system manages how assets are stored and how they are accessed. A file system manages how assets are stored and how they are accessed.
A well-designed file system also allows multiple developers to edit the A well-designed file system also allows multiple developers to edit the
same source files and assets while collaborating. Pandemonium stores same source files and assets while collaborating. Pandemonium stores
all assets as files in its file system. all assets as files in its file system.
Implementation ## Implementation
--------------
The file system stores resources on disk. Anything, from a script, to a scene or a The file system stores resources on disk. Anything, from a script, to a scene or a
PNG image is a resource to the engine. If a resource contains properties PNG image is a resource to the engine. If a resource contains properties
@ -32,12 +29,11 @@ Example of file system contents:
/project.pandemonium /project.pandemonium
/enemy/enemy.tscn /enemy/enemy.tscn
/enemy/enemy.gd /enemy/enemy.gd
/enemy/enemysprite.png) /enemy/enemysprite.png
/player/player.gd /player/player.gd
``` ```
project.pandemonium ## project.pandemonium
-------------
The `project.pandemonium` file is the project description file, and it is always found The `project.pandemonium` file is the project description file, and it is always found
at the root of the project. In fact, its location defines where the root is. This at the root of the project. In fact, its location defines where the root is. This
@ -47,16 +43,14 @@ This file contains the project configuration in plain text, using the win.ini
format. Even an empty `project.pandemonium` can function as a basic definition of format. Even an empty `project.pandemonium` can function as a basic definition of
a blank project. a blank project.
Path delimiter ## Path delimiter
--------------
Pandemonium only supports `/` as a path delimiter. This is done for Pandemonium only supports `/` as a path delimiter. This is done for
portability reasons. All operating systems support this, even Windows, portability reasons. All operating systems support this, even Windows,
so a path such as `C:\project\project.pandemonium` needs to be typed as so a path such as `C:\project\project.pandemonium` needs to be typed as
`C:/project/project.pandemonium`. `C:/project/project.pandemonium`.
Resource path ## Resource path
-------------
When accessing resources, using the host OS file system layout can be When accessing resources, using the host OS file system layout can be
cumbersome and non-portable. To solve this problem, the special path cumbersome and non-portable. To solve this problem, the special path
@ -71,8 +65,7 @@ the editor. When exported or when running on different devices (such as
phones or consoles, or running from DVD), the file system will become phones or consoles, or running from DVD), the file system will become
read-only and writing will no longer be permitted. read-only and writing will no longer be permitted.
User path ## User path
---------
Writing to disk is still needed for tasks such as saving game state or Writing to disk is still needed for tasks such as saving game state or
downloading content packs. To this end, the engine ensures that there is a downloading content packs. To this end, the engine ensures that there is a
@ -80,16 +73,14 @@ special path `user://` that is always writable. This path resolves
differently depending on the OS the project is running on. Local path differently depending on the OS the project is running on. Local path
resolution is further explained in `doc_data_paths`. resolution is further explained in `doc_data_paths`.
Host file system ## Host file system
----------------
Alternatively host file system paths can also be used, but this is not recommended Alternatively host file system paths can also be used, but this is not recommended
for a released product as these paths are not guaranteed to work on all platforms. for a released product as these paths are not guaranteed to work on all platforms.
However, using host file system paths can be useful when writing development However, using host file system paths can be useful when writing development
tools in Pandemonium. tools in Pandemonium.
Drawbacks ## Drawbacks
---------
There are some drawbacks to this simple file system design. The first issue is that There are some drawbacks to this simple file system design. The first issue is that
moving assets around (renaming them or moving them from one path to another inside moving assets around (renaming them or moving them from one path to another inside
@ -102,8 +93,8 @@ to be fixed manually (Pandemonium detects this and helps you fix them anyway, bu
go the hard route?). go the hard route?).
The second is that, under Windows and macOS, file and path names are case insensitive. The second is that, under Windows and macOS, file and path names are case insensitive.
If a developer working in a case insensitive host file system saves an asset as `myfile.png)`, If a developer working in a case insensitive host file system saves an asset as `myfile.png`,
but then references it as `myfile.png)`, it will work fine on their platform, but not but then references it as `myfile.png`, it will work fine on their platform, but not
on other platforms, such as Linux, Android, etc. This may also apply to exported binaries, on other platforms, such as Linux, Android, etc. This may also apply to exported binaries,
which use a compressed package to store all files. which use a compressed package to store all files.

View File

@ -1,10 +1,8 @@
Resources # Resources
=========
Nodes and resources ## Nodes and resources
-------------------
Up to this tutorial, we focused on the `Node` Up to this tutorial, we focused on the `Node`
class in Pandemonium as that's the one you use to code behavior and class in Pandemonium as that's the one you use to code behavior and
@ -18,10 +16,8 @@ do anything on their own: instead, nodes use the data contained in resources.
Anything Pandemonium saves or loads from disk is a resource. Be it a scene (a `.tscn` Anything Pandemonium saves or loads from disk is a resource. Be it a scene (a `.tscn`
or an `.scn` file), an image, a script... Here are some `Resource` examples: or an `.scn` file), an image, a script... Here are some `Resource` examples:
`Texture`, `Mesh `Texture`, `Mesh( Mesh )`, `Animation`, `AudioStream( AudioStream )`, `Font`,
( Mesh )`, `Animation`, `AudioStream `Translation( Translation )`.
( AudioStream )`, `Font`, `Translation
( Translation )`.
When the engine loads a resource from disk, **it only loads it once**. If a copy When the engine loads a resource from disk, **it only loads it once**. If a copy
of that resource is already in memory, trying to load the resource again will of that resource is already in memory, trying to load the resource again will
@ -35,8 +31,7 @@ resources as properties:
![](img/nodes_resources.png) ![](img/nodes_resources.png)
External vs built-in ## External vs built-in
--------------------
There are two ways to save resources. They can be: There are two ways to save resources. They can be:
@ -63,12 +58,10 @@ save, Pandemonium will save the image inside the `.tscn` scene file.
Note: Note:
Even if you save a built-in resource, when you instance a scene multiple Even if you save a built-in resource, when you instance a scene multiple
times, the engine will only load one copy of it. times, the engine will only load one copy of it.
Loading resources from code ## Loading resources from code
---------------------------
There are two ways to load resources from code. First, you can use the `load()` function anytime: There are two ways to load resources from code. First, you can use the `load()` function anytime:
@ -92,8 +85,7 @@ gdscript GDScript
get_node("sprite").texture = res get_node("sprite").texture = res
``` ```
Loading scenes ## Loading scenes
--------------
Scenes are also resources, but there is a catch. Scenes saved to disk are Scenes are also resources, but there is a catch. Scenes saved to disk are
resources of type `PackedScene`. The resources of type `PackedScene`. The
@ -120,15 +112,13 @@ enemies, bullets, effects, etc. without having to load them again from disk each
time. Remember that, as always, images, meshes, etc. are all shared between the time. Remember that, as always, images, meshes, etc. are all shared between the
scene instances. scene instances.
Freeing resources ## Freeing resources
-----------------
When a `Resource` is no longer in use, it will automatically free itself. When a `Resource` is no longer in use, it will automatically free itself.
Since, in most cases, Resources are contained in Nodes, when you free a node, Since, in most cases, Resources are contained in Nodes, when you free a node,
the engine frees all the resources it owns as well if no other node uses them. the engine frees all the resources it owns as well if no other node uses them.
Creating your own resources ## Creating your own resources
---------------------------
Like any Object in Pandemonium, users can also script Resources. Resource scripts Like any Object in Pandemonium, users can also script Resources. Resource scripts
inherit the ability to freely translate between object properties and serialized inherit the ability to freely translate between object properties and serialized
@ -272,4 +262,4 @@ Warning:
# This will NOT serialize the 'value' property. # This will NOT serialize the 'value' property.
ResourceSaver.save("res://my_res.tres", my_res) ResourceSaver.save("res://my_res.tres", my_res)
``` ```

View File

@ -1,10 +1,8 @@
Singletons (AutoLoad) # Singletons (AutoLoad)
=====================
Introduction ## Introduction
------------
Pandemonium's scene system, while powerful and flexible, has a drawback: there is no Pandemonium's scene system, while powerful and flexible, has a drawback: there is no
method for storing information (e.g. a player's score or inventory) that is method for storing information (e.g. a player's score or inventory) that is
@ -37,26 +35,22 @@ Autoloading nodes and scripts can give us these characteristics.
Note: Note:
Pandemonium won't make an AutoLoad a "true" singleton as per the singleton design Pandemonium won't make an AutoLoad a "true" singleton as per the singleton design
pattern. It may still be instanced more than once by the user if desired. pattern. It may still be instanced more than once by the user if desired.
Tip: Tip:
If you're creating an autoload as part of an editor plugin, consider If you're creating an autoload as part of an editor plugin, consider
`registering it automatically in the Project Settings ( doc_making_plugins_autoload )` `registering it automatically in the Project Settings ( doc_making_plugins_autoload )`
when the plugin is enabled. when the plugin is enabled.
AutoLoad ## AutoLoad
--------
You can create an AutoLoad to load a scene or a script that inherits from You can create an AutoLoad to load a scene or a script that inherits from
`Node`. `Node`.
Note: Note:
When autoloading a script, a `Node` will be created and the script will be When autoloading a script, a `Node` will be created and the script will be
attached to it. This node will be added to the root viewport before any attached to it. This node will be added to the root viewport before any
other scenes are loaded. other scenes are loaded.
@ -106,8 +100,7 @@ Warning:
Autoloads must **not** be removed using `free()` or `queue_free()` at Autoloads must **not** be removed using `free()` or `queue_free()` at
runtime, or the engine will crash. runtime, or the engine will crash.
Custom scene switcher ## Custom scene switcher
---------------------
This tutorial will demonstrate building a scene switcher using autoloads. This tutorial will demonstrate building a scene switcher using autoloads.
For basic scene switching, you can use the For basic scene switching, you can use the
@ -116,15 +109,14 @@ method (see `doc_scene_tree` for details). However, if you need more
complex behavior when changing scenes, this method provides more functionality. complex behavior when changing scenes, this method provides more functionality.
To begin, download the template from here: To begin, download the template from here:
:download:`autoload.zip <files/autoload.zip )` and open it in Pandemonium. :download:`autoload.zip ( files/autoload.zip )` and open it in Pandemonium.
The project contains two scenes: `Scene1.tscn` and `Scene2.tscn`. Each The project contains two scenes: `Scene1.tscn` and `Scene2.tscn`. Each
scene contains a label displaying the scene name and a button with its scene contains a label displaying the scene name and a button with its
`pressed()` signal connected. When you run the project, it starts in `pressed()` signal connected. When you run the project, it starts in
`Scene1.tscn`. However, pressing the button does nothing. `Scene1.tscn`. However, pressing the button does nothing.
Global.gd ### Global.gd
~~~~~~~~~
Switch to the **Script** tab and create a new script called `Global.gd`. Switch to the **Script** tab and create a new script called `Global.gd`.
Make sure it inherits from `Node`: Make sure it inherits from `Node`:

View File

@ -1,17 +1,14 @@
Using SceneTree # Using SceneTree
===============
Introduction ## Introduction
------------
In previous tutorials, everything revolved around the concept of In previous tutorials, everything revolved around the concept of
nodes. Scenes are collections of nodes. They become active once nodes. Scenes are collections of nodes. They become active once
they enter the *scene tree*. they enter the *scene tree*.
MainLoop ## MainLoop
--------
The way Pandemonium works internally is as follows. There is the The way Pandemonium works internally is as follows. There is the
`OS` class, `OS` class,
@ -29,8 +26,7 @@ methods, for initialization, idle (frame-synchronized callback), fixed
(physics-synchronized callback), and input. Again, this is low (physics-synchronized callback), and input. Again, this is low
level and when making games in Pandemonium, writing your own MainLoop seldom makes sense. level and when making games in Pandemonium, writing your own MainLoop seldom makes sense.
SceneTree ## SceneTree
---------
One of the ways to explain how Pandemonium works is that it's a high level One of the ways to explain how Pandemonium works is that it's a high level
game engine over a low level middleware. game engine over a low level middleware.
@ -59,8 +55,7 @@ When a node is part of the Scene Tree, the
singleton can be obtained by calling singleton can be obtained by calling
`Node.get_tree()`. `Node.get_tree()`.
Root viewport ## Root viewport
-------------
The root `Viewport` The root `Viewport`
is always at the top of the scene. From a node, it can be obtained in is always at the top of the scene. From a node, it can be obtained in
@ -82,8 +77,7 @@ While other viewports can be created in the scene (for split-screen
effects and such), this one is the only one that is never created by the effects and such), this one is the only one that is never created by the
user. It's created automatically inside SceneTree. user. It's created automatically inside SceneTree.
Scene tree ## Scene tree
----------
When a node is connected, directly or indirectly, to the root When a node is connected, directly or indirectly, to the root
viewport, it becomes part of the *scene tree*. viewport, it becomes part of the *scene tree*.
@ -98,8 +92,7 @@ to everything they need to process, get input, display 2D and 3D visuals,
receive and send notifications, play sounds, etc. When they are removed from the receive and send notifications, play sounds, etc. When they are removed from the
*scene tree*, they lose these abilities. *scene tree*, they lose these abilities.
Tree order ## Tree order
----------
Most node operations in Pandemonium, such as drawing 2D, processing, or getting Most node operations in Pandemonium, such as drawing 2D, processing, or getting
notifications are done in tree order. This means that parents and notifications are done in tree order. This means that parents and
@ -108,25 +101,23 @@ the current node.
![](img/toptobottom.png) ![](img/toptobottom.png)
"Becoming active" by entering the *Scene Tree* ## "Becoming active" by entering the *Scene Tree*
----------------------------------------------
#. A scene is loaded from disk or created by scripting. 1. A scene is loaded from disk or created by scripting.
#. The root node of that scene (only one root, remember?) is added as 2. The root node of that scene (only one root, remember?) is added as
either a child of the "root" Viewport (from SceneTree), or to any either a child of the "root" Viewport (from SceneTree), or to any
child or grandchild of it. child or grandchild of it.
#. Every node of the newly added scene, will receive the "enter_tree" 3. Every node of the newly added scene, will receive the "enter_tree"
notification ( _enter_tree() callback in GDScript) in top-to-bottom notification ( _enter_tree() callback in GDScript) in top-to-bottom
order. order.
#. An extra notification, "ready" ( _ready() callback in GDScript) is 4. An extra notification, "ready" ( _ready() callback in GDScript) is
provided for convenience, when a node and all its children are provided for convenience, when a node and all its children are
inside the active scene. inside the active scene.
#. When a scene (or part of it) is removed, they receive the "exit 5. When a scene (or part of it) is removed, they receive the "exit
scene" notification ( _exit_tree() callback in GDScript) in scene" notification ( _exit_tree() callback in GDScript) in
bottom-to-top order bottom-to-top order
Changing current scene ## Changing current scene
----------------------
After a scene is loaded, it is often desired to change this scene for After a scene is loaded, it is often desired to change this scene for
another one. The simple way to do this is to use the another one. The simple way to do this is to use the

View File

@ -1,10 +1,8 @@
Scene Unique Nodes # Scene Unique Nodes
==================
Introduction ## Introduction
------------
There are times in a project where a node needs to be called There are times in a project where a node needs to be called
from a script. However, its position in the tree might change from a script. However, its position in the tree might change
@ -15,8 +13,7 @@ In situations like this, a node can be turned into a scene
unique node to avoid having to update a script every time unique node to avoid having to update a script every time
its path is changed. its path is changed.
Creating and using them ## Creating and using them
-----------------------
In the Scene tree dock, right-click on a node and select In the Scene tree dock, right-click on a node and select
**Access as Scene Unique Name** in the context menu. **Access as Scene Unique Name** in the context menu.

View File

@ -1,7 +1,6 @@
Overview of debugging tools # Overview of debugging tools
===========================
This guide will give you an overview of the available debugging tools in the This guide will give you an overview of the available debugging tools in the
engine. engine.
@ -14,14 +13,12 @@ in the running game.
Finally, you have options to debug the game running on a remote device Finally, you have options to debug the game running on a remote device
and to reload changes to your scenes or your code while the game is running. and to reload changes to your scenes or your code while the game is running.
Debugger Panel ## Debugger Panel
--------------
Many of Pandemonium's debugging tools are part of the Debugger panel, which you can Many of Pandemonium's debugging tools are part of the Debugger panel, which you can
find information about in `doc_debugger_panel`. find information about in `doc_debugger_panel`.
Debug menu options ## Debug menu options
------------------
There are a few common debug options you can toggle on or off when running There are a few common debug options you can toggle on or off when running
your game in the editor, which can help you in debugging your game. your game in the editor, which can help you in debugging your game.
@ -32,14 +29,12 @@ You can find these options in the **Debug** editor menu.
Here are the descriptions of the options: Here are the descriptions of the options:
Deploy with Remote Debug #### Deploy with Remote Debug
++++++++++++++++++++++++
When exporting and deploying, the resulting executable will attempt to connect When exporting and deploying, the resulting executable will attempt to connect
to the IP of your computer for debugging. to the IP of your computer for debugging.
Small Deploy with Network FS #### Small Deploy with Network FS
++++++++++++++++++++++++++++
This option speeds up testing for games with a large footprint on remote devices. This option speeds up testing for games with a large footprint on remote devices.
@ -49,31 +44,26 @@ from the project over the network.
Also, on Android, the game is deployed using the USB cable to speed up deployment. Also, on Android, the game is deployed using the USB cable to speed up deployment.
Visible Collision Shapes #### Visible Collision Shapes
++++++++++++++++++++++++
This option makes collision shapes and raycast nodes visible in the running game. This option makes collision shapes and raycast nodes visible in the running game.
Visible Navigation #### Visible Navigation
++++++++++++++++++
Navigation meshes and polygons will be visible on the running game. Navigation meshes and polygons will be visible on the running game.
Sync Scene Changes #### Sync Scene Changes
++++++++++++++++++
With this option, any change you make to a scene in the editor at runtime With this option, any change you make to a scene in the editor at runtime
appears instantly. When used remotely on a device, this is more efficient appears instantly. When used remotely on a device, this is more efficient
with the network filesystem. with the network filesystem.
Sync Script Changes #### Sync Script Changes
+++++++++++++++++++
Any script that is saved will be reloaded on the running game. When used Any script that is saved will be reloaded on the running game. When used
remotely on a device, this is more efficient with the network filesystem. remotely on a device, this is more efficient with the network filesystem.
Script editor debug tools and options ## Script editor debug tools and options
-------------------------------------
The script editor has its own set of debug tools for use with breakpoints and The script editor has its own set of debug tools for use with breakpoints and
two options. The breakpoint tools can also be found in the **Debugger** tab two options. The breakpoint tools can also be found in the **Debugger** tab
@ -97,33 +87,28 @@ Warning:
`running in a thread ( doc_using_multiple_threads )`. `running in a thread ( doc_using_multiple_threads )`.
This is a current limitation of the GDScript debugger. This is a current limitation of the GDScript debugger.
Debug project settings ## Debug project settings
----------------------
In the project settings, there is a **Debug** category with three subcategories In the project settings, there is a **Debug** category with three subcategories
which control different things. which control different things.
Settings #### Settings
++++++++
These are some general settings such as printing the current FPS These are some general settings such as printing the current FPS
to the **Output** panel, the maximum amount of functions when profiling to the **Output** panel, the maximum amount of functions when profiling
and others. and others.
GDScript #### GDScript
++++++++
These settings allow you to toggle specific GDScript warnings, such as for These settings allow you to toggle specific GDScript warnings, such as for
unused variables. You can also turn off warnings completely. unused variables. You can also turn off warnings completely.
Shapes #### Shapes
++++++
Shapes are where you can adjust the color of shapes that only appear for Shapes are where you can adjust the color of shapes that only appear for
debugging purposes, such as collision and navigation shapes. debugging purposes, such as collision and navigation shapes.
Remote in scene dock ## Remote in scene dock
--------------------
When running a game in the editor two options appear at the top of the **Scene** When running a game in the editor two options appear at the top of the **Scene**
dock, **Remote** and **Local**. While using **Remote** you can inspect or change dock, **Remote** and **Local**. While using **Remote** you can inspect or change

View File

@ -1,7 +1,6 @@
Debugger panel # Debugger panel
==============
Many of Pandemonium's debugging tools, including the debugger, can be found in the Many of Pandemonium's debugging tools, including the debugger, can be found in the
debugger panel at the bottom of the screen. Click on **Debugger** to open it. debugger panel at the bottom of the screen. Click on **Debugger** to open it.
@ -10,8 +9,7 @@ debugger panel at the bottom of the screen. Click on **Debugger** to open it.
The debugger panel is split into several tabs, each focusing on a specific task. The debugger panel is split into several tabs, each focusing on a specific task.
Debugger #### Debugger
++++++++
The Debugger tab opens automatically when the GDScript compiler reaches The Debugger tab opens automatically when the GDScript compiler reaches
a breakpoint in your code. a breakpoint in your code.
@ -39,15 +37,13 @@ Warning:
`running in a thread ( doc_using_multiple_threads )`. `running in a thread ( doc_using_multiple_threads )`.
This is a current limitation of the GDScript debugger. This is a current limitation of the GDScript debugger.
Errors #### Errors
++++++
This is where error and warning messages are printed while running the game. This is where error and warning messages are printed while running the game.
You can disable specific warnings in **Project Settings > Debug > GDScript**. You can disable specific warnings in **Project Settings > Debug > GDScript**.
Profiler #### Profiler
++++++++
The debugger comes with three profilers for your processor, network operations, The debugger comes with three profilers for your processor, network operations,
and video memory. and video memory.
@ -76,24 +72,21 @@ If you want to add something to your graph or think it looks too cluttered,
you can check and uncheck the box next to an item to add or remove it you can check and uncheck the box next to an item to add or remove it
from the graph. from the graph.
Network Profiler #### Network Profiler
++++++++++++++++
The Network Profiler contains a list of all the nodes that communicate over the The Network Profiler contains a list of all the nodes that communicate over the
multiplayer API and, for each one, some counters on the amount of incoming and multiplayer API and, for each one, some counters on the amount of incoming and
outgoing network interactions. It also features a bandwidth meter that displays outgoing network interactions. It also features a bandwidth meter that displays
the total bandwidth usage at any given moment. the total bandwidth usage at any given moment.
Monitors #### Monitors
++++++++
The monitors are graphs of several aspects of the game while its running such as The monitors are graphs of several aspects of the game while its running such as
FPS, memory usage, how many nodes are in a scene and more. All monitors keep FPS, memory usage, how many nodes are in a scene and more. All monitors keep
track of stats automatically, so even if one monitor isn't open while the game track of stats automatically, so even if one monitor isn't open while the game
is running, you can open it later and see how the values changed. is running, you can open it later and see how the values changed.
Video RAM #### Video RAM
+++++++++
The **Video RAM** tab shows the video RAM usage of the game while it is running. The **Video RAM** tab shows the video RAM usage of the game while it is running.
It provides a list of every resource using video RAM by resource path, the type It provides a list of every resource using video RAM by resource path, the type
@ -102,8 +95,7 @@ using. There is also a total video RAM usage number at the top right of the pane
![](img/video_ram.png) ![](img/video_ram.png)
Misc #### Misc
++++
The **Misc** tab contains tools to identify the control nodes you are clicking The **Misc** tab contains tools to identify the control nodes you are clicking
at runtime: at runtime:

View File

@ -1,10 +1,8 @@
GDScript basics # GDScript basics
===============
Introduction ## Introduction
------------
*GDScript* is a high-level, dynamically typed programming language used to *GDScript* is a high-level, dynamically typed programming language used to
create content. It uses a syntax similar to create content. It uses a syntax similar to
@ -13,8 +11,7 @@ create content. It uses a syntax similar to
to be optimized for and tightly integrated with Pandemonium Engine, allowing great to be optimized for and tightly integrated with Pandemonium Engine, allowing great
flexibility for content creation and integration. flexibility for content creation and integration.
History ### History
~~~~~~~
Note: Note:
@ -22,8 +19,7 @@ Note:
Documentation about GDScript's history has been moved to the Documentation about GDScript's history has been moved to the
`Frequently Asked Questions ( doc_faq_what_is_gdscript )`. `Frequently Asked Questions ( doc_faq_what_is_gdscript )`.
Example of GDScript ### Example of GDScript
~~~~~~~~~~~~~~~~~~~
Some people can learn better by taking a look at the syntax, so Some people can learn better by taking a look at the syntax, so
here's a simple example of how GDScript looks. here's a simple example of how GDScript looks.
@ -107,28 +103,26 @@ here's a simple example of how GDScript looks.
print("Constructed!") print("Constructed!")
var lv = Something.new() var lv = Something.new()
print(lv.a) print(lv.a)
```
If you have previous experience with statically typed languages such as If you have previous experience with statically typed languages such as
C, C++, or C# but never used a dynamically typed one before, it is advised you C, C++, or C# but never used a dynamically typed one before, it is advised you
read this tutorial: `doc_gdscript_more_efficiently`. read this tutorial: `doc_gdscript_more_efficiently`.
Language ## Language
--------
In the following, an overview is given to GDScript. Details, such as which In the following, an overview is given to GDScript. Details, such as which
methods are available to arrays or other objects, should be looked up in methods are available to arrays or other objects, should be looked up in
the linked class descriptions. the linked class descriptions.
Identifiers ### Identifiers
~~~~~~~~~~~
Any string that restricts itself to alphabetic characters (`a` to Any string that restricts itself to alphabetic characters (`a` to
`z` and `A` to `Z`), digits (`0` to `9`) and `` qualifies `z` and `A` to `Z`), digits (`0` to `9`) and `` qualifies
as an identifier. Additionally, identifiers must not begin with a digit. as an identifier. Additionally, identifiers must not begin with a digit.
Identifiers are case-sensitive (`foo` is different from `FOO`). Identifiers are case-sensitive (`foo` is different from `FOO`).
Keywords ### Keywords
~~~~~~~~
The following is the list of keywords supported by the language. Since The following is the list of keywords supported by the language. Since
keywords are reserved words (tokens), they can't be used as identifiers. keywords are reserved words (tokens), they can't be used as identifiers.
@ -138,111 +132,64 @@ as listed in the following sections are also reserved.
Keywords are defined in the `GDScript tokenizer ( https://github.com/Relintai/pandemonium_engine/blob/master/modules/gdscript/gdscript_tokenizer.cpp )` Keywords are defined in the `GDScript tokenizer ( https://github.com/Relintai/pandemonium_engine/blob/master/modules/gdscript/gdscript_tokenizer.cpp )`
in case you want to take a look under the hood. in case you want to take a look under the hood.
+------------+---------------------------------------------------------------------------------------------------------------+
| Keyword | Description |
+============+===============================================================================================================+
| if | See `if/else/elif`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| elif | See `if/else/elif`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| else | See `if/else/elif`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| for | See for_. |
+------------+---------------------------------------------------------------------------------------------------------------+
| while | See while_. |
+------------+---------------------------------------------------------------------------------------------------------------+
| match | See match_. |
+------------+---------------------------------------------------------------------------------------------------------------+
| break | Exits the execution of the current `for` or `while` loop. |
+------------+---------------------------------------------------------------------------------------------------------------+
| continue | Immediately skips to the next iteration of the `for` or `while` loop. |
+------------+---------------------------------------------------------------------------------------------------------------+
| pass | Used where a statement is required syntactically but execution of code is undesired, e.g. in empty functions. |
+------------+---------------------------------------------------------------------------------------------------------------+
| return | Returns a value from a function. |
+------------+---------------------------------------------------------------------------------------------------------------+
| class | Defines an inner class. |
+------------+---------------------------------------------------------------------------------------------------------------+
| class_name | Defines a class name and optional icon for your script. |
+------------+---------------------------------------------------------------------------------------------------------------+
| extends | Defines what class to extend with the current class. |
+------------+---------------------------------------------------------------------------------------------------------------+
| is | Tests whether a variable extends a given class, or is of a given built-in type. |
+------------+---------------------------------------------------------------------------------------------------------------+
| as | Cast the value to a given type if possible. |
+------------+---------------------------------------------------------------------------------------------------------------+
| self | Refers to current class instance. |
+------------+---------------------------------------------------------------------------------------------------------------+
| tool | Executes the script in the editor. |
+------------+---------------------------------------------------------------------------------------------------------------+
| signal | Defines a signal. |
+------------+---------------------------------------------------------------------------------------------------------------+
| func | Defines a function. |
+------------+---------------------------------------------------------------------------------------------------------------+
| static | Defines a static function. Static member variables are not allowed. |
+------------+---------------------------------------------------------------------------------------------------------------+
| const | Defines a constant. |
+------------+---------------------------------------------------------------------------------------------------------------+
| enum | Defines an enum. |
+------------+---------------------------------------------------------------------------------------------------------------+
| var | Defines a variable. |
+------------+---------------------------------------------------------------------------------------------------------------+
| onready | Initializes a variable once the Node the script is attached to and its children are part of the scene tree. |
+------------+---------------------------------------------------------------------------------------------------------------+
| export | Saves a variable along with the resource it's attached to and makes it visible and modifiable in the editor. |
+------------+---------------------------------------------------------------------------------------------------------------+
| setget | Defines setter and getter functions for a variable. |
+------------+---------------------------------------------------------------------------------------------------------------+
| breakpoint | Editor helper for debugger breakpoints. |
+------------+---------------------------------------------------------------------------------------------------------------+
| preload | Preloads a class or variable. See `Classes as resources`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| yield | Coroutine support. See `Coroutines with yield`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| assert | Asserts a condition, logs error on failure. Ignored in non-debug builds. See `Assert keyword`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| remote | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| master | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| puppet | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| remotesync | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| mastersync | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| puppetsync | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
+------------+---------------------------------------------------------------------------------------------------------------+
| PI | PI constant. |
+------------+---------------------------------------------------------------------------------------------------------------+
| TAU | TAU constant. |
+------------+---------------------------------------------------------------------------------------------------------------+
| INF | Infinity constant. Used for comparisons. |
+------------+---------------------------------------------------------------------------------------------------------------+
| NAN | NAN (not a number) constant. Used for comparisons. |
+------------+---------------------------------------------------------------------------------------------------------------+
Operators | Keyword | Description |
~~~~~~~~~ |------------|---------------------------------------------------------------------------------------------------------------|
| if | See `if/else/elif`. |
| elif | See `if/else/elif`. |
| else | See `if/else/elif`. |
| for | See for_. |
| while | See while_. |
| match | See match_. |
| break | Exits the execution of the current `for` or `while` loop. |
| continue | Immediately skips to the next iteration of the `for` or `while` loop. |
| pass | Used where a statement is required syntactically but execution of code is undesired, e.g. in empty functions. |
| return | Returns a value from a function. |
| class | Defines an inner class. |
| class_name | Defines a class name and optional icon for your script. |
| extends | Defines what class to extend with the current class. |
| is | Tests whether a variable extends a given class, or is of a given built-in type. |
| as | Cast the value to a given type if possible. |
| self | Refers to current class instance. |
| tool | Executes the script in the editor. |
| signal | Defines a signal. |
| func | Defines a function. |
| static | Defines a static function. Static member variables are not allowed. |
| const | Defines a constant. |
| enum | Defines an enum. |
| var | Defines a variable. |
| onready | Initializes a variable once the Node the script is attached to and its children are part of the scene tree. |
| export | Saves a variable along with the resource it's attached to and makes it visible and modifiable in the editor. |
| setget | Defines setter and getter functions for a variable. |
| breakpoint | Editor helper for debugger breakpoints. |
| preload | Preloads a class or variable. See `Classes as resources`. |
| yield | Coroutine support. See `Coroutines with yield`. |
| assert | Asserts a condition, logs error on failure. Ignored in non-debug builds. See `Assert keyword`. |
| remote | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
| master | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
| puppet | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
| remotesync | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
| mastersync | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
| puppetsync | Networking RPC annotation. See `high-level multiplayer docs ( doc_high_level_multiplayer )`. |
| PI | PI constant. |
| TAU | TAU constant. |
| INF | Infinity constant. Used for comparisons. |
| NAN | NAN (not a number) constant. Used for comparisons. |
### Operators
The following is the list of supported operators and their precedence. The following is the list of supported operators and their precedence.
+------------------------------------------------------------------------+-----------------------------------------+
| **Operator** | **Description** | | **Operator** | **Description** |
+------------------------------------------------------------------------+-----------------------------------------+ |------------------------------------------------------------------------|-----------------------------------------|
| `x[index]` | Subscription (highest priority) | | `x[index]` | Subscription (highest priority) |
+------------------------------------------------------------------------+-----------------------------------------+ | `x.attribute` | Attribute reference |
| `x.attribute` | Attribute reference | | `foo()` | Function call |
+------------------------------------------------------------------------+-----------------------------------------+ | `is` | Instance type checker |
| `foo()` | Function call | | `~` | Bitwise NOT |
+------------------------------------------------------------------------+-----------------------------------------+ | `-x` | Negative / Unary negation |
| `is` | Instance type checker | | `*` `/` `%` | Multiplication / Division / Remainder |
+------------------------------------------------------------------------+-----------------------------------------+
| `~` | Bitwise NOT |
+------------------------------------------------------------------------+-----------------------------------------+
| `-x` | Negative / Unary negation |
+------------------------------------------------------------------------+-----------------------------------------+
| `*` `/` `%` | Multiplication / Division / Remainder |
| | | | | |
| | These operators have the same behavior | | | These operators have the same behavior |
| | as C++. Integer division is truncated | | | as C++. Integer division is truncated |
@ -251,66 +198,44 @@ The following is the list of supported operators and their precedence.
| | available for ints ("fmod" for floats), | | | available for ints ("fmod" for floats), |
| | and is additionally used for Format | | | and is additionally used for Format |
| | Strings | | | Strings |
+------------------------------------------------------------------------+-----------------------------------------+ | `+` | Addition / Concatenation of arrays |
| `+` | Addition / Concatenation of arrays | | `-` | Subtraction |
+------------------------------------------------------------------------+-----------------------------------------+ | `&lt;&lt;` `&gt; )` | Bit shifting |
| `-` | Subtraction | | `&` | Bitwise AND |
+------------------------------------------------------------------------+-----------------------------------------+ | `^` | Bitwise XOR |
| `<<` `> )` | Bit shifting | | `|` | Bitwise OR |
+------------------------------------------------------------------------+-----------------------------------------+ | `&lt;` ` )` `==` `!=` `&gt;=` `&lt;=` | Comparisons |
| `&` | Bitwise AND | | `in` | When used with the `if` keyword it |
+------------------------------------------------------------------------+-----------------------------------------+
| `^` | Bitwise XOR |
+------------------------------------------------------------------------+-----------------------------------------+
| `|` | Bitwise OR |
+------------------------------------------------------------------------+-----------------------------------------+
| `<` ` )` `==` `!=` `>=` `<=` | Comparisons |
+------------------------------------------------------------------------+-----------------------------------------+
| `in` | When used with the `if` keyword it |
| | checks if a value is within a string, | | | checks if a value is within a string, |
| | list, range, dictionary, or node. When | | | list, range, dictionary, or node. When |
| | used with the `for` keyword it is used| | | used with the `for` keyword it is used |
| | to iterate though the contents of a | | | to iterate though the contents of a |
| | string, list, range, dictionary or node.| | | string, list, range, dictionary or node.|
+------------------------------------------------------------------------+-----------------------------------------+ | `!` `not` | Boolean NOT |
| `!` `not` | Boolean NOT | | `and` `&&` | Boolean AND |
+------------------------------------------------------------------------+-----------------------------------------+ | `or` `||` | Boolean OR |
| `and` `&&` | Boolean AND | | `if x else` | Ternary if/else |
+------------------------------------------------------------------------+-----------------------------------------+ | `as` | Type casting |
| `or` `||` | Boolean OR | | `=` `+=` `-=` `*=` `/=` `%=` `&=` `|=` `&lt;&lt;=` `&gt;&gt;=` | Assignment (lowest priority) |
+------------------------------------------------------------------------+-----------------------------------------+
| `if x else` | Ternary if/else |
+------------------------------------------------------------------------+-----------------------------------------+
| `as` | Type casting |
+------------------------------------------------------------------------+-----------------------------------------+
| `=` `+=` `-=` `*=` `/=` `%=` `&=` `|=` `<<=` `>>=` | Assignment (lowest priority) |
+------------------------------------------------------------------------+-----------------------------------------+
Literals
~~~~~~~~
+--------------------------+----------------------------------------+ ### Literals
| **Literal** | **Type** | | **Literal** | **Type** |
+--------------------------+----------------------------------------+ |--------------------------|----------------------------------------|
| `45` | Base 10 integer | | `45` | Base 10 integer |
+--------------------------+----------------------------------------+ | `0x8f51` | Base 16 (hexadecimal) integer |
| `0x8f51` | Base 16 (hexadecimal) integer | | `0b101010` | Base 2 (binary) integer |
+--------------------------+----------------------------------------+ | `3.14`, `58.1e-10` | Floating-point number (real) |
| `0b101010` | Base 2 (binary) integer | | `"Hello"`, `"Hi"` | Strings |
+--------------------------+----------------------------------------+ | `"""Hello"""` | Multiline string |
| `3.14`, `58.1e-10` | Floating-point number (real) | | `@"Node/Label"` | `NodePath` or StringName |
+--------------------------+----------------------------------------+ | `$NodePath` | Shorthand for `get_node("NodePath")` |
| `"Hello"`, `"Hi"` | Strings |
+--------------------------+----------------------------------------+
| `"""Hello"""` | Multiline string |
+--------------------------+----------------------------------------+
| `@"Node/Label"` | `NodePath` or StringName |
+--------------------------+----------------------------------------+
| `$NodePath` | Shorthand for `get_node("NodePath")` |
+--------------------------+----------------------------------------+
Integers and floats can have their numbers separated with `` to make them more readable.
Integers and floats can have their numbers separated with `_` to make them more readable.
The following ways to write numbers are all valid The following ways to write numbers are all valid
``` ```
12_345_678 # Equal to 12345678. 12_345_678 # Equal to 12345678.
3.141_592_7 # Equal to 3.1415927. 3.141_592_7 # Equal to 3.1415927.
@ -318,8 +243,7 @@ The following ways to write numbers are all valid
0b11_00_11_00 # Equal to 0b11001100. 0b11_00_11_00 # Equal to 0b11001100.
``` ```
Comments ### Comments
~~~~~~~~
Anything from a `#` to the end of the line is ignored and is Anything from a `#` to the end of the line is ignored and is
considered a comment. considered a comment.
@ -331,8 +255,7 @@ considered a comment.
Built-in types ## Built-in types
--------------
Built-in types are stack-allocated. They are passed as values. This means a copy Built-in types are stack-allocated. They are passed as values. This means a copy
is created on each assignment or when passing them as arguments to functions. is created on each assignment or when passing them as arguments to functions.
@ -340,159 +263,126 @@ The only exceptions are `Array`\ s and `Dictionaries`, which are passed by
reference so they are shared. (Pooled arrays such as `PoolByteArray` are still reference so they are shared. (Pooled arrays such as `PoolByteArray` are still
passed as values.) passed as values.)
Basic built-in types ### Basic built-in types
~~~~~~~~~~~~~~~~~~~~
A variable in GDScript can be assigned to several built-in types. A variable in GDScript can be assigned to several built-in types.
null #### null
^^^^
`null` is an empty data type that contains no information and can not `null` is an empty data type that contains no information and can not
be assigned any other value. be assigned any other value.
`bool` #### `bool`
^^^^^^^^^^^^^^^^^^^^^^^^
Short for "boolean", it can only contain `true` or `false`. Short for "boolean", it can only contain `true` or `false`.
`int` #### `int`
^^^^^^^^^^^^^^^^^^^^^^
Short for "integer", it stores whole numbers (positive and negative). Short for "integer", it stores whole numbers (positive and negative).
It is stored as a 64-bit value, equivalent to "int64_t" in C++. It is stored as a 64-bit value, equivalent to "int64_t" in C++.
`float` #### `float`
^^^^^^^^^^^^^^^^^^^^^^^^^^
Stores real numbers, including decimals, using floating-point values. Stores real numbers, including decimals, using floating-point values.
It is stored as a 64-bit value, equivalent to "double" in C++. It is stored as a 64-bit value, equivalent to "double" in C++.
Note: Currently, data structures such as Vector2, Vector3, and Note: Currently, data structures such as Vector2, Vector3, and
PoolRealArray store 32-bit single-precision "float" values. PoolRealArray store 32-bit single-precision "float" values.
`String` #### `String`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A sequence of characters in `Unicode format ( https://en.wikipedia.org/wiki/Unicode )`. A sequence of characters in `Unicode format ( https://en.wikipedia.org/wiki/Unicode )`.
Strings can contain the following escape sequences: Strings can contain the following escape sequences:
+---------------------+---------------------------------+
| **Escape sequence** | **Expands to** | | **Escape sequence** | **Expands to** |
+---------------------+---------------------------------+ |---------------------|---------------------------------|
| `\n` | Newline (line feed) | | `\n` | Newline (line feed) |
+---------------------+---------------------------------+ | `\t` | Horizontal tab character |
| `\t` | Horizontal tab character | | `\r` | Carriage return |
+---------------------+---------------------------------+ | `\a` | Alert (beep/bell) |
| `\r` | Carriage return | | `\b` | Backspace |
+---------------------+---------------------------------+ | `\f` | Formfeed page break |
| `\a` | Alert (beep/bell) | | `\v` | Vertical tab character |
+---------------------+---------------------------------+ | `\"` | Double quote |
| `\b` | Backspace | | `\'` | Single quote |
+---------------------+---------------------------------+ | `\\ ` | Backslash |
| `\f` | Formfeed page break | | `\uXXXX` | Unicode codepoint `XXXX` |
+---------------------+---------------------------------+
| `\v` | Vertical tab character |
+---------------------+---------------------------------+
| `\"` | Double quote |
+---------------------+---------------------------------+
| `\'` | Single quote |
+---------------------+---------------------------------+
| `\\` | Backslash |
+---------------------+---------------------------------+
| `\uXXXX` | Unicode codepoint `XXXX` |
| | (hexadecimal, case-insensitive) | | | (hexadecimal, case-insensitive) |
+---------------------+---------------------------------+
GDScript also supports `doc_gdscript_printf`. GDScript also supports `doc_gdscript_printf`.
Vector built-in types ### Vector built-in types
~~~~~~~~~~~~~~~~~~~~~
`Vector2` #### `Vector2`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2D vector type containing `x` and `y` fields. Can also be 2D vector type containing `x` and `y` fields. Can also be
accessed as an array. accessed as an array.
`Rect2` #### `Rect2`
^^^^^^^^^^^^^^^^^^^^^^^^^^
2D Rectangle type containing two vectors fields: `position` and `size`. 2D Rectangle type containing two vectors fields: `position` and `size`.
Also contains an `end` field which is `position + size`. Also contains an `end` field which is `position + size`.
`Vector3` #### `Vector3`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3D vector type containing `x`, `y` and `z` fields. This can also 3D vector type containing `x`, `y` and `z` fields. This can also
be accessed as an array. be accessed as an array.
`Transform2D` #### `Transform2D`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3×2 matrix used for 2D transforms. 3×2 matrix used for 2D transforms.
`Plane` #### `Plane`
^^^^^^^^^^^^^^^^^^^^^^^^^^
3D Plane type in normalized form that contains a `normal` vector field 3D Plane type in normalized form that contains a `normal` vector field
and a `d` scalar distance. and a `d` scalar distance.
`Quat` #### `Quat`
^^^^^^^^^^^^^^^^^^^^^^^^
Quaternion is a datatype used for representing a 3D rotation. It's Quaternion is a datatype used for representing a 3D rotation. It's
useful for interpolating rotations. useful for interpolating rotations.
`AABB` #### `AABB`
^^^^^^^^^^^^^^^^^^^^^^^^
Axis-aligned bounding box (or 3D box) contains 2 vectors fields: `position` Axis-aligned bounding box (or 3D box) contains 2 vectors fields: `position`
and `size`. Also contains an `end` field which is and `size`. Also contains an `end` field which is
`position + size`. `position + size`.
`Basis` #### `Basis`
^^^^^^^^^^^^^^^^^^^^^^^^^^
3x3 matrix used for 3D rotation and scale. It contains 3 vector fields 3x3 matrix used for 3D rotation and scale. It contains 3 vector fields
(`x`, `y` and `z`) and can also be accessed as an array of 3D (`x`, `y` and `z`) and can also be accessed as an array of 3D
vectors. vectors.
`Transform` #### `Transform`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3D Transform contains a Basis field `basis` and a Vector3 field 3D Transform contains a Basis field `basis` and a Vector3 field
`origin`. `origin`.
Engine built-in types ### Engine built-in types
~~~~~~~~~~~~~~~~~~~~~
`Color` #### `Color`
^^^^^^^^^^^^^^^^^^^^^^^^^^
Color data type contains `r`, `g`, `b`, and `a` fields. It can Color data type contains `r`, `g`, `b`, and `a` fields. It can
also be accessed as `h`, `s`, and `v` for hue/saturation/value. also be accessed as `h`, `s`, and `v` for hue/saturation/value.
`NodePath` #### `NodePath`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Compiled path to a node used mainly in the scene system. It can be Compiled path to a node used mainly in the scene system. It can be
easily assigned to, and from, a String. easily assigned to, and from, a String.
`RID` #### `RID`
^^^^^^^^^^^^^^^^^^^^^^
Resource ID (RID). Servers use generic RIDs to reference opaque data. Resource ID (RID). Servers use generic RIDs to reference opaque data.
`Object` #### `Object`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Base class for anything that is not a built-in type. Base class for anything that is not a built-in type.
Container built-in types ### Container built-in types
~~~~~~~~~~~~~~~~~~~~~~~~
`Array` #### `Array`
^^^^^^^^^^^^^^^^^^^^^^^^^^
Generic sequence of arbitrary object types, including other arrays or dictionaries (see below). Generic sequence of arbitrary object types, including other arrays or dictionaries (see below).
The array can resize dynamically. Arrays are indexed starting from index `0`. The array can resize dynamically. Arrays are indexed starting from index `0`.
@ -524,8 +414,7 @@ arrays. They are therefore only recommended to use for large data sets:
- `PoolVector3Array` objects. - `PoolVector3Array` objects.
- `PoolColorArray` objects. - `PoolColorArray` objects.
`Dictionary` #### `Dictionary`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Associative container which contains values referenced by unique keys. Associative container which contains values referenced by unique keys.
@ -558,6 +447,7 @@ identifier).
To add a key to an existing dictionary, access it like an existing key and To add a key to an existing dictionary, access it like an existing key and
assign to it assign to it
``` ```
var d = {} # Create an empty Dictionary. var d = {} # Create an empty Dictionary.
d.waiting = 14 # Add String "waiting" as a key and assign the value 14 to it. d.waiting = 14 # Add String "waiting" as a key and assign the value 14 to it.
@ -580,11 +470,9 @@ Note:
this, use the `Object.get()` and this, use the `Object.get()` and
`Object.set()` methods instead. `Object.set()` methods instead.
Data ## Data
----
Variables ### Variables
~~~~~~~~~
Variables can exist as class members or local to functions. They are Variables can exist as class members or local to functions. They are
created with the `var` keyword and may, optionally, be assigned a created with the `var` keyword and may, optionally, be assigned a
@ -613,6 +501,7 @@ after the variable name, followed by the type.
If the variable is initialized within the declaration, the type can be inferred, so If the variable is initialized within the declaration, the type can be inferred, so
it's possible to omit the type name it's possible to omit the type name
``` ```
var my_vector2 := Vector2() # 'my_vector2' is of type 'Vector2'. var my_vector2 := Vector2() # 'my_vector2' is of type 'Vector2'.
var my_node := Sprite.new() # 'my_node' is of type 'Sprite'. var my_node := Sprite.new() # 'my_node' is of type 'Sprite'.
@ -629,8 +518,7 @@ Valid types are:
- Other classes in the same script, respecting scope (`InnerClass.NestedClass` if you declared `class NestedClass` inside the `class InnerClass` in the same scope). - Other classes in the same script, respecting scope (`InnerClass.NestedClass` if you declared `class NestedClass` inside the `class InnerClass` in the same scope).
- Script classes declared with the `name` keyword. - Script classes declared with the `name` keyword.
Casting #### Casting
^^^^^^^
Values assigned to typed variables must have a compatible type. If it's needed to Values assigned to typed variables must have a compatible type. If it's needed to
coerce a value to be of a certain type, in particular for object types, you can coerce a value to be of a certain type, in particular for object types, you can
@ -665,6 +553,7 @@ engine will raise an error.
Casting is also useful to have better type-safe variables when interacting with Casting is also useful to have better type-safe variables when interacting with
the scene tree the scene tree
``` ```
# Will infer the variable to be of type Sprite. # Will infer the variable to be of type Sprite.
var my_sprite := $Character as Sprite var my_sprite := $Character as Sprite
@ -673,8 +562,7 @@ the scene tree
($AnimPlayer as AnimationPlayer).play("walk") ($AnimPlayer as AnimationPlayer).play("walk")
``` ```
Constants ### Constants
~~~~~~~~~
Constants are values you cannot change when the game is running. Constants are values you cannot change when the game is running.
Their value must be known at compile-time. Using the Their value must be known at compile-time. Using the
@ -697,6 +585,7 @@ We recommend using constants whenever a value is not meant to change.
Although the type of constants is inferred from the assigned value, it's also Although the type of constants is inferred from the assigned value, it's also
possible to add explicit type specification possible to add explicit type specification
``` ```
const A: int = 5 const A: int = 5
const B: Vector2 = Vector2() const B: Vector2 = Vector2()
@ -711,8 +600,7 @@ Note:
This means that if you declare a constant array or dictionary, it can still This means that if you declare a constant array or dictionary, it can still
be modified afterwards. They can't be reassigned with another value though. be modified afterwards. They can't be reassigned with another value though.
Enums #### Enums
^^^^^
Enums are basically a shorthand for constants, and are pretty useful if you Enums are basically a shorthand for constants, and are pretty useful if you
want to assign consecutive integers to some constant. want to assign consecutive integers to some constant.
@ -740,10 +628,9 @@ dictionary of that name.
``` ```
Functions ### Functions
~~~~~~~~~
Functions always belong to a `class <Classes_ )`. The scope priority for Functions always belong to a `class`. The scope priority for
variable look-up is: local → class member → global. The `self` variable is variable look-up is: local → class member → global. The `self` variable is
always available and is provided as an option for accessing class members, but always available and is provided as an option for accessing class members, but
is not always required (and should *not* be sent as the function's first is not always required (and should *not* be sent as the function's first
@ -761,17 +648,20 @@ A function can `return` at any point. The default return value is `null`.
Functions can also have type specification for the arguments and for the return Functions can also have type specification for the arguments and for the return
value. Types for arguments can be added in a similar way to variables value. Types for arguments can be added in a similar way to variables
``` ```
func my_function(a: int, b: String): func my_function(a: int, b: String):
pass pass
If a function argument has a default value, it's possible to infer the type If a function argument has a default value, it's possible to infer the type
``` ```
func my_function(int_arg := 42, String_arg := "string"): func my_function(int_arg := 42, String_arg := "string"):
pass pass
The return type of the function can be specified after the arguments list using The return type of the function can be specified after the arguments list using
the arrow token (`- )`) the arrow token (`- )`)
``` ```
func my_int_function() -> int: func my_int_function() -> int:
return 0 return 0
@ -788,6 +678,7 @@ return early with the `return` keyword, but they can't return any value.
``` ```
Note: Note:
Non-void functions must **always** return a value, so if your code has Non-void functions must **always** return a value, so if your code has
branching statements (such as an `if`/`else` construct), all the branching statements (such as an `if`/`else` construct), all the
possible paths must have a return. E.g., if you have a `return` possible paths must have a return. E.g., if you have a `return`
@ -795,8 +686,7 @@ Note:
error because if the block is not executed, the function won't have a error because if the block is not executed, the function won't have a
valid value to return. valid value to return.
Referencing functions #### Referencing functions
^^^^^^^^^^^^^^^^^^^^^
Contrary to Python, functions are *not* first-class objects in GDScript. This Contrary to Python, functions are *not* first-class objects in GDScript. This
means they cannot be stored in variables, passed as an argument to another means they cannot be stored in variables, passed as an argument to another
@ -805,6 +695,7 @@ function or be returned from other functions. This is for performance reasons.
To reference a function by name at run-time, (e.g. to store it in a variable, or To reference a function by name at run-time, (e.g. to store it in a variable, or
pass it to another function as an argument) one must use the `call` or pass it to another function as an argument) one must use the `call` or
`funcref` helpers `funcref` helpers
``` ```
# Call a function by name in one step. # Call a function by name in one step.
my_node.call("my_function", args) my_node.call("my_function", args)
@ -816,27 +707,25 @@ pass it to another function as an argument) one must use the `call` or
``` ```
Static functions #### Static functions
^^^^^^^^^^^^^^^^
A function can be declared static. When a function is static, it has no A function can be declared static. When a function is static, it has no
access to the instance member variables or `self`. This is mainly access to the instance member variables or `self`. This is mainly
useful to make libraries of helper functions useful to make libraries of helper functions
``` ```
static func sum2(a, b): static func sum2(a, b):
return a + b return a + b
``` ```
Statements and control flow ### Statements and control flow
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Statements are standard and can be assignments, function calls, control Statements are standard and can be assignments, function calls, control
flow structures, etc (see below). `;` as a statement separator is flow structures, etc (see below). `;` as a statement separator is
entirely optional. entirely optional.
if/else/elif #### if/else/elif
^^^^^^^^^^^^
Simple conditions are created by using the `if`/`else`/`elif` syntax. Simple conditions are created by using the `if`/`else`/`elif` syntax.
Parenthesis around conditions are allowed, but not required. Given the Parenthesis around conditions are allowed, but not required. Given the
@ -903,8 +792,7 @@ use an `if` statement combined with the `in` operator to accomplish this
if "varName" in get_parent(): print("varName is defined in parent!") if "varName" in get_parent(): print("varName is defined in parent!")
``` ```
while #### while
^^^^^
Simple loops are created by using `while` syntax. Loops can be broken Simple loops are created by using `while` syntax. Loops can be broken
using `break` or continued using `continue`: using `break` or continued using `continue`:
@ -915,8 +803,7 @@ using `break` or continued using `continue`:
statement(s) statement(s)
``` ```
for #### for
^^^
To iterate through a range, such as an array or table, a *for* loop is To iterate through a range, such as an array or table, a *for* loop is
used. When iterating over an array, the current array element is stored in used. When iterating over an array, the current array element is stored in
@ -951,8 +838,7 @@ in the loop variable.
statement # Similar to range(ceil(2.2)) statement # Similar to range(ceil(2.2))
``` ```
match #### match
^^^^^
A `match` statement is used to branch execution of a program. A `match` statement is used to branch execution of a program.
It's the equivalent of the `switch` statement found in many other languages, but offers some additional features. It's the equivalent of the `switch` statement found in many other languages, but offers some additional features.
@ -1102,8 +988,7 @@ There are 6 pattern types:
print("Yep, you've taken damage") print("Yep, you've taken damage")
``` ```
Classes ### Classes
~~~~~~~
By default, all script files are unnamed classes. In this case, you can only By default, all script files are unnamed classes. In this case, you can only
reference them using the file's path, using either a relative or an absolute reference them using the file's path, using either a relative or an absolute
@ -1121,8 +1006,7 @@ path. For example, if you name a script file `character.gd`
``` ```
Registering named classes #### Registering named classes
~~~~~~~~~~~~~~~~~~~~~~~~~
You can give your class a name to register it as a new type in Pandemonium's You can give your class a name to register it as a new type in Pandemonium's
editor. For that, you use the `name` keyword. You can optionally add editor. For that, you use the `name` keyword. You can optionally add
@ -1176,8 +1060,7 @@ Note:
safety, since scripts can be initialized in separate threads without the user safety, since scripts can be initialized in separate threads without the user
knowing. knowing.
Inheritance #### Inheritance
^^^^^^^^^^^
A class (stored as a file) can inherit from: A class (stored as a file) can inherit from:
@ -1188,6 +1071,7 @@ A class (stored as a file) can inherit from:
Multiple inheritance is not allowed. Multiple inheritance is not allowed.
Inheritance uses the `extends` keyword Inheritance uses the `extends` keyword
``` ```
# Inherit/extend a globally available class. # Inherit/extend a globally available class.
extends SomeClass extends SomeClass
@ -1235,8 +1119,7 @@ Note:
There is no need to call them explicitly when overloading them. There is no need to call them explicitly when overloading them.
Class constructor #### Class constructor
^^^^^^^^^^^^^^^^^
The class constructor, called on class instantiation, is named `init`. As The class constructor, called on class instantiation, is named `init`. As
mentioned earlier, the constructors of parent classes are called automatically mentioned earlier, the constructors of parent classes are called automatically
@ -1293,8 +1176,7 @@ There are a few things to keep in mind here:
pass pass
``` ```
Inner classes #### Inner classes
^^^^^^^^^^^^^
A class file can contain inner classes. Inner classes are defined using the A class file can contain inner classes. Inner classes are defined using the
`class` keyword. They are instanced using the `ClassName.new()` `class` keyword. They are instanced using the `ClassName.new()`
@ -1321,8 +1203,7 @@ function.
``` ```
Classes as resources #### Classes as resources
^^^^^^^^^^^^^^^^^^^^
Classes stored as files are treated as `resources`. They Classes stored as files are treated as `resources`. They
must be loaded from disk to access them in other classes. This is done using must be loaded from disk to access them in other classes. This is done using
@ -1341,16 +1222,14 @@ class resource is done by calling the `new` function on the class object
a.some_function() a.some_function()
``` ```
Exports ### Exports
~~~~~~~
Note: Note:
Documentation about exports has been moved to `doc_gdscript_exports`. Documentation about exports has been moved to `doc_gdscript_exports`.
Setters/getters ### Setters/getters
~~~~~~~~~~~~~~~
It is often useful to know when a class' member variable changes for It is often useful to know when a class' member variable changes for
whatever reason. It may also be desired to encapsulate its access in some way. whatever reason. It may also be desired to encapsulate its access in some way.
@ -1368,6 +1247,7 @@ Whenever the value of `variable` is modified by an *external* source
will be called. This happens *before* the value is changed. The *setter* must decide what to do will be called. This happens *before* the value is changed. The *setter* must decide what to do
with the new value. Vice versa, when `variable` is accessed, the *getter* function with the new value. Vice versa, when `variable` is accessed, the *getter* function
(`getterfunc` above) must `return` the desired value. Below is an example (`getterfunc` above) must `return` the desired value. Below is an example
``` ```
var my_var setget my_var_set, my_var_get var my_var setget my_var_set, my_var_get
@ -1381,6 +1261,7 @@ with the new value. Vice versa, when `variable` is accessed, the *getter* functi
``` ```
Either of the *setter* or *getter* functions can be omitted Either of the *setter* or *getter* functions can be omitted
``` ```
# Only a setter. # Only a setter.
var my_var = 5 setget my_var_set var my_var = 5 setget my_var_set
@ -1408,8 +1289,7 @@ illustration of this:
``` ```
Tool mode ### Tool mode
~~~~~~~~~
By default, scripts don't run inside the editor and only the exported By default, scripts don't run inside the editor and only the exported
properties can be changed. In some cases, it is desired that they do run properties can be changed. In some cases, it is desired that they do run
@ -1436,8 +1316,7 @@ Warning:
Memory management ### Memory management
~~~~~~~~~~~~~~~~~
If a class inherits from `Reference`, then instances will be If a class inherits from `Reference`, then instances will be
freed when no longer in use. No garbage collector exists, just freed when no longer in use. No garbage collector exists, just
@ -1468,8 +1347,7 @@ freed.
Signals ### Signals
~~~~~~~
Signals are a tool to emit messages from an object that other objects can react Signals are a tool to emit messages from an object that other objects can react
to. To create custom signals for a class, use the `signal` keyword. to. To create custom signals for a class, use the `signal` keyword.
@ -1499,6 +1377,7 @@ signals of nodes like `Button` or `RigidBody`.
In the example below, we connect the `health_depleted` signal from a In the example below, we connect the `health_depleted` signal from a
`Character` node to a `Game` node. When the `Character` node emits the `Character` node to a `Game` node. When the `Character` node emits the
signal, the game node's `on_Character_health_depleted` is called signal, the game node's `on_Character_health_depleted` is called
``` ```
# Game.gd # Game.gd
@ -1521,6 +1400,7 @@ In our `Character.gd` script, we define a `health_changed` signal and emit
it with `Object.emit_signal()`, and from it with `Object.emit_signal()`, and from
a `Game` node higher up our scene tree, we connect it to the `Lifebar` using a `Game` node higher up our scene tree, we connect it to the `Lifebar` using
the `Object.connect()` method the `Object.connect()` method
``` ```
# Character.gd # Character.gd
@ -1584,6 +1464,7 @@ the `Character` node.
You can write optional argument names in parentheses after the signal's You can write optional argument names in parentheses after the signal's
definition definition
``` ```
# Defining a signal that forwards two arguments. # Defining a signal that forwards two arguments.
signal health_changed(old_value, new_value) signal health_changed(old_value, new_value)
@ -1609,6 +1490,7 @@ taken by each character on the screen, like `Player1 took 22 damage.`. The
`health_changed` signal doesn't give us the name of the character that took `health_changed` signal doesn't give us the name of the character that took
damage. So when we connect the signal to the in-game console, we can add the damage. So when we connect the signal to the in-game console, we can add the
character's name in the binds array argument character's name in the binds array argument
``` ```
# Game.gd # Game.gd
@ -1620,6 +1502,7 @@ character's name in the binds array argument
``` ```
Our `BattleLog` node receives each element in the binds array as an extra argument Our `BattleLog` node receives each element in the binds array as an extra argument
``` ```
# BattleLog.gd # BattleLog.gd
@ -1632,8 +1515,7 @@ Our `BattleLog` node receives each element in the binds array as an extra argume
``` ```
Coroutines with yield ### Coroutines with yield
~~~~~~~~~~~~~~~~~~~~~
GDScript offers support for `coroutines ( https://en.wikipedia.org/wiki/Coroutine )` GDScript offers support for `coroutines ( https://en.wikipedia.org/wiki/Coroutine )`
via the `yield( @GDScript_method_yield )` built-in function. Calling `yield()` will via the `yield( @GDScript_method_yield )` built-in function. Calling `yield()` will
@ -1642,6 +1524,7 @@ state of the same function as the return value. Calling `resume()` on
this resulting object will continue execution and return whatever the this resulting object will continue execution and return whatever the
function returns. Once resumed, the state object becomes invalid. Here is function returns. Once resumed, the state object becomes invalid. Here is
an example an example
``` ```
func my_func(): func my_func():
print("Hello") print("Hello")
@ -1658,6 +1541,7 @@ an example
``` ```
Will print Will print
``` ```
Hello Hello
my dear my dear
@ -1666,6 +1550,7 @@ Will print
It is also possible to pass values between `yield()` and `resume()`, It is also possible to pass values between `yield()` and `resume()`,
for example for example
``` ```
func my_func(): func my_func():
print("Hello") print("Hello")
@ -1681,6 +1566,7 @@ for example
``` ```
Will print Will print
``` ```
Hello Hello
world world
@ -1688,6 +1574,7 @@ Will print
``` ```
Remember to save the new function state, when using multiple `yield`\s Remember to save the new function state, when using multiple `yield`\s
``` ```
func co_func(): func co_func():
for i in range(1, 5): for i in range(1, 5):
@ -1702,12 +1589,12 @@ Remember to save the new function state, when using multiple `yield`\s
``` ```
Coroutines & signals #### Coroutines & signals
^^^^^^^^^^^^^^^^^^^^
The real strength of using `yield` is when combined with signals. The real strength of using `yield` is when combined with signals.
`yield` can accept two arguments, an object and a signal. When the `yield` can accept two arguments, an object and a signal. When the
signal is received, execution will recommence. Here are some examples signal is received, execution will recommence. Here are some examples
``` ```
# Resume execution the next frame. # Resume execution the next frame.
yield(get_tree(), "idle_frame") yield(get_tree(), "idle_frame")
@ -1721,6 +1608,7 @@ signal is received, execution will recommence. Here are some examples
Coroutines themselves use the `completed` signal when they transition Coroutines themselves use the `completed` signal when they transition
into an invalid state, for example into an invalid state, for example
``` ```
func my_func(): func my_func():
yield(button_func(), "completed") yield(button_func(), "completed")
@ -1744,6 +1632,7 @@ You can also get the signal's argument once it's emitted by an object:
If there is more than one argument, `yield` returns an array containing If there is more than one argument, `yield` returns an array containing
the arguments the arguments
``` ```
signal done(input, processed) signal done(input, processed)
@ -1791,8 +1680,7 @@ when the function didn't yield anymore.
`onready` keyword ### `onready` keyword
~~~~~~~~~~~~~~~~~
When using nodes, it's common to desire to keep references to parts When using nodes, it's common to desire to keep references to parts
of the scene in a variable. As scenes are only warranted to be of the scene in a variable. As scenes are only warranted to be
@ -1812,12 +1700,12 @@ This can get a little cumbersome, especially when nodes and external
references pile up. For this, GDScript has the `onready` keyword, that references pile up. For this, GDScript has the `onready` keyword, that
defers initialization of a member variable until `ready()` is called. It defers initialization of a member variable until `ready()` is called. It
can replace the above code with a single line can replace the above code with a single line
``` ```
onready var my_label = get_node("MyLabel") onready var my_label = get_node("MyLabel")
``` ```
Assert keyword ### Assert keyword
~~~~~~~~~~~~~~
The `assert` keyword can be used to check conditions in debug builds. These The `assert` keyword can be used to check conditions in debug builds. These
assertions are ignored in non-debug builds. This means that the expression assertions are ignored in non-debug builds. This means that the expression

View File

@ -1,10 +1,8 @@
GDScript: An introduction to dynamic languages # GDScript: An introduction to dynamic languages
==============================================
About ## About
-----
This tutorial aims to be a quick reference for how to use GDScript more This tutorial aims to be a quick reference for how to use GDScript more
efficiently. It focuses on common cases specific to the language, but efficiently. It focuses on common cases specific to the language, but
@ -13,11 +11,9 @@ also covers a lot of information on dynamically typed languages.
It's meant to be especially useful for programmers with little or no previous It's meant to be especially useful for programmers with little or no previous
experience with dynamically typed languages. experience with dynamically typed languages.
Dynamic nature ## Dynamic nature
--------------
Pros & cons of dynamic typing ### Pros & cons of dynamic typing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
GDScript is a Dynamically Typed language. As such, its main advantages GDScript is a Dynamically Typed language. As such, its main advantages
are that: are that:
@ -48,8 +44,7 @@ possibility of using C++ is present too. This allows you to still create most of
game in GDScript and add small bits of C++ in the areas that need game in GDScript and add small bits of C++ in the areas that need
a performance boost. a performance boost.
Variables & assignment ### Variables & assignment
~~~~~~~~~~~~~~~~~~~~~~
All variables in a dynamically typed language are "variant"-like. This All variables in a dynamically typed language are "variant"-like. This
means that their type is not fixed, and is only modified through means that their type is not fixed, and is only modified through
@ -71,8 +66,7 @@ Dynamic:
a = "Hi!" # Valid, 'a' changed to a string. a = "Hi!" # Valid, 'a' changed to a string.
``` ```
As function arguments: ### As function arguments:
~~~~~~~~~~~~~~~~~~~~~~
Functions are of dynamic nature too, which means they can be called with Functions are of dynamic nature too, which means they can be called with
different arguments, for example: different arguments, for example:
@ -103,8 +97,7 @@ Dynamic:
print_value("Hello") # Valid. print_value("Hello") # Valid.
``` ```
Pointers & referencing: ### Pointers & referencing:
~~~~~~~~~~~~~~~~~~~~~~~
In static languages, such as C or C++ (and to some extent Java and C#), In static languages, such as C or C++ (and to some extent Java and C#),
there is a distinction between a variable and a pointer/reference to a there is a distinction between a variable and a pointer/reference to a
@ -172,7 +165,6 @@ if inheriting manually from `Object`.
Note: Note:
A value is **passed by value** when it is copied every time it's specified A value is **passed by value** when it is copied every time it's specified
as a function parameter. One consequence of this is that the function cannot as a function parameter. One consequence of this is that the function cannot
modify the parameter in a way that is visible from outside the function: modify the parameter in a way that is visible from outside the function:
@ -222,8 +214,7 @@ Note:
means that modifying them will *always* return a copy of the original value, means that modifying them will *always* return a copy of the original value,
rather than modifying the value in-place. rather than modifying the value in-place.
Arrays ## Arrays
------
Arrays in dynamically typed languages can contain many different mixed Arrays in dynamically typed languages can contain many different mixed
datatypes inside and are always dynamic (can be resized at any time). datatypes inside and are always dynamic (can be resized at any time).
@ -279,8 +270,7 @@ Or unordered sets:
print("We have a winner!") print("We have a winner!")
``` ```
Dictionaries ## Dictionaries
------------
Dictionaries are a powerful tool in dynamically typed languages. Dictionaries are a powerful tool in dynamically typed languages.
Most programmers that come from statically typed languages (such as C++ Most programmers that come from statically typed languages (such as C++
@ -367,8 +357,7 @@ states and quick structs:
d.mother = "Caroline" # This would work too to create a new key. d.mother = "Caroline" # This would work too to create a new key.
``` ```
For & while ## For & while
-----------
Iterating in some statically typed languages can be quite complex: Iterating in some statically typed languages can be quite complex:
@ -456,8 +445,7 @@ Becomes:
pass pass
``` ```
While ## While
-----
while() loops are the same everywhere: while() loops are the same everywhere:
@ -469,8 +457,8 @@ while() loops are the same everywhere:
i += 1 i += 1
``` ```
Custom iterators ## Custom iterators
----------------
You can create custom iterators in case the default ones don't quite meet your You can create custom iterators in case the default ones don't quite meet your
needs by overriding the Variant class's `iter_init`, `iter_next`, and `iter_get` needs by overriding the Variant class's `iter_init`, `iter_next`, and `iter_get`
functions in your script. An example implementation of a forward iterator follows: functions in your script. An example implementation of a forward iterator follows:
@ -514,8 +502,7 @@ And it can be used like any other iterator:
Make sure to reset the state of the iterator in `iter_init`, otherwise nested Make sure to reset the state of the iterator in `iter_init`, otherwise nested
for-loops that use custom iterators will not work as expected. for-loops that use custom iterators will not work as expected.
Duck typing ## Duck typing
-----------
One of the most difficult concepts to grasp when moving from a One of the most difficult concepts to grasp when moving from a
statically typed language to a dynamic one is duck typing. Duck typing statically typed language to a dynamic one is duck typing. Duck typing

View File

@ -1,10 +1,8 @@
GDScript exports # GDScript exports
================
Introduction to exports ## Introduction to exports
-----------------------
In Pandemonium, class members can be exported. This means their value gets saved along In Pandemonium, class members can be exported. This means their value gets saved along
with the resource (such as the `scene`) they're with the resource (such as the `scene`) they're
@ -28,15 +26,13 @@ special export syntax is provided.
Note: Note:
Exporting properties can also be done in other languages such as C#. Exporting properties can also be done in other languages such as C#.
The syntax varies depending on the language. The syntax varies depending on the language.
.. ..
See ref `doc_c_sharp_exports` for information on C# exports. See ref `doc_c_sharp_exports` for information on C# exports.
Examples ## Examples
--------
``` ```
# If the exported value assigns a constant or constant expression, # If the exported value assigns a constant or constant expression,
@ -143,8 +139,7 @@ It must be noted that even if the script is not being run while in the
editor, the exported properties are still editable. This can be used editor, the exported properties are still editable. This can be used
in conjunction with a `script in "tool" mode ( doc_gdscript_tool_mode )`. in conjunction with a `script in "tool" mode ( doc_gdscript_tool_mode )`.
Exporting bit flags ## Exporting bit flags
-------------------
Integers used as bit flags can store multiple `true`/`false` (boolean) Integers used as bit flags can store multiple `true`/`false` (boolean)
values in one property. By using the export hint `int, FLAGS, ...`, they values in one property. By using the export hint `int, FLAGS, ...`, they
@ -172,8 +167,7 @@ Export hints are also provided for the physics and render layers defined in the
Using bit flags requires some understanding of bitwise operations. Using bit flags requires some understanding of bitwise operations.
If in doubt, use boolean variables instead. If in doubt, use boolean variables instead.
Exporting arrays ## Exporting arrays
----------------
Exported arrays can have initializers, but they must be constant expressions. Exported arrays can have initializers, but they must be constant expressions.
@ -214,8 +208,7 @@ from the FileSystem dock at once.
var c = [a, 2, 3] var c = [a, 2, 3]
``` ```
Setting exported variables from a tool script ## Setting exported variables from a tool script
---------------------------------------------
When changing an exported variable's value from a script in When changing an exported variable's value from a script in
`doc_gdscript_tool_mode`, the value in the inspector won't be updated `doc_gdscript_tool_mode`, the value in the inspector won't be updated
@ -223,8 +216,7 @@ automatically. To update it, call
`property_list_changed_notify()` `property_list_changed_notify()`
after setting the exported variable's value. after setting the exported variable's value.
Advanced exports ## Advanced exports
----------------
Not every type of export can be provided on the level of the language itself to Not every type of export can be provided on the level of the language itself to
avoid unnecessary design complexity. The following describes some more or less avoid unnecessary design complexity. The following describes some more or less
@ -232,9 +224,7 @@ common exporting features which can be implemented with a low-level API.
Before reading further, you should get familiar with the way properties are Before reading further, you should get familiar with the way properties are
handled and how they can be customized with handled and how they can be customized with
`set()`, `set()`, `get()`, and `get_property_list()` methods as
`get()`, and
`get_property_list()` methods as
described in `doc_accessing_data_or_logic_from_object`. described in `doc_accessing_data_or_logic_from_object`.
See also: See also:
@ -245,8 +235,7 @@ Warning:
The script must operate in the `tool` mode so the above methods The script must operate in the `tool` mode so the above methods
can work from within the editor. can work from within the editor.
Properties ### Properties
~~~~~~~~~~
To understand how to better use the sections below, you should understand To understand how to better use the sections below, you should understand
how to make properties with advanced exports. how to make properties with advanced exports.
@ -271,19 +260,18 @@ how to make properties with advanced exports.
* `type` is the type of the property from `Variant.Type`. * `type` is the type of the property from `Variant.Type`.
Note: Note:
The `float` type is called a real (`TYPE_REAL`) in the `Variant.Type` enum. The `float` type is called a real (`TYPE_REAL`) in the `Variant.Type` enum.
Attaching variables to properties ### Attaching variables to properties
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To attach variables to properties (allowing the value of the property to be used To attach variables to properties (allowing the value of the property to be used
in scripts), you need to create a variable with the exact same name as the in scripts), you need to create a variable with the exact same name as the
property or else you may need to override the property or else you may need to override the
`set()` and `set()` and `get()` methods. Attaching
`get()` methods. Attaching
a variable to to a property also gives you the ability to give it a default state. a variable to to a property also gives you the ability to give it a default state.
```
```
# This variable is determined by the function below. # This variable is determined by the function below.
# This variable acts just like a regular gdscript export. # This variable acts just like a regular gdscript export.
var my_property = 5 var my_property = 5
@ -298,8 +286,7 @@ a variable to to a property also gives you the ability to give it a default stat
return properties return properties
``` ```
Adding default values for properties ### Adding default values for properties
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To define default values for advanced exports, you need to override the `property_can_revert()` and `property_get_revert()` methods. To define default values for advanced exports, you need to override the `property_can_revert()` and `property_get_revert()` methods.
@ -326,12 +313,12 @@ To define default values for advanced exports, you need to override the `propert
return 5 return 5
``` ```
Adding script categories ### Adding script categories
~~~~~~~~~~~~~~~~~~~~~~~~
For better visual distinguishing of properties, a special script category can be For better visual distinguishing of properties, a special script category can be
embedded into the inspector to act as a separator. `Script Variables` is one embedded into the inspector to act as a separator. `Script Variables` is one
example of a built-in category. example of a built-in category.
``` ```
func _get_property_list(): func _get_property_list():
var properties = [] var properties = []
@ -358,10 +345,10 @@ example of a built-in category.
script category specifically, so the type `TYPE_NIL` can be ignored as it script category specifically, so the type `TYPE_NIL` can be ignored as it
won't be actually used for the scripting logic, yet it must be defined anyway. won't be actually used for the scripting logic, yet it must be defined anyway.
Grouping properties ### Grouping properties
~~~~~~~~~~~~~~~~~~~
A list of properties with similar names can be grouped. A list of properties with similar names can be grouped.
``` ```
func _get_property_list(): func _get_property_list():
var properties = [] var properties = []

View File

@ -1,7 +1,6 @@
GDScript style guide # GDScript style guide
====================
This style guide lists conventions to write elegant GDScript. The goal is to This style guide lists conventions to write elegant GDScript. The goal is to
encourage writing clean, readable code and promote consistency across projects, encourage writing clean, readable code and promote consistency across projects,
@ -25,6 +24,7 @@ Note:
Here is a complete class example based on these guidelines: Here is a complete class example based on these guidelines:
``` ```
class_name StateMachine class_name StateMachine
extends Node extends Node
@ -89,21 +89,16 @@ Here is a complete class example based on these guidelines:
emit_signal("state_changed") emit_signal("state_changed")
``` ```
.. _formatting: ## Formatting
Formatting ### Encoding and special characters
----------
Encoding and special characters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Use line feed (**LF**) characters to break lines, not CRLF or CR. *(editor default)* * Use line feed (**LF**) characters to break lines, not CRLF or CR. *(editor default)*
* Use one line feed character at the end of each file. *(editor default)* * Use one line feed character at the end of each file. *(editor default)*
* Use **UTF-8** encoding without a `byte order mark ( https://en.wikipedia.org/wiki/Byte_order_mark )`. *(editor default)* * Use **UTF-8** encoding without a `byte order mark ( https://en.wikipedia.org/wiki/Byte_order_mark )`. *(editor default)*
* Use **Tabs** instead of spaces for indentation. *(editor default)* * Use **Tabs** instead of spaces for indentation. *(editor default)*
Indentation ### Indentation
~~~~~~~~~~~
Each indent level should be one greater than the block containing it. Each indent level should be one greater than the block containing it.
@ -192,8 +187,7 @@ indentation level to distinguish continuation lines:
} }
``` ```
Trailing comma ### Trailing comma
~~~~~~~~~~~~~~
Use a trailing comma on the last line in arrays, dictionaries, and enums. This Use a trailing comma on the last line in arrays, dictionaries, and enums. This
results in easier refactoring and better diffs in version control as the last results in easier refactoring and better diffs in version control as the last
@ -235,8 +229,7 @@ Trailing commas are unnecessary in single-line lists, so don't add them in this
enum Tiles {TILE_BRICK, TILE_FLOOR, TILE_SPIKE, TILE_TELEPORT,} enum Tiles {TILE_BRICK, TILE_FLOOR, TILE_SPIKE, TILE_TELEPORT,}
``` ```
Blank lines ### Blank lines
~~~~~~~~~~~
Surround functions and class definitions with two blank lines: Surround functions and class definitions with two blank lines:
@ -259,8 +252,7 @@ Note:
We use a single line between classes and function definitions in the class reference and We use a single line between classes and function definitions in the class reference and
in short code snippets in this documentation. in short code snippets in this documentation.
Line length ### Line length
~~~~~~~~~~~
Keep individual lines of code under 100 characters. Keep individual lines of code under 100 characters.
@ -268,8 +260,7 @@ If you can, try to keep lines under 80 characters. This helps to read the code
on small displays and with two scripts opened side-by-side in an external text on small displays and with two scripts opened side-by-side in an external text
editor. For example, when looking at a differential revision. editor. For example, when looking at a differential revision.
One statement per line ### One statement per line
~~~~~~~~~~~~~~~~~~~~~~
Never combine multiple statements on a single line. No, C programmers, Never combine multiple statements on a single line. No, C programmers,
not even with a single line conditional statement. not even with a single line conditional statement.
@ -298,8 +289,7 @@ The only exception to that rule is the ternary operator:
next_state = "fall" if not is_on_floor() else "idle" next_state = "fall" if not is_on_floor() else "idle"
``` ```
Format multiline statements for readability ### Format multiline statements for readability
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When you have particularly long `if` statements or nested ternary expressions, When you have particularly long `if` statements or nested ternary expressions,
wrapping them over multiple lines improves readability. Since continuation lines wrapping them over multiple lines improves readability. Since continuation lines
@ -345,8 +335,7 @@ end of the previous line.
pass pass
``` ```
Avoid unnecessary parentheses ### Avoid unnecessary parentheses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Avoid parentheses in expressions and conditional statements. Unless Avoid parentheses in expressions and conditional statements. Unless
necessary for order of operations or wrapping over multiple lines, necessary for order of operations or wrapping over multiple lines,
@ -366,8 +355,7 @@ they only reduce readability.
queue_free() queue_free()
``` ```
Boolean operators ### Boolean operators
~~~~~~~~~~~~~~~~~
Prefer the plain English versions of boolean operators, as they are the most accessible: Prefer the plain English versions of boolean operators, as they are the most accessible:
@ -391,8 +379,7 @@ This can make long expressions easier to read.
print("condition is true") print("condition is true")
``` ```
Comment spacing ### Comment spacing
~~~~~~~~~~~~~~~
Regular comments should start with a space, but not code that you comment out. Regular comments should start with a space, but not code that you comment out.
This helps differentiate text comments from disabled code. This helps differentiate text comments from disabled code.
@ -418,8 +405,7 @@ Note:
:kbd:`Ctrl + K`. This feature adds a single # sign at the start :kbd:`Ctrl + K`. This feature adds a single # sign at the start
of the selected lines. of the selected lines.
Whitespace ### Whitespace
~~~~~~~~~~
Always use one space around operators and after commas. Also, avoid extra spaces Always use one space around operators and after commas. Also, avoid extra spaces
in dictionary references and function calls. in dictionary references and function calls.
@ -452,8 +438,7 @@ Don't use spaces to align expressions vertically:
velocity = 500 velocity = 500
``` ```
Quotes ### Quotes
~~~~~~
Use double quotes unless single quotes make it possible to escape fewer Use double quotes unless single quotes make it possible to escape fewer
characters in a given string. See the examples below: characters in a given string. See the examples below:
@ -472,8 +457,7 @@ characters in a given string. See the examples below:
print("'hello' \"world\"") print("'hello' \"world\"")
``` ```
Numbers ### Numbers
~~~~~~~
Don't omit the leading or trailing zero in floating-point numbers. Otherwise, Don't omit the leading or trailing zero in floating-point numbers. Otherwise,
this makes them less readable and harder to distinguish from integers at a this makes them less readable and harder to distinguish from integers at a
@ -527,15 +511,13 @@ readable.
.. _naming_conventions: .. _naming_conventions:
Naming conventions ## Naming conventions
------------------
These naming conventions follow the Pandemonium Engine style. Breaking these will make These naming conventions follow the Pandemonium Engine style. Breaking these will make
your code clash with the built-in naming conventions, leading to inconsistent your code clash with the built-in naming conventions, leading to inconsistent
code. code.
File names ### File names
~~~~~~~~~~
Use snake_case for file names. For named classes, convert the PascalCase class Use snake_case for file names. For named classes, convert the PascalCase class
name to snake_case: name to snake_case:
@ -555,8 +537,7 @@ This is consistent with how C++ files are named in Pandemonium's source code. Th
also avoids case sensitivity issues that can crop up when exporting a project also avoids case sensitivity issues that can crop up when exporting a project
from Windows to other platforms. from Windows to other platforms.
Classes and nodes ### Classes and nodes
~~~~~~~~~~~~~~~~~
Use PascalCase for class and node names: Use PascalCase for class and node names:
@ -570,8 +551,7 @@ Also use PascalCase when loading a class into a constant or a variable:
const Weapon = preload("res://weapon.gd") const Weapon = preload("res://weapon.gd")
``` ```
Functions and variables ### Functions and variables
~~~~~~~~~~~~~~~~~~~~~~~
Use snake\_case to name functions and variables: Use snake\_case to name functions and variables:
@ -588,8 +568,7 @@ override, private functions, and private variables:
func _recalculate_path(): func _recalculate_path():
``` ```
Signals ### Signals
~~~~~~~
Use the past tense to name signals: Use the past tense to name signals:
@ -598,8 +577,7 @@ Use the past tense to name signals:
signal score_changed signal score_changed
``` ```
Constants and enums ### Constants and enums
~~~~~~~~~~~~~~~~~~~
Write constants with CONSTANT\_CASE, that is to say in all caps with an Write constants with CONSTANT\_CASE, that is to say in all caps with an
underscore (\_) to separate words: underscore (\_) to separate words:
@ -621,8 +599,7 @@ are constants:
``` ```
Code order ## Code order
----------
This first section focuses on code order. For formatting, see This first section focuses on code order. For formatting, see
`formatting`. For naming conventions, see `naming_conventions`. `formatting`. For naming conventions, see `naming_conventions`.
@ -663,8 +640,8 @@ This code order follows four rules of thumb:
`ready`, come before functions that modify the object at runtime. `ready`, come before functions that modify the object at runtime.
Class declaration ### Class declaration
~~~~~~~~~~~~~~~~~
If the code is meant to run in the editor, place the `tool` keyword on the If the code is meant to run in the editor, place the `tool` keyword on the
first line of the script. first line of the script.
@ -686,8 +663,7 @@ and how other developers should use it, for example.
# Longer description. # Longer description.
``` ```
Signals and properties ### Signals and properties
~~~~~~~~~~~~~~~~~~~~~~
Write signal declarations, followed by properties, that is to say, member Write signal declarations, followed by properties, that is to say, member
variables, after the docstring. variables, after the docstring.
@ -726,22 +702,19 @@ Note:
child nodes in the scene that your class relies on. This is what the example child nodes in the scene that your class relies on. This is what the example
above shows. above shows.
Member variables ### Member variables
~~~~~~~~~~~~~~~~
Don't declare member variables if they are only used locally in a method, as it Don't declare member variables if they are only used locally in a method, as it
makes the code more difficult to follow. Instead, declare them as local makes the code more difficult to follow. Instead, declare them as local
variables in the method's body. variables in the method's body.
Local variables ### Local variables
~~~~~~~~~~~~~~~
Declare local variables as close as possible to their first use. This makes it Declare local variables as close as possible to their first use. This makes it
easier to follow the code, without having to scroll too much to find where the easier to follow the code, without having to scroll too much to find where the
variable was declared. variable was declared.
Methods and static functions ### Methods and static functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
After the class's properties come the methods. After the class's properties come the methods.
@ -792,28 +765,25 @@ in that order.
``` ```
Static typing ## Static typing
-------------
Since Pandemonium 3.1, GDScript supports `optional static typing( doc_gdscript_static_typing )`. Since Pandemonium 3.1, GDScript supports `optional static typing( doc_gdscript_static_typing )`.
Declared types ### Declared types
~~~~~~~~~~~~~~
To declare a variable's type, use `<variable>: <type )`: To declare a variable's type, use `&lt;variable&gt;: &lt;type&gt;`:
``` ```
var health: int = 0 var health: int = 0
``` ```
To declare the return type of a function, use `-> <type )`: To declare the return type of a function, use `-> &lt;type&gt;`:
``` ```
func heal(amount: int) -> void: func heal(amount: int) -> void:
``` ```
Inferred types ### Inferred types
~~~~~~~~~~~~~~
In most cases you can let the compiler infer the type, using `:=`: In most cases you can let the compiler infer the type, using `:=`:

View File

@ -1,7 +1,6 @@
Static typing in GDScript # Static typing in GDScript
=========================
In this guide, you will learn: In this guide, you will learn:
@ -17,11 +16,9 @@ and return types.
Note: Note:
Typed GDScript is available since Pandemonium 3.1. Typed GDScript is available since Pandemonium 3.1.
A brief look at static typing ## A brief look at static typing
-----------------------------
With typed GDScript, Pandemonium can detect even more errors as you write With typed GDScript, Pandemonium can detect even more errors as you write
code! It gives you and your teammates more information as you're code! It gives you and your teammates more information as you're
@ -60,15 +57,17 @@ options for a class called `PlayerController`.
You've probably stored a node in a variable before, and typed a dot to You've probably stored a node in a variable before, and typed a dot to
be left with no autocomplete suggestions: be left with no autocomplete suggestions:
.. figure:: img/typed_gdscript_code_completion_dynamic.png) ![code completion options for dynamic](img/typed_gdscript_code_completion_dynamic.png)
:alt: code completion options for dynamic
code completion options for dynamic
This is due to dynamic code. Pandemonium cannot know what node or value type This is due to dynamic code. Pandemonium cannot know what node or value type
you're passing to the function. If you write the type explicitly you're passing to the function. If you write the type explicitly
however, you will get all public methods and variables from the node: however, you will get all public methods and variables from the node:
.. figure:: img/typed_gdscript_code_completion_typed.png) ![code completion options for typed](img/typed_gdscript_code_completion_typed.png)
:alt: code completion options for typed
code completion options for typed
In the future, typed GDScript will also increase code performance: In the future, typed GDScript will also increase code performance:
Just-In-Time compilation and other compiler improvements are already Just-In-Time compilation and other compiler improvements are already
@ -82,8 +81,7 @@ their time reading other people's code, or scripts they wrote in the
past and forgot about. The clearer and the more structured the code, the past and forgot about. The clearer and the more structured the code, the
faster it is to understand, the faster you can move forward. faster it is to understand, the faster you can move forward.
How to use static typing ## How to use static typing
------------------------
To define the type of a variable or a constant, write a colon after the To define the type of a variable or a constant, write a colon after the
variable's name, followed by its type. E.g. `var health: int`. This variable's name, followed by its type. E.g. `var health: int`. This
@ -113,11 +111,9 @@ Currently you can use three types of… types:
Note: Note:
You don't need to write type hints for constants, as Pandemonium sets it automatically from the assigned value. But you can still do so to make the intent of your code clearer. You don't need to write type hints for constants, as Pandemonium sets it automatically from the assigned value. But you can still do so to make the intent of your code clearer.
Custom variable types ### Custom variable types
~~~~~~~~~~~~~~~~~~~~~
You can use any class, including your custom classes, as types. There You can use any class, including your custom classes, as types. There
are two ways to use them in scripts. The first method is to preload the are two ways to use them in scripts. The first method is to preload the
@ -144,8 +140,7 @@ into a constant:
var my_rifle: Rifle var my_rifle: Rifle
``` ```
Variable casting ### Variable casting
~~~~~~~~~~~~~~~~
Type casting is a key concept in typed languages. Type casting is a key concept in typed languages.
Casting is the conversion of a value from one type to another. Casting is the conversion of a value from one type to another.
@ -178,13 +173,11 @@ get full autocompletion on the player variable thanks to that cast.
Note: Note:
If you try to cast with a built-in type and it fails, Pandemonium will throw an error. If you try to cast with a built-in type and it fails, Pandemonium will throw an error.
Safe lines #### Safe lines
^^^^^^^^^^
You can also use casting to ensure safe lines. Safe lines are a new You can also use casting to ensure safe lines. Safe lines are a new
tool in Pandemonium 3.1 to tell you when ambiguous lines of code are tool in Pandemonium 3.1 to tell you when ambiguous lines of code are
@ -205,18 +198,15 @@ node: `($Timer as Timer)`, `($Player as KinematicBody2D)`, etc.
Pandemonium will ensure the type works and if so, the line number will turn Pandemonium will ensure the type works and if so, the line number will turn
green at the left of the script editor. green at the left of the script editor.
.. figure:: img/typed_gdscript_safe_unsafe_line.png) ![Unsafe vs Safe Line](img/typed_gdscript_safe_unsafe_line.png)
:alt: Unsafe vs Safe Line
Unsafe line (line 7) vs Safe Lines (line 6 and 8) Unsafe line (line 7) vs Safe Lines (line 6 and 8)
Note: Note:
You can turn off safe lines or change their color in the editor settings. You can turn off safe lines or change their color in the editor settings.
Define the return type of a function with the arrow -> #### Define the return type of a function with the arrow ->
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
To define the return type of a function, write a dash and a right angle To define the return type of a function, write a dash and a right angle
bracket `- )` after its declaration, followed by the return type: bracket `- )` after its declaration, followed by the return type:
@ -250,8 +240,7 @@ You can also use your own nodes as return types:
return item return item
``` ```
Typed or dynamic: stick to one style #### Typed or dynamic: stick to one style
------------------------------------
Typed GDScript and dynamic GDScript can coexist in the same project. But Typed GDScript and dynamic GDScript can coexist in the same project. But
it's recommended to stick to either style for consistency in your codebase, it's recommended to stick to either style for consistency in your codebase,
@ -263,6 +252,7 @@ Typed code takes a little more writing, but you get the benefits we
discussed above. Here's an example of the same, empty script, in a discussed above. Here's an example of the same, empty script, in a
dynamic style: dynamic style:
``` ```
extends Node extends Node
@ -321,17 +311,14 @@ we make sure it is our `Bullet`, a node we created for our project. If
it's anything else, like an `Area2D`, or any node that doesn't extend it's anything else, like an `Area2D`, or any node that doesn't extend
`Bullet`, the `bullet` variable will be `null`. `Bullet`, the `bullet` variable will be `null`.
Warning system ## Warning system
--------------
Note: Note:
Documentation about the GDScript warning system has been moved to Documentation about the GDScript warning system has been moved to
`doc_gdscript_warning_system`. `doc_gdscript_warning_system`.
Cases where you can't specify types ## Cases where you can't specify types
-----------------------------------
To wrap up this introduction, let's cover a few cases where you can't To wrap up this introduction, let's cover a few cases where you can't
use type hints. All the examples below **will trigger errors**. use type hints. All the examples below **will trigger errors**.
@ -382,8 +369,7 @@ Two scripts can't depend on each other in a cyclic fashion:
var player: Player var player: Player
``` ```
Summary ## Summary
-------
Typed GDScript is a powerful tool. Available as of version 3.1 of Pandemonium, it Typed GDScript is a powerful tool. Available as of version 3.1 of Pandemonium, it
helps you write more structured code, avoid common errors, and helps you write more structured code, avoid common errors, and

View File

@ -1,7 +1,5 @@
# GDScript warning system
GDScript warning system
=======================
The GDScript warning system complements `static typing ( doc_gdscript_static_typing )` The GDScript warning system complements `static typing ( doc_gdscript_static_typing )`
(but it can work without static typing too). It's here to help you avoid (but it can work without static typing too). It's here to help you avoid
@ -11,18 +9,16 @@ to runtime errors.
You can configure warnings in the Project Settings under the section You can configure warnings in the Project Settings under the section
called **Gdscript**: called **Gdscript**:
.. figure:: img/typed_gdscript_warning_system_settings.png) ![Warning system project settings](img/typed_gdscript_warning_system_settings.png)
:alt: Warning system project settings
Warning system project settings Warning system project settings
You can find a list of warnings for the active GDScript file in the You can find a list of warnings for the active GDScript file in the
script editor's status bar. The example below has 3 warnings: script editor's status bar. The example below has 3 warnings:
.. figure:: img/typed_gdscript_warning_example.png) ![Warning system example](img/typed_gdscript_warning_example.png)
:alt: Warning system example
Warning system example Warning system example
To ignore specific warnings in one file, insert a special comment of the To ignore specific warnings in one file, insert a special comment of the
form `# warning-ignore:warning-id`, or click on the ignore link to the form `# warning-ignore:warning-id`, or click on the ignore link to the
@ -30,10 +26,9 @@ right of the warning's description. Pandemonium will add a comment above the
corresponding line and the code won't trigger the corresponding warning corresponding line and the code won't trigger the corresponding warning
anymore: anymore:
.. figure:: img/typed_gdscript_warning_system_ignore.png) ![Warning system ignore example](img/typed_gdscript_warning_system_ignore.png)
:alt: Warning system ignore example
Warning system ignore example Warning system ignore example
You can also choose to ignore not just one but all warnings of a certain You can also choose to ignore not just one but all warnings of a certain
type in this file with `# warning-ignore-all:warning-id`. To ignore all type in this file with `# warning-ignore-all:warning-id`. To ignore all
@ -45,7 +40,6 @@ all warnings. Head to the `GDScript` section of the Project Settings to
turn on this option. Here's the same file as the previous example with turn on this option. Here's the same file as the previous example with
warnings as errors turned on: warnings as errors turned on:
.. figure:: img/typed_gdscript_warning_system_errors.png) ![Warnings as errors](img/typed_gdscript_warning_system_errors.png)
:alt: Warnings as errors
Warnings as errors Warnings as errors

View File

@ -1,7 +1,6 @@
GDScript format strings # GDScript format strings
=======================
GDScript offers a feature called *format strings*, which allows reusing text GDScript offers a feature called *format strings*, which allows reusing text
templates to succinctly create different but similar strings. templates to succinctly create different but similar strings.
@ -16,8 +15,7 @@ the placeholder is in the middle of the string; modifying it without format
strings could be cumbersome. strings could be cumbersome.
Usage in GDScript ## Usage in GDScript
-----------------
Examine this concrete GDScript example: Examine this concrete GDScript example:
@ -67,8 +65,7 @@ There are other `format specifiers`, but they are only applicable when using
the `%` operator. the `%` operator.
Multiple placeholders ## Multiple placeholders
---------------------
Format strings may contain multiple placeholders. In such a case, the values Format strings may contain multiple placeholders. In such a case, the values
are handed in the form of an array, one value per placeholder (unless using a are handed in the form of an array, one value per placeholder (unless using a
@ -86,8 +83,7 @@ Note the values are inserted in order. Remember all placeholders must be
replaced at once, so there must be an appropriate number of values. replaced at once, so there must be an appropriate number of values.
Format specifiers ## Format specifiers
-----------------
There are format specifiers other than `s` that can be used in placeholders. There are format specifiers other than `s` that can be used in placeholders.
They consist of one or more characters. Some of them work by themselves like They consist of one or more characters. Some of them work by themselves like
@ -95,61 +91,51 @@ They consist of one or more characters. Some of them work by themselves like
values or characters. values or characters.
Placeholder types ### Placeholder types
~~~~~~~~~~~~~~~~~
One and only one of these must always appear as the last character in a format One and only one of these must always appear as the last character in a format
specifier. Apart from `s`, these require certain types of parameters. specifier. Apart from `s`, these require certain types of parameters.
+-------+---------------------------------------------------------------------+
| `s` | **Simple** conversion to String by the same method as implicit | | | |
|-------|---------------------------------------------------------------------|
| `s` | **Simple** conversion to String by the same method as implicit |
| | String conversion. | | | String conversion. |
+-------+---------------------------------------------------------------------+ | `c` | A single **Unicode character**. Expects an unsigned 8-bit integer |
| `c` | A single **Unicode character**. Expects an unsigned 8-bit integer |
| | (0-255) for a code point or a single-character string. | | | (0-255) for a code point or a single-character string. |
+-------+---------------------------------------------------------------------+ | `d` | A **decimal integral** number. Expects an integral or real number |
| `d` | A **decimal integral** number. Expects an integral or real number |
| | (will be floored). | | | (will be floored). |
+-------+---------------------------------------------------------------------+ | `o` | An **octal integral** number. Expects an integral or real number |
| `o` | An **octal integral** number. Expects an integral or real number |
| | (will be floored). | | | (will be floored). |
+-------+---------------------------------------------------------------------+ | `x` | A **hexadecimal integral** number with **lower-case** letters. |
| `x` | A **hexadecimal integral** number with **lower-case** letters. |
| | Expects an integral or real number (will be floored). | | | Expects an integral or real number (will be floored). |
+-------+---------------------------------------------------------------------+ | `X` | A **hexadecimal integral** number with **upper-case** letters. |
| `X` | A **hexadecimal integral** number with **upper-case** letters. |
| | Expects an integral or real number (will be floored). | | | Expects an integral or real number (will be floored). |
+-------+---------------------------------------------------------------------+ | `f` | A **decimal real** number. Expects an integral or real number. |
| `f` | A **decimal real** number. Expects an integral or real number. |
+-------+---------------------------------------------------------------------+
Placeholder modifiers
~~~~~~~~~~~~~~~~~~~~~ ### Placeholder modifiers
These characters appear before the above. Some of them work only under certain These characters appear before the above. Some of them work only under certain
conditions. conditions.
+---------+-------------------------------------------------------------------+ | | |
| `+` | In number specifiers, **show + sign** if positive. | |---------|-------------------------------------------------------------------|
+---------+-------------------------------------------------------------------+ | `+` | In number specifiers, **show + sign** if positive. |
| Integer | Set **padding**. Padded with spaces or with zeroes if integer | | Integer | Set **padding**. Padded with spaces or with zeroes if integer |
| | starts with `0` in an integer or real number placeholder. | | | starts with `0` in an integer or real number placeholder. |
| | The leading `0` is ignored if `-` is present. | | | The leading `0` is ignored if `-` is present. |
| | When used after `.`, see `.`. | | | When used after `.`, see `.`. |
+---------+-------------------------------------------------------------------+ | `.` | Before `f`, set **precision** to 0 decimal places. Can be |
| `.` | Before `f`, set **precision** to 0 decimal places. Can be |
| | followed up with numbers to change. Padded with zeroes. | | | followed up with numbers to change. Padded with zeroes. |
+---------+-------------------------------------------------------------------+ | `-` | **Pad to the right** rather than the left. |
| `-` | **Pad to the right** rather than the left. | | `*` | **Dynamic padding**, expect additional integral parameter to set |
+---------+-------------------------------------------------------------------+ | | padding or precision after `.`, see `dynamic padding`. |
| `*` | **Dynamic padding**, expect additional integral parameter to set |
| | padding or precision after `.`, see `dynamic padding`. |
+---------+-------------------------------------------------------------------+
Padding
------- ## Padding
The `.` (*dot*), `*` (*asterisk*), `-` (*minus sign*) and digit The `.` (*dot*), `*` (*asterisk*), `-` (*minus sign*) and digit
(`0`-`9`) characters are used for padding. This allows printing several (`0`-`9`) characters are used for padding. This allows printing several
@ -194,8 +180,7 @@ useful for right text alignment:
``` ```
Dynamic padding ### Dynamic padding
~~~~~~~~~~~~~~~
By using the `*` (*asterisk*) character, the padding or precision can be set By using the `*` (*asterisk*) character, the padding or precision can be set
without modifying the format string. It is used in place of an integer in the without modifying the format string. It is used in place of an integer in the
@ -219,8 +204,7 @@ before `*`:
``` ```
Escape sequence ## Escape sequence
---------------
To insert a literal `%` character into a format string, it must be escaped to To insert a literal `%` character into a format string, it must be escaped to
avoid reading it as a placeholder. This is done by doubling the character: avoid reading it as a placeholder. This is done by doubling the character:
@ -232,50 +216,39 @@ avoid reading it as a placeholder. This is done by doubling the character:
``` ```
Format method examples ## Format method examples
----------------------
The following are some examples of how to use the various invocations of the The following are some examples of how to use the various invocations of the
`String.format` method. `String.format` method.
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| **Type** | **Style** | **Example** | **Result** | | **Type** | **Style** | **Example** | **Result** |
+------------+-----------+------------------------------------------------------------------------------+-------------------+ |------------|-----------|------------------------------------------------------------------------------|-------------------|
| Dictionary | key | `"Hi, {name} v{version}!".format({"name":"Godette", "version":"3.0"})` | Hi, Godette v3.0! | | Dictionary | key | `"Hi, {name} v{version}!".format({"name":"Godette", "version":"3.0"})` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+ | Dictionary | index | `"Hi, {0} v{1}!".format({"0":"Godette", "1":"3.0"})` | Hi, Godette v3.0! |
| Dictionary | index | `"Hi, {0} v{1}!".format({"0":"Godette", "1":"3.0"})` | Hi, Godette v3.0! | | Dictionary | mix | `"Hi, {0} v{version}!".format({"0":"Godette", "version":"3.0"})` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+ | Array | key | `"Hi, {name} v{version}!".format([["version","3.0"], ["name","Godette"]])` | Hi, Godette v3.0! |
| Dictionary | mix | `"Hi, {0} v{version}!".format({"0":"Godette", "version":"3.0"})` | Hi, Godette v3.0! | | Array | index | `"Hi, {0} v{1}!".format(["Godette","3.0"])` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+ | Array | mix | `"Hi, {name} v{0}!".format([3.0, ["name","Godette"]])` | Hi, Godette v3.0! |
| Array | key | `"Hi, {name} v{version}!".format([["version","3.0"], ["name","Godette"]])` | Hi, Godette v3.0! | | Array | no index | `"Hi, {} v{}!".format(["Godette", 3.0], "{}")` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| Array | index | `"Hi, {0} v{1}!".format(["Godette","3.0"])` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| Array | mix | `"Hi, {name} v{0}!".format([3.0, ["name","Godette"]])` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| Array | no index | `"Hi, {} v{}!".format(["Godette", 3.0], "{}")` | Hi, Godette v3.0! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
Placeholders can also be customized when using `String.format`, here's some Placeholders can also be customized when using `String.format`, here's some
examples of that functionality. examples of that functionality.
+-----------------+------------------------------------------------------+------------------+
| **Type** | **Example** | **Result** | | **Type** | **Example** | **Result** |
+-----------------+------------------------------------------------------+------------------+ |-----------------|------------------------------------------------------|------------------|
| Infix (default) | `"Hi, {0} v{1}".format(["Godette", "3.0"], "{_}")` | Hi, Godette v3.0 | | Infix (default) | `"Hi, {0} v{1}".format(["Godette", "3.0"], "{_}")` | Hi, Godette v3.0 |
+-----------------+------------------------------------------------------+------------------+ | Postfix | `"Hi, 0% v1%".format(["Godette", "3.0"], "_%")` | Hi, Godette v3.0 |
| Postfix | `"Hi, 0% v1%".format(["Godette", "3.0"], "_%")` | Hi, Godette v3.0 | | Prefix | `"Hi, %0 v%1".format(["Godette", "3.0"], "%_")` | Hi, Godette v3.0 |
+-----------------+------------------------------------------------------+------------------+
| Prefix | `"Hi, %0 v%1".format(["Godette", "3.0"], "%_")` | Hi, Godette v3.0 |
+-----------------+------------------------------------------------------+------------------+
Combining both the `String.format` method and the `%` operator could be useful, as Combining both the `String.format` method and the `%` operator could be useful, as
`String.format` does not have a way to manipulate the representation of numbers. `String.format` does not have a way to manipulate the representation of numbers.
+---------------------------------------------------------------------------+-------------------+
| **Example** | **Result** | | **Example** | **Result** |
+---------------------------------------------------------------------------+-------------------+ |---------------------------------------------------------------------------|-------------------|
| `"Hi, {0} v{version}".format({0:"Godette", "version":"%0.2f" % 3.114})` | Hi, Godette v3.11 | | `"Hi, {0} v{version}".format({0:"Godette", "version":"%0.2f" % 3.114})` | Hi, Godette v3.11 |
+---------------------------------------------------------------------------+-------------------+

View File

@ -1,7 +1,6 @@
Introduction to shaders # Introduction to shaders
=======================
This page explains what shaders are and will give you an overview of how they This page explains what shaders are and will give you an overview of how they
work in Pandemonium. For a detailed reference of the engine's shading language, see work in Pandemonium. For a detailed reference of the engine's shading language, see
@ -42,11 +41,9 @@ look like this.
Note: Note:
The graphics card calls the `fragment()` function once or more for each pixel it has to draw. More on that below. The graphics card calls the `fragment()` function once or more for each pixel it has to draw. More on that below.
Shaders in Pandemonium ## Shaders in Pandemonium
----------------
Pandemonium provides a shading language based on the popular OpenGL Shading Language Pandemonium provides a shading language based on the popular OpenGL Shading Language
(GLSL) but simplified. The engine handles some of the lower-level initialization (GLSL) but simplified. The engine handles some of the lower-level initialization
@ -73,8 +70,7 @@ Warning:
enabled in the Project Settings. It's enabled by default on mobile enabled in the Project Settings. It's enabled by default on mobile
platforms. platforms.
Shader types ## Shader types
------------
Instead of supplying a general-purpose configuration for all uses (2D, 3D, Instead of supplying a general-purpose configuration for all uses (2D, 3D,
particles), you must specify the type of shader you're writing. Different types particles), you must specify the type of shader you're writing. Different types
@ -92,8 +88,7 @@ Here are the available types:
* `canvas_item ( doc_canvas_item_shader )` for 2D rendering. * `canvas_item ( doc_canvas_item_shader )` for 2D rendering.
* `particles ( doc_particle_shader )` for particle systems. * `particles ( doc_particle_shader )` for particle systems.
Render modes ## Render modes
------------
Shaders have optional render modes you can specify on the second line, after the Shaders have optional render modes you can specify on the second line, after the
shader type, like so: shader type, like so:
@ -109,16 +104,14 @@ Render modes alter the way Pandemonium applies the shader. For example, the
Each shader type has different render modes. See the reference for each shader Each shader type has different render modes. See the reference for each shader
type for a complete list of render modes. type for a complete list of render modes.
Processor functions ## Processor functions
-------------------
Depending on the shader type, you can override different processor functions. Depending on the shader type, you can override different processor functions.
For `spatial` and `canvas_item`, you have access to `vertex()`, For `spatial` and `canvas_item`, you have access to `vertex()`,
`fragment()`, and `light()`. For `particles`, you only have access to `fragment()`, and `light()`. For `particles`, you only have access to
`vertex()`. `vertex()`.
Vertex processor #### Vertex processor
^^^^^^^^^^^^^^^^
The `vertex()` processing function is called once for every vertex in The `vertex()` processing function is called once for every vertex in
`spatial` and `canvas_item` shaders. For `particles` shaders, it is called `spatial` and `canvas_item` shaders. For `particles` shaders, it is called
@ -133,8 +126,7 @@ to project geometry onto the screen. You can use render modes to transform the
data yourself; see the `Spatial shader doc ( doc_spatial_shader )` for an data yourself; see the `Spatial shader doc ( doc_spatial_shader )` for an
example. example.
Fragment processor #### Fragment processor
^^^^^^^^^^^^^^^^^^
The `fragment()` processing function is used to set up the Pandemonium material The `fragment()` processing function is used to set up the Pandemonium material
parameters per pixel. This code runs on every visible pixel the object or parameters per pixel. This code runs on every visible pixel the object or
@ -152,8 +144,7 @@ Pandemonium checks to see if `RIM` is used; if not, it cuts all the correspondin
code out. Therefore, you will not waste calculations on the effects that you do code out. Therefore, you will not waste calculations on the effects that you do
not use. not use.
Light processor #### Light processor
^^^^^^^^^^^^^^^
The `light()` processor runs per pixel too, and it runs once for every light The `light()` processor runs per pixel too, and it runs once for every light
that affects the object. It does not run if no lights affect the object. It that affects the object. It does not run if no lights affect the object. It

View File

@ -1,10 +1,8 @@
Shader materials # Shader materials
================
Introduction ## Introduction
------------
For the most common cases, Pandemonium provides ready to use materials for For the most common cases, Pandemonium provides ready to use materials for
most types of shaders, such as `SpatialMaterial`, most types of shaders, such as `SpatialMaterial`,
@ -28,8 +26,7 @@ easier. Additionally, Pandemonium's shader editor will detect errors as you
type, so you can see your edited shaders in real-time. It is also type, so you can see your edited shaders in real-time. It is also
possible to edit shaders using a visual, node-based graph editor. possible to edit shaders using a visual, node-based graph editor.
Creating a ShaderMaterial ## Creating a ShaderMaterial
-------------------------
Create a new ShaderMaterial in some object of your choice. Go to the Create a new ShaderMaterial in some object of your choice. Go to the
"Material" property and create a ShaderMaterial. "Material" property and create a ShaderMaterial.
@ -63,12 +60,9 @@ your visual shader to a text shader.
![](img/visual_shader_code.png) ![](img/visual_shader_code.png)
Note: Note:
To learn more about visual shaders, read `doc_visual_shaders`. To learn more about visual shaders, read `doc_visual_shaders`.
Converting to ShaderMaterial ## Converting to ShaderMaterial
----------------------------
It is possible to convert from SpatialMaterial, CanvasItemMaterial and It is possible to convert from SpatialMaterial, CanvasItemMaterial and
ParticlesMaterial to ShaderMaterial. To do so, go to the material properties ParticlesMaterial to ShaderMaterial. To do so, go to the material properties
@ -78,6 +72,5 @@ and select the convert option.
Note: Note:
Using the convert option will turn the SpatialMaterial into a ShaderMaterial Using the convert option will turn the SpatialMaterial into a ShaderMaterial
with a text shader, not a visual shader. with a text shader, not a visual shader.

View File

@ -1,10 +1,7 @@
# Screen-reading shaders
Screen-reading shaders ### Introduction
======================
Introduction
~~~~~~~~~~~~
It is often desired to make a shader that reads from the same It is often desired to make a shader that reads from the same
screen to which it's writing. 3D APIs, such as OpenGL or DirectX, make this very screen to which it's writing. 3D APIs, such as OpenGL or DirectX, make this very
@ -17,8 +14,7 @@ The workaround is to make a copy of the screen, or a part of the screen,
to a back-buffer and then read from it while drawing. Pandemonium provides a to a back-buffer and then read from it while drawing. Pandemonium provides a
few tools that make this process easy. few tools that make this process easy.
SCREEN_TEXTURE built-in texture ### SCREEN_TEXTURE built-in texture
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Pandemonium `doc_shading_language` has a special texture, `SCREEN_TEXTURE` (and `DEPTH_TEXTURE` for depth, in the case of 3D). Pandemonium `doc_shading_language` has a special texture, `SCREEN_TEXTURE` (and `DEPTH_TEXTURE` for depth, in the case of 3D).
It takes as argument the UV of the screen and returns a vec3 RGB with the color. A It takes as argument the UV of the screen and returns a vec3 RGB with the color. A
@ -45,8 +41,7 @@ Note:
Mipmaps are not generated in GLES2 due to poor performance and compatibility with older Mipmaps are not generated in GLES2 due to poor performance and compatibility with older
devices. devices.
SCREEN_TEXTURE example ### SCREEN_TEXTURE example
~~~~~~~~~~~~~~~~~~~~~~
`SCREEN_TEXTURE` can be used for many things. There is a `SCREEN_TEXTURE` can be used for many things. There is a
special demo for *Screen Space Shaders*, that you can download to see special demo for *Screen Space Shaders*, that you can download to see
@ -71,8 +66,7 @@ and saturation:
} }
``` ```
Behind the scenes ### Behind the scenes
~~~~~~~~~~~~~~~~~
While this seems magical, it's not. In 2D, the `SCREEN_TEXTURE` built-in, when While this seems magical, it's not. In 2D, the `SCREEN_TEXTURE` built-in, when
first found in a node that is about to be drawn, does a full-screen first found in a node that is about to be drawn, does a full-screen
@ -102,7 +96,7 @@ With correct back-buffer copying, the two spheres blend correctly:
![](img/texscreen_demo2.png) ![](img/texscreen_demo2.png)
.. warning: Warning:
Materials that use `SCREEN_TEXTURE` are considered transparent themselves and Materials that use `SCREEN_TEXTURE` are considered transparent themselves and
will not appear in the resulting `SCREEN_TEXTURE` of other materials. will not appear in the resulting `SCREEN_TEXTURE` of other materials.
@ -118,8 +112,7 @@ You can reproduce the back-buffer logic in 3D by creating a `Viewport`
with a camera in the same position as your object, and then use the with a camera in the same position as your object, and then use the
`Viewport's` texture instead of `SCREEN_TEXTURE`. `Viewport's` texture instead of `SCREEN_TEXTURE`.
Back-buffer logic ### Back-buffer logic
~~~~~~~~~~~~~~~~~
So, to make it clearer, here's how the backbuffer copying logic works in So, to make it clearer, here's how the backbuffer copying logic works in
Pandemonium: Pandemonium:
@ -141,8 +134,7 @@ Pandemonium:
and then use `SCREEN_TEXTURE` on a different region. Avoid this behavior! and then use `SCREEN_TEXTURE` on a different region. Avoid this behavior!
DEPTH_TEXTURE ### DEPTH_TEXTURE
~~~~~~~~~~~~~
For 3D shaders, it's also possible to access the screen depth buffer. For this, For 3D shaders, it's also possible to access the screen depth buffer. For this,
the `DEPTH_TEXTURE` built-in is used. This texture is not linear; it must be the `DEPTH_TEXTURE` built-in is used. This texture is not linear; it must be

View File

@ -1,7 +1,6 @@
Converting GLSL to Pandemonium shaders # Converting GLSL to Pandemonium shaders
================================
This document explains the differences between Pandemonium's shading language and GLSL This document explains the differences between Pandemonium's shading language and GLSL
and gives practical advice on how to migrate shaders from other sources, such as and gives practical advice on how to migrate shaders from other sources, such as
@ -10,15 +9,13 @@ Shadertoy and The Book of Shaders, into Pandemonium shaders.
For detailed information on Pandemonium's shading language, please refer to the For detailed information on Pandemonium's shading language, please refer to the
`Shading Language ( doc_shading_language )` reference. `Shading Language ( doc_shading_language )` reference.
GLSL ## GLSL
----
Pandemonium uses a shading language based on GLSL with the addition of a few Pandemonium uses a shading language based on GLSL with the addition of a few
quality-of-life features. Accordingly, most features available in GLSL are quality-of-life features. Accordingly, most features available in GLSL are
available in Pandemonium's shading language. available in Pandemonium's shading language.
Shader programs #### Shader programs
^^^^^^^^^^^^^^^
In GLSL, each shader uses a separate program. You have one program for the In GLSL, each shader uses a separate program. You have one program for the
vertex shader and one for the fragment shader. In Pandemonium, you have a single vertex shader and one for the fragment shader. In Pandemonium, you have a single
@ -29,8 +26,7 @@ Pandemonium allows uniform variables and functions to be shared by defining the
fragment and vertex shaders in one file. In GLSL, the vertex and fragment fragment and vertex shaders in one file. In GLSL, the vertex and fragment
programs cannot share variables except when varyings are used. programs cannot share variables except when varyings are used.
Vertex attributes #### Vertex attributes
^^^^^^^^^^^^^^^^^
In GLSL, you can pass in per-vertex information using attributes and have the In GLSL, you can pass in per-vertex information using attributes and have the
flexibility to pass in as much or as little as you want. In Pandemonium, you have a flexibility to pass in as much or as little as you want. In Pandemonium, you have a
@ -38,8 +34,7 @@ set number of input attributes, including `VERTEX` (position), `COLOR`,
`UV`, `UV2`, `NORMAL`. For a complete list, see the `Shading language `UV`, `UV2`, `NORMAL`. For a complete list, see the `Shading language
reference ( doc_shading_language )`. reference ( doc_shading_language )`.
gl_Position #### gl_Position
^^^^^^^^^^^
`gl_Position` receives the final position of a vertex specified in the vertex `gl_Position` receives the final position of a vertex specified in the vertex
shader. It is specified by the user in clip space. Typically, in GLSL, the model shader. It is specified by the user in clip space. Typically, in GLSL, the model
@ -55,30 +50,26 @@ skip the conversion from model to view space, you can set the `render_mode` to
to `mat4(1.0)` in order to nullify the final transform from view space to clip to `mat4(1.0)` in order to nullify the final transform from view space to clip
space. space.
Varyings #### Varyings
^^^^^^^^
Varyings are a type of variable that can be passed from the vertex shader to the Varyings are a type of variable that can be passed from the vertex shader to the
fragment shader. In modern GLSL (3.0 and up), varyings are defined with the fragment shader. In modern GLSL (3.0 and up), varyings are defined with the
`in` and `out` keywords. A variable going out of the vertex shader is `in` and `out` keywords. A variable going out of the vertex shader is
defined with `out` in the vertex shader and `in` inside the fragment shader. defined with `out` in the vertex shader and `in` inside the fragment shader.
Main #### Main
^^^^
In GLSL, each shader program looks like a self-contained C-style program. In GLSL, each shader program looks like a self-contained C-style program.
Accordingly, the main entry point is `main`. If you are copying a vertex Accordingly, the main entry point is `main`. If you are copying a vertex
shader, rename `main` to `vertex` and if you are copying a fragment shader, shader, rename `main` to `vertex` and if you are copying a fragment shader,
rename `main` to `fragment`. rename `main` to `fragment`.
Constants #### Constants
^^^^^^^^^
Global array constants are not supported in Pandemonium 3.x. You can fake the functionality by using a uniform Global array constants are not supported in Pandemonium 3.x. You can fake the functionality by using a uniform
initialized to the value, but you will not benefit from the increased speed from using a constant. initialized to the value, but you will not benefit from the increased speed from using a constant.
Macros #### Macros
^^^^^^
In keeping with its similarity to C, GLSL lets you use macros. Commonly In keeping with its similarity to C, GLSL lets you use macros. Commonly
`#define` is used to define constants or small functions. There is no `#define` is used to define constants or small functions. There is no
@ -88,39 +79,30 @@ then replace with a uniform. For other macros (`#if`, `#ifdef`, etc.), there
is no equivalent because they run during the pre-processing stage of is no equivalent because they run during the pre-processing stage of
compilation. compilation.
Variables #### Variables
^^^^^^^^^ ^^^^^^^^^
GLSL has many built-in variables that are hard-coded. These variables are not GLSL has many built-in variables that are hard-coded. These variables are not
uniforms, so they are not editable from the main program. uniforms, so they are not editable from the main program.
+---------------------+---------+------------------------+-----------------------------------------------------+
|Variable |Type |Equivalent |Description |
+=====================+=========+========================+=====================================================+
|gl_FragColor |out vec4 |COLOR |Output color for each pixel. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|gl_FragCoord |vec4 |FRAGCOORD |For full screen quads. For smaller quads, use UV. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|gl_Position |vec4 |VERTEX |Position of Vertex, output from Vertex Shader. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|gl_PointSize |float |POINT_SIZE |Size of Point primitive. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|gl_PointCoord |vec2 |POINT_COORD |Position on point when drawing Point primitives. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|gl_FrontFacing |bool |FRONT_FACING |True if front face of primitive. |
+---------------------+---------+------------------------+-----------------------------------------------------+
.. _glsl_coordinates: | Variable | Type | Equivalent | Description |
|----------------------|----------|-------------------------|------------------------------------------------------|
| gl_FragColor | out vec4 | COLOR | Output color for each pixel. |
| gl_FragCoord | vec4 | FRAGCOORD | For full screen quads. For smaller quads, use UV. |
| gl_Position | vec4 | VERTEX | Position of Vertex, output from Vertex Shader. |
| gl_PointSize | float | POINT_SIZE | Size of Point primitive. |
| gl_PointCoord | vec2 | POINT_COORD | Position on point when drawing Point primitives. |
| gl_FrontFacing | bool | FRONT_FACING | True if front face of primitive. |
Coordinates
^^^^^^^^^^^ #### Coordinates
`gl_FragCoord` in GLSL and `FRAGCOORD` in the Pandemonium shading language use the `gl_FragCoord` in GLSL and `FRAGCOORD` in the Pandemonium shading language use the
same coordinate system. If using UV in Pandemonium, the y-coordinate will be flipped same coordinate system. If using UV in Pandemonium, the y-coordinate will be flipped
upside down. upside down.
Precision #### Precision
^^^^^^^^^
In GLSL, you can define the precision of a given type (float or int) at the top In GLSL, you can define the precision of a given type (float or int) at the top
of the shader with the `precision` keyword. In Pandemonium, you can set the of the shader with the `precision` keyword. In Pandemonium, you can set the
@ -129,8 +111,7 @@ precision of individual variables as you need by placing precision qualifiers
For more information, see the `Shading Language ( doc_shading_language )` For more information, see the `Shading Language ( doc_shading_language )`
reference. reference.
Shadertoy #### Shadertoy
---------
`Shadertoy ( https://www.shadertoy.com/results?query=&sort=popular&from=10&num=4 )` `Shadertoy ( https://www.shadertoy.com/results?query=&sort=popular&from=10&num=4 )`
is a website that makes it easy to write fragment shaders and is a website that makes it easy to write fragment shaders and
@ -139,14 +120,12 @@ create `pure magic ( https://www.shadertoy.com/view/4tjGRh )`.
Shadertoy does not give the user full control over the shader. It handles all Shadertoy does not give the user full control over the shader. It handles all
the input and uniforms and only lets the user write the fragment shader. the input and uniforms and only lets the user write the fragment shader.
Types #### Types
^^^^^
Shadertoy uses the webgl spec, so it runs a slightly different version of GLSL. Shadertoy uses the webgl spec, so it runs a slightly different version of GLSL.
However, it still has the regular types, including constants and macros. However, it still has the regular types, including constants and macros.
mainImage #### mainImage
^^^^^^^^^
The main point of entry to a Shadertoy shader is the `mainImage` function. The main point of entry to a Shadertoy shader is the `mainImage` function.
`mainImage` has two parameters, `fragColor` and `fragCoord`, which `mainImage` has two parameters, `fragColor` and `fragCoord`, which
@ -155,8 +134,7 @@ parameters are handled automatically in Pandemonium, so you do not need to inclu
them as parameters yourself. Anything in the `mainImage` function should be them as parameters yourself. Anything in the `mainImage` function should be
copied into the `fragment` function when porting to Pandemonium. copied into the `fragment` function when porting to Pandemonium.
Variables #### Variables
^^^^^^^^^
In order to make writing fragment shaders straightforward and easy, Shadertoy In order to make writing fragment shaders straightforward and easy, Shadertoy
handles passing a lot of helpful information from the main program into the handles passing a lot of helpful information from the main program into the
@ -167,41 +145,28 @@ equivalents are listed as "Provide with Uniform", users are responsible for
creating that uniform themselves. The description gives the reader a hint about creating that uniform themselves. The description gives the reader a hint about
what they can pass in as a substitute. what they can pass in as a substitute.
+---------------------+---------+------------------------+-----------------------------------------------------+
|Variable |Type |Equivalent |Description |
+=====================+=========+========================+=====================================================+
|fragColor |out vec4 |COLOR |Output color for each pixel. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|fragCoord |vec2 |FRAGCOORD.xy |For full screen quads. For smaller quads, use UV. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iResolution |vec3 |1.0 / SCREEN_PIXEL_SIZE |Can also pass in manually. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iTime |float |TIME |Time since shader started. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iTimeDelta |float |Provide with Uniform |Time to render previous frame. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iFrame |float |Provide with Uniform |Frame number. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iChannelTime[4] |float |Provide with Uniform |Time since that particular texture started. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iMouse |vec4 |Provide with Uniform |Mouse position in pixel coordinates. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iDate |vec4 |Provide with Uniform |Current date, expressed in seconds. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iChannelResolution[4]|vec3 |1.0 / TEXTURE_PIXEL_SIZE|Resolution of particular texture. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|iChanneli |Sampler2D|TEXTURE |Pandemonium provides only one built-in; user can make more.|
+---------------------+---------+------------------------+-----------------------------------------------------+
Coordinates | Variable | Type | Equivalent | Description |
^^^^^^^^^^^ |----------------------|-----------|--------------------------|------------------------------------------------------|
| fragColor | out vec4 | COLOR | Output color for each pixel. |
| fragCoord | vec2 | FRAGCOORD.xy | For full screen quads. For smaller quads, use UV. |
| iResolution | vec3 | 1.0 / SCREEN_PIXEL_SIZE | Can also pass in manually. |
| iTime | float | TIME | Time since shader started. |
| iTimeDelta | float | Provide with Uniform | Time to render previous frame. |
| iFrame | float | Provide with Uniform | Frame number. |
| iChannelTime[4] | float | Provide with Uniform | Time since that particular texture started. |
| iMouse | vec4 | Provide with Uniform | Mouse position in pixel coordinates. |
| iDate | vec4 | Provide with Uniform | Current date, expressed in seconds. |
| iChannelResolution[4]| vec3 | 1.0 / TEXTURE_PIXEL_SIZE | Resolution of particular texture. |
| iChanneli | Sampler2D | TEXTURE | Pandemonium provides only one built-in; user can make more.|
#### Coordinates
`fragCoord` behaves the same as `gl_FragCoord` in `GLSL `fragCoord` behaves the same as `gl_FragCoord` in `GLSL
<glsl_coordinates )` and `FRAGCOORD` in Pandemonium. (glsl_coordinates )` and `FRAGCOORD` in Pandemonium.
The Book of Shaders ## The Book of Shaders
-------------------
Similar to Shadertoy, `The Book of Shaders ( https://thebookofshaders.com )` Similar to Shadertoy, `The Book of Shaders ( https://thebookofshaders.com )`
provides access to a fragment shader in the web browser, with which the user may provides access to a fragment shader in the web browser, with which the user may
@ -212,42 +177,34 @@ For further help on porting shaders to various frameworks generally, The Book of
Shaders provides a `page ( https://thebookofshaders.com/04 )` on running shaders Shaders provides a `page ( https://thebookofshaders.com/04 )` on running shaders
in various frameworks. in various frameworks.
Types #### Types
^^^^^
The Book of Shaders uses the webgl spec, so it runs a slightly different version The Book of Shaders uses the webgl spec, so it runs a slightly different version
of GLSL. However, it still has the regular types, including constants and of GLSL. However, it still has the regular types, including constants and
macros. macros.
Main #### Main
^^^^
The entry point for a Book of Shaders fragment shader is `main`, just like in The entry point for a Book of Shaders fragment shader is `main`, just like in
GLSL. Everything written in a Book of Shaders `main` function should be copied GLSL. Everything written in a Book of Shaders `main` function should be copied
into Pandemonium's `fragment` function. into Pandemonium's `fragment` function.
Variables #### Variables
^^^^^^^^^
The Book of Shaders sticks closer to plain GLSL than Shadertoy does. It also The Book of Shaders sticks closer to plain GLSL than Shadertoy does. It also
implements fewer uniforms than Shadertoy. implements fewer uniforms than Shadertoy.
+---------------------+---------+------------------------+-----------------------------------------------------+
|Variable |Type |Equivalent |Description |
+=====================+=========+========================+=====================================================+
|gl_FragColor |out vec4 |COLOR |Output color for each pixel. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|gl_FragCoord |vec4 |FRAGCOORD |For full screen quads. For smaller quads, use UV. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|u_resolution |vec2 |1.0 / SCREEN_PIXEL_SIZE |Can also pass in manually. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|u_time |float |TIME |Time since shader started. |
+---------------------+---------+------------------------+-----------------------------------------------------+
|u_mouse |vec2 |Provide with Uniform |Mouse position in pixel coordinates. |
+---------------------+---------+------------------------+-----------------------------------------------------+
Coordinates | Variable | Type | Equivalent | Description |
^^^^^^^^^^^ |----------------------|----------|-------------------------|------------------------------------------------------|
| gl_FragColor | out vec4 | COLOR | Output color for each pixel. |
| gl_FragCoord | vec4 | FRAGCOORD | For full screen quads. For smaller quads, use UV. |
| u_resolution | vec2 | 1.0 / SCREEN_PIXEL_SIZE | Can also pass in manually. |
| u_time | float | TIME | Time since shader started. |
| u_mouse | vec2 | Provide with Uniform | Mouse position in pixel coordinates. |
#### Coordinates
The Book of Shaders uses the same coordinate system as The Book of Shaders uses the same coordinate system as
`GLSL <glsl_coordinates )`. `GLSL ( glsl_coordinates )`.

View File

@ -1,7 +1,6 @@
Shaders style guide # Shaders style guide
===================
This style guide lists conventions to write elegant shaders. The goal is to This style guide lists conventions to write elegant shaders. The goal is to
encourage writing clean, readable code and promote consistency across projects, encourage writing clean, readable code and promote consistency across projects,
@ -47,19 +46,16 @@ Here is a complete shader example based on these guidelines:
} }
``` ```
Formatting ## Formatting
----------
Encoding and special characters ### Encoding and special characters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Use line feed (**LF**) characters to break lines, not CRLF or CR. *(editor default)* * Use line feed (**LF**) characters to break lines, not CRLF or CR. *(editor default)*
* Use one line feed character at the end of each file. *(editor default)* * Use one line feed character at the end of each file. *(editor default)*
* Use **UTF-8** encoding without a `byte order mark ( https://en.wikipedia.org/wiki/Byte_order_mark )`. *(editor default)* * Use **UTF-8** encoding without a `byte order mark ( https://en.wikipedia.org/wiki/Byte_order_mark )`. *(editor default)*
* Use **Tabs** instead of spaces for indentation. *(editor default)* * Use **Tabs** instead of spaces for indentation. *(editor default)*
Indentation ### Indentation
~~~~~~~~~~~
Each indent level should be one tab greater than the block containing it. Each indent level should be one tab greater than the block containing it.
@ -99,8 +95,7 @@ regular code blocks.
``` ```
Line breaks and blank lines ### Line breaks and blank lines
~~~~~~~~~~~~~~~~~~~~~~~~~~~
For a general indentation rule, follow For a general indentation rule, follow
`the "1TBS Style" ( https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS) )` `the "1TBS Style" ( https://en.wikipedia.org/wiki/Indentation_style#Variant:_1TBS_(OTBS) )`
@ -129,8 +124,7 @@ an `if` statement or similar.
} }
``` ```
Blank lines ### Blank lines
~~~~~~~~~~~
Surround function definitions with one (and only one) blank line: Surround function definitions with one (and only one) blank line:
@ -146,8 +140,7 @@ Surround function definitions with one (and only one) blank line:
Use one (and only one) blank line inside functions to separate logical sections. Use one (and only one) blank line inside functions to separate logical sections.
Line length ### Line length
~~~~~~~~~~~
Keep individual lines of code under 100 characters. Keep individual lines of code under 100 characters.
@ -155,8 +148,7 @@ If you can, try to keep lines under 80 characters. This helps to read the code
on small displays and with two shaders opened side-by-side in an external text on small displays and with two shaders opened side-by-side in an external text
editor. For example, when looking at a differential revision. editor. For example, when looking at a differential revision.
One statement per line ### One statement per line
~~~~~~~~~~~~~~~~~~~~~~
Never combine multiple statements on a single line. Never combine multiple statements on a single line.
@ -186,8 +178,7 @@ The only exception to that rule is the ternary operator:
} }
``` ```
Comment spacing ### Comment spacing
~~~~~~~~~~~~~~~
Regular comments should start with a space, but not code that you comment out. Regular comments should start with a space, but not code that you comment out.
This helps differentiate text comments from disabled code. This helps differentiate text comments from disabled code.
@ -219,8 +210,7 @@ Note:
press :kbd:`Ctrl + K`. This feature adds or removes `//` at the start of press :kbd:`Ctrl + K`. This feature adds or removes `//` at the start of
the selected lines. the selected lines.
Whitespace ### Whitespace
~~~~~~~~~~
Always use one space around operators and after commas. Also, avoid extraneous spaces Always use one space around operators and after commas. Also, avoid extraneous spaces
in function calls. in function calls.
@ -248,8 +238,7 @@ Don't use spaces to align expressions vertically:
EMISSION.r = 1.0; EMISSION.r = 1.0;
``` ```
Floating-point numbers ### Floating-point numbers
~~~~~~~~~~~~~~~~~~~~~~
Always specify at least one digit for both the integer and fractional part. This Always specify at least one digit for both the integer and fractional part. This
makes it easier to distinguish floating-point numbers from integers, as well as makes it easier to distinguish floating-point numbers from integers, as well as
@ -271,8 +260,7 @@ distinguishing numbers greater than 1 from those lower than 1.
} }
``` ```
Accessing vector members ## Accessing vector members
------------------------
Use `r`, `g`, `b`, and `a` when accessing a vector's members if it Use `r`, `g`, `b`, and `a` when accessing a vector's members if it
contains a color. If the vector contains anything else than a color, use `x`, contains a color. If the vector contains anything else than a color, use `x`,
@ -291,15 +279,13 @@ understand what the underlying data represents.
COLOR.xyz = vec3(5.0, 0.1, 0.2); COLOR.xyz = vec3(5.0, 0.1, 0.2);
``` ```
Naming conventions ## Naming conventions
------------------
These naming conventions follow the Pandemonium Engine style. Breaking these will make These naming conventions follow the Pandemonium Engine style. Breaking these will make
your code clash with the built-in naming conventions, leading to inconsistent your code clash with the built-in naming conventions, leading to inconsistent
code. code.
Functions and variables ### Functions and variables
~~~~~~~~~~~~~~~~~~~~~~~
Use snake\_case to name functions and variables: Use snake\_case to name functions and variables:
@ -309,8 +295,7 @@ Use snake\_case to name functions and variables:
} }
``` ```
Constants ### Constants
~~~~~~~~~
Write constants with CONSTANT\_CASE, that is to say in all caps with an Write constants with CONSTANT\_CASE, that is to say in all caps with an
underscore (\_) to separate words: underscore (\_) to separate words:
@ -319,8 +304,7 @@ underscore (\_) to separate words:
const float GOLDEN_RATIO = 1.618; const float GOLDEN_RATIO = 1.618;
``` ```
Code order ## Code order
----------
We suggest to organize shader code this way: We suggest to organize shader code this way:
@ -349,8 +333,7 @@ This code order follows two rules of thumb:
2. "Public" comes before "private". In a shader language's context, "public" 2. "Public" comes before "private". In a shader language's context, "public"
refers to what's easily adjustable by the user (uniforms). refers to what's easily adjustable by the user (uniforms).
Local variables ### Local variables
~~~~~~~~~~~~~~~
Declare local variables as close as possible to their first use. This makes it Declare local variables as close as possible to their first use. This makes it
easier to follow the code, without having to scroll too much to find where the easier to follow the code, without having to scroll too much to find where the

View File

@ -1,10 +1,8 @@
Advanced post-processing # Advanced post-processing
========================
Introduction ## Introduction
------------
This tutorial describes an advanced method for post-processing in Pandemonium. This tutorial describes an advanced method for post-processing in Pandemonium.
In particular, it will explain how to write a post-processing shader that In particular, it will explain how to write a post-processing shader that
@ -17,8 +15,7 @@ to the main scene. One limitation of this method is that we could not access the
depth buffer because the depth buffer is only available in spatial shaders and depth buffer because the depth buffer is only available in spatial shaders and
Viewports do not maintain depth information. Viewports do not maintain depth information.
Full screen quad ## Full screen quad
----------------
In the `custom post-processing tutorial ( doc_custom_postprocessing )`, we In the `custom post-processing tutorial ( doc_custom_postprocessing )`, we
covered how to use a Viewport to make custom post-processing effects. There are covered how to use a Viewport to make custom post-processing effects. There are
@ -72,8 +69,7 @@ The second option ensures that the quad is visible in the editor, while the firs
option guarantees that it will still be visible even if the camera moves outside the cull margin. option guarantees that it will still be visible even if the camera moves outside the cull margin.
You can also use both options. You can also use both options.
Depth texture ## Depth texture
-------------
To read from the depth texture, perform a texture lookup using `texture()` and To read from the depth texture, perform a texture lookup using `texture()` and
the uniform variable `DEPTH_TEXTURE`. the uniform variable `DEPTH_TEXTURE`.
@ -143,8 +139,7 @@ it needs to be passed to the fragment shader with a varying.
} }
``` ```
An optimization ## An optimization
---------------
You can benefit from using a single large triangle rather than using a full You can benefit from using a single large triangle rather than using a full
screen quad. The reason for this is explained `here ( https://michaldrobot.com/2014/04/01/gcn-execution-patterns-in-full-screen-passes )`. screen quad. The reason for this is explained `here ( https://michaldrobot.com/2014/04/01/gcn-execution-patterns-in-full-screen-passes )`.

View File

@ -1,10 +1,8 @@
Using a Viewport as a texture # Using a Viewport as a texture
=============================
Introduction ## Introduction
------------
This tutorial will introduce you to using the `Viewport` as a This tutorial will introduce you to using the `Viewport` as a
texture that can be applied to 3D objects. In order to do so, it will walk you through the process texture that can be applied to 3D objects. In order to do so, it will walk you through the process
@ -28,8 +26,7 @@ In this tutorial, we'll cover the following topics:
- Fragment shader techniques for procedural planets - Fragment shader techniques for procedural planets
- Setting a Roughness map from a `Viewport Texture` - Setting a Roughness map from a `Viewport Texture`
Setting up the Viewport ## Setting up the Viewport
-----------------------
First, add a `Viewport` to the scene. First, add a `Viewport` to the scene.
@ -74,8 +71,7 @@ The above code renders a gradient like the one below.
Now we have the basics of a `Viewport` that we render to and we have a unique image that we can Now we have the basics of a `Viewport` that we render to and we have a unique image that we can
apply to the sphere. apply to the sphere.
Applying the texture ## Applying the texture
--------------------
MeshInstance > GeometryInstance > Geometry > Material Override > `New SpatialMaterial`: MeshInstance > GeometryInstance > Geometry > Material Override > `New SpatialMaterial`:
@ -105,8 +101,7 @@ problem in 2D map projection. Game developers often have a 2-dimensional map the
onto a sphere, but when it wraps around, it has large seams. There is an elegant workaround for this onto a sphere, but when it wraps around, it has large seams. There is an elegant workaround for this
problem that we will illustrate in the next section. problem that we will illustrate in the next section.
Making the planet texture ## Making the planet texture
-------------------------
So now, when we render to our `Viewport`, it appears magically on the sphere. But there is an ugly So now, when we render to our `Viewport`, it appears magically on the sphere. But there is an ugly
seam created by our texture coordinates. So how do we get a range of coordinates that wrap around seam created by our texture coordinates. So how do we get a range of coordinates that wrap around
@ -199,8 +194,7 @@ Note:
You can see now that the noise indeed wraps seamlessly around the sphere. Although this You can see now that the noise indeed wraps seamlessly around the sphere. Although this
looks nothing like the planet you were promised. So let's move onto something more colorful. looks nothing like the planet you were promised. So let's move onto something more colorful.
Coloring the planet ## Coloring the planet
-------------------
Now to make the planet colors. While there are many ways to do this, for now, we will stick Now to make the planet colors. While there are many ways to do this, for now, we will stick
with a gradient between water and land. with a gradient between water and land.
@ -259,8 +253,7 @@ And with shading turned back on, it looks like:
![](img/planet_noise_fbm_shaded.png) ![](img/planet_noise_fbm_shaded.png)
Making an ocean ## Making an ocean
---------------
One final thing to make this look more like a planet. The ocean and the land reflect light differently. One final thing to make this look more like a planet. The ocean and the land reflect light differently.
So we want the ocean to shine a little more than the land. We can do this by passing a fourth value So we want the ocean to shine a little more than the land. We can do this by passing a fourth value

View File

@ -1,10 +1,7 @@
# Custom post-processing
Custom post-processing ## Introduction
======================
Introduction
------------
Pandemonium provides many post-processing effects out of the box, including Bloom, DOF, and SSAO. Sometimes you Pandemonium provides many post-processing effects out of the box, including Bloom, DOF, and SSAO. Sometimes you
want to write your own custom effect. Here's how you can do so. want to write your own custom effect. Here's how you can do so.
@ -19,13 +16,11 @@ Tutorial ( doc_screen-reading_shaders )` first.
Note: Note:
As of the time of writing, Pandemonium does not support rendering to multiple buffers at the same time. Your As of the time of writing, Pandemonium does not support rendering to multiple buffers at the same time. Your
post-processing shader will not have access to normals or other render passes. You only have post-processing shader will not have access to normals or other render passes. You only have
access to the rendered frame. access to the rendered frame.
Single pass post-processing ## Single pass post-processing
---------------------------
You will need a `Viewport` to render your scene to, and a scene to render your You will need a `Viewport` to render your scene to, and a scene to render your
`Viewport` on the screen. You can use a `ViewportContainer `Viewport` on the screen. You can use a `ViewportContainer
@ -34,7 +29,6 @@ another `Control` node.
Note: Note:
Rendering using a `Viewport` gives you control over Rendering using a `Viewport` gives you control over
how the scene render, including the framerate, and you can use the how the scene render, including the framerate, and you can use the
`ViewportContainer` to render 3D objects in a 2D scene. `ViewportContainer` to render 3D objects in a 2D scene.
@ -54,7 +48,6 @@ shader resource to it. You can access your rendered `Viewport` with the built-in
Note: Note:
You can choose not to use a `ViewportContainer`, but if you do so, you will You can choose not to use a `ViewportContainer`, but if you do so, you will
need to create your own uniform in the shader and pass the `Viewport` texture in need to create your own uniform in the shader and pass the `Viewport` texture in
manually, like so: manually, like so:
@ -62,7 +55,7 @@ Note:
``` ```
// Inside the Shader. // Inside the Shader.
uniform sampler2D ViewportTexture; uniform sampler2D ViewportTexture;
``` ```
And you can pass the texture into the shader from GDScript like so: And you can pass the texture into the shader from GDScript like so:
@ -70,7 +63,7 @@ Note:
# In GDScript. # In GDScript.
func _ready(): func _ready():
$Sprite.material.set_shader_param("ViewportTexture", $Viewport.get_texture()) $Sprite.material.set_shader_param("ViewportTexture", $Viewport.get_texture())
``` ```
Copy the following code to your shader. The above code is a single pass edge detection filter, a Copy the following code to your shader. The above code is a single pass edge detection filter, a
`Sobel filter ( https://en.wikipedia.org/wiki/Sobel_operator )`. `Sobel filter ( https://en.wikipedia.org/wiki/Sobel_operator )`.
@ -94,7 +87,6 @@ Copy the following code to your shader. The above code is a single pass edge det
Note: Note:
The Sobel filter reads pixels in a 9x9 grid around the current pixel and adds them together, using weight. The Sobel filter reads pixels in a 9x9 grid around the current pixel and adds them together, using weight.
What makes it interesting is that it assigns weights to each pixel; +1 for each of the eight around the What makes it interesting is that it assigns weights to each pixel; +1 for each of the eight around the
center and -8 for the center pixel. The choice of weights is called a "kernel". You can use different center and -8 for the center pixel. The choice of weights is called a "kernel". You can use different
@ -102,8 +94,7 @@ Note:
![](img/post_outline.png) ![](img/post_outline.png)
Multi-pass post-processing ## Multi-pass post-processing
--------------------------
Some post-processing effects like blur are resource intensive. If you break them down in multiple passes Some post-processing effects like blur are resource intensive. If you break them down in multiple passes
however, you can make them run a lot faster. In a multipass material, each pass takes the result from the however, you can make them run a lot faster. In a multipass material, each pass takes the result from the
@ -124,7 +115,6 @@ the tree.
Note: Note:
You can also render your Viewports separately without nesting them like this. You just You can also render your Viewports separately without nesting them like this. You just
need to use two Viewports and to render them one after the other. need to use two Viewports and to render them one after the other.

View File

@ -1,7 +1,6 @@
Making trees # Making trees
============
This is a short tutorial on how to make trees and other types of vegetation from scratch. This is a short tutorial on how to make trees and other types of vegetation from scratch.
@ -9,8 +8,7 @@ The aim is to not focus on the modelling techniques (there are plenty of tutoria
![](img/tree_sway.gif) ![](img/tree_sway.gif)
Start with a tree ## Start with a tree
-----------------
I took this tree from SketchFab: I took this tree from SketchFab:
@ -20,8 +18,7 @@ https://sketchfab.com/models/ea5e6ed7f9d6445ba69589d503e8cebf
and opened it in Blender. and opened it in Blender.
Paint with vertex colors ## Paint with vertex colors
------------------------
The first thing you may want to do is to use the vertex colors to paint how much the tree will sway when there is wind. Just use the vertex color painting tool of your favorite 3D modelling program and paint something like this: The first thing you may want to do is to use the vertex colors to paint how much the tree will sway when there is wind. Just use the vertex color painting tool of your favorite 3D modelling program and paint something like this:
@ -31,8 +28,7 @@ This is a bit exaggerated, but the idea is that color indicates how much sway af
![](img/tree_gradient.png) ![](img/tree_gradient.png)
Write a custom shader for the leaves ## Write a custom shader for the leaves
------------------------------------
This is a simple example of a shader for leaves: This is a simple example of a shader for leaves:
@ -84,8 +80,7 @@ And this is pretty much it.
The trunk shader is similar, except it does not write to the alpha channel (thus no alpha prepass is needed) and does not require transmission to work. Both shaders can be improved by adding normal mapping, AO and other maps. The trunk shader is similar, except it does not write to the alpha channel (thus no alpha prepass is needed) and does not require transmission to work. Both shaders can be improved by adding normal mapping, AO and other maps.
Improving the shader ## Improving the shader
--------------------
There are many more resources on how to do this that you can read. Now that you know the basics, a recommended read is the chapter from GPU Gems3 about how Crysis does this There are many more resources on how to do this that you can read. Now that you know the basics, a recommended read is the chapter from GPU Gems3 about how Crysis does this
(focus mostly on the sway code, as many other techniques shown there are obsolete): (focus mostly on the sway code, as many other techniques shown there are obsolete):

View File

@ -1,10 +0,0 @@
Shading reference
=================
.. toctree::
:maxdepth: 1
:name: toc-shading-reference
shading_language
spatial_shader
canvas_item_shader