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
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
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
officially supported are:
@ -55,8 +52,7 @@ Note:
they are a licensed console developer. Doing so would violate the console
manufacturer's NDA.
Third-party support
-------------------
## Third-party support
Console ports of Pandemonium are offered by third-party companies (which have
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:
The general `doc_3d_rendering_limitations` also apply to mobile platforms.
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:
+---------------------------------------------------------------------------+-----------------+--------------------+
| Setting | Desktop default | Mobile default |
+---------------------------------------------------------------------------+-----------------+--------------------+
| Setting | Desktop default | Mobile default |
|-------------------------------------------------------------------------|-----------------|--------------------|
| `rendering/quality/directional_shadow/size` | 4096 | 2048 |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/intended_usage/framebuffer_allocation` | 3D | 3D Without Effects |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `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/shading/force_lambert_over_burley` | `false` | `true` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/shading/force_vertex_shading` | `false` | `true` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `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/shading/force_lambert_over_burley` | `false` | `true` |
| `rendering/quality/shading/force_vertex_shading` | `false` | `true` |
| `rendering/quality/shadow_atlas/size` | 4096 | 2048 |
+---------------------------------------------------------------------------+-----------------+--------------------+
| `rendering/quality/shadows/filter_mode` | PCF5 | Disabled |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/gles3/shaders/max_simultaneous_compiles` | 2 | 1 |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/gles3/shaders/shader_cache_size_mb` | 512 | 128 |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/quality/depth/hdr` | `true` | `false` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/quality/reflections/texture_array_reflections` | `true` | `false` |
+---------------------------------------------------------------------------+-----------------+--------------------+
| *GLES3 only:* `rendering/quality/depth/hdr` | `true` | `false` |
| *GLES3 only:* `rendering/quality/reflections/texture_array_reflections` | `true` | `false` |
See the `ProjectSettings class documentation`
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)
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 include a specifically configured `<meta-data )` tag in its manifest file.
- 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 `&lt;meta-data&gt;` tag in its manifest file.
#### 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:
- 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
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.
@ -63,8 +63,8 @@ The instructions below assumes that you're using Android Studio.
4. Update the plugin `AndroidManifest.xml` file:
- Open the plugin `AndroidManifest.xml` file.
- Add the `<application></application )` tag if it's missing.
- In the `<application )` tag, add a `<meta-data )` tag setup as follow:
- Add the `&lt;application>&lt;/application&gt;` tag if it's missing.
- In the `&lt;application&gt;` tag, add a `&lt;meta-data&gt;` tag setup as follow:
```
<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
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>
```
Setup
-----
## Setup
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.
The only required placeholders are:
- `$PANDEMONIUM_URL`:
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.
- `$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.
- `$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.
- `$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
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.
@ -74,8 +72,8 @@ section.
![](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
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).
@ -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
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`
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.
```
@ -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.
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
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,
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
(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.
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
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.
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
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.
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
`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
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

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
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
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
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 )`.
Static Methods
^^^^^^^^^^^^^^
#### Static Methods
+---------+-----------------------------------------------------------------------------------------------+
| Promise | :js:attr:`load <Engine.load )` **(** string basePath **)** |
+---------+-----------------------------------------------------------------------------------------------+
| void | :js:attr:`unload <Engine.unload )` **(** **)** |
+---------+-----------------------------------------------------------------------------------------------+
| boolean | :js:attr:`isWebGLAvailable <Engine.isWebGLAvailable )` **(** *[ number majorVersion=1 ]* **)** |
+---------+-----------------------------------------------------------------------------------------------+
| | |
|---------|------------------------------------------------------------------------------------------------|
| Promise | :js:attr:`load ( Engine.load )` **(** string basePath **)** |
| void | :js:attr:`unload ( Engine.unload )` **(** **)** |
| boolean | :js:attr:`isWebGLAvailable ( Engine.isWebGLAvailable )` **(** *[ number majorVersion=1 ]* **)** |
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:`start <Engine.prototype.start )` **(** 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:`requestQuit <Engine.prototype.requestQuit )` **(** **)** |
+---------+---------------------------------------------------------------------------------------------------------------+
#### 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:`start ( Engine.prototype.start )` **(** 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:`requestQuit ( Engine.prototype.requestQuit )` **(** **)** |
.. js:class:: Engine( initConfig )
@ -123,9 +113,9 @@ Instance Methods
.. js:function:: prototype.start( override )
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.
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).
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.
@ -174,42 +164,28 @@ Instance Methods
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.
Engine configuration
--------------------
## Engine configuration
An object used to configure the Engine instance based on pandemonium export options, and to override those in custom HTML
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
@ -285,9 +261,9 @@ Properties
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: `[]`
@ -300,7 +276,7 @@ Properties
:param string path:
The path that Pandemonium's wants executed.
:param Array.<string> args:
:param Array.&lt;string&gt; args:
The arguments of the "command" to execute.
.. 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
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
what to do with the resulting texture.
Input
-----
## Input
`Viewports` are also responsible for delivering properly adjusted and
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 )`.
Listener
--------
## Listener
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
@ -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
to enable this!
Cameras (2D & 3D)
-----------------
## Cameras (2D & 3D)
When using a `Camera` /
`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`
property to restrict which objects are rendered.
Scale & stretching
------------------
## Scale & stretching
`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
settings. For more information on scaling and stretching visit the `Multiple Resolutions Tutorial ( doc_multiple_resolutions )`
Worlds
------
## Worlds
For 3D, a `Viewport`. This
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.
Capture
-------
## Capture
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
@ -159,8 +151,7 @@ it using (for example):
# 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:
@ -170,8 +161,7 @@ The `Viewport` completely
if `Stretch( viewportcontainer_property_stretch )` is set to `true` in `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
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.
Render target
-------------
## Render target
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.

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
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.
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
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.
Base size
---------
## Base size
A base size for the window can be specified in the Project Settings under
**Display → Window**.
@ -85,8 +81,7 @@ Note:
out of a game much slower since the monitor has to change resolutions every
time this is done.
Resizing
--------
## Resizing
There are several types of devices, with several types of screens, which
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
project settings to handle multiple resolutions.
Stretch settings
----------------
## Stretch settings
Stretch settings are located in the project settings and provide several options:
![](img/stretchsettings.png)
Stretch Mode
^^^^^^^^^^^^
#### Stretch Mode
The **Stretch Mode** setting defines how the base size is stretched to fit
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)
Stretch Aspect
^^^^^^^^^^^^^^
#### Stretch Aspect
The second setting is the stretch aspect. Note that this only takes effect if
**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,
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
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
by rendering them at a lower resolution.
From scripts
^^^^^^^^^^^^
#### From scripts
To configure stretching at runtime from a script, use the
`get_tree().set_screen_stretch()` method (see
`SceneTree.set_screen_stretch()`).
Common use case scenarios
-------------------------
## Common use case scenarios
The following settings are recommended to support multiple resolutions and aspect
ratios well.
Desktop game
^^^^^^^^^^^^
#### Desktop game
**Non-pixel art:**
@ -307,8 +295,7 @@ Note:
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 )`.
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
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).
- 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`.
- 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).
- 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.
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
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.
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
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
mobile devices.
Handling aspect ratios
----------------------
## Handling aspect ratios
Once scaling for different resolutions is accounted for, make sure that
your *user interface* also scales for different aspect ratios. This can be
done using `anchors ( doc_size_and_anchors )` and/or `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**
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
*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
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,
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.
Distinguishing between them
---------------------------
## Distinguishing between them
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)
Jitter
------
## Jitter
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.
@ -47,8 +43,7 @@ Note:
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.
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
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.
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
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.
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.
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
developers.
macOS
^^^^^
#### macOS
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.
Android
^^^^^^^
#### Android
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.
iOS
^^^
#### iOS
iOS devices are generally stutter-free, but older devices running newer versions of the operating system may exhibit problems.
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
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
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 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.
Managing groups
---------------
## Managing groups
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.
@ -26,8 +24,7 @@ There are two ways to add/remove nodes to groups:
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
Node dock.
@ -68,8 +65,7 @@ Note:
in a different scene and you cannot edit it here. This happens on
scene instances in particular.
Using code
~~~~~~~~~~
### Using code
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

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
instantiate scenes from code.
Getting nodes
-------------
## Getting nodes
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
@ -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)
Node paths
----------
## Node paths
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
@ -72,8 +69,7 @@ Note:
slash to make it absolute, in which case your topmost node would be
"/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
`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
```
Creating nodes
--------------
## Creating nodes
To create a node from code, call its `new()` method like for any other
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
node.
Instancing scenes
-----------------
## Instancing scenes
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
@ -164,7 +158,7 @@ gdscript GDScript
```
var scene = preload("res://MyScene.tscn")
```
```
At that point, `scene` is a packed scene resource, not a node. To create the
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
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
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

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.
This means a single project can define nodes in both C# and GDScript.
@ -33,14 +32,12 @@ gdscript GDScript
print(msg)
```
Instantiating nodes
-------------------
## Instantiating nodes
If you're not using nodes from the scene tree, you'll probably want to
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
(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
`.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
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
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
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
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
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.
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
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
```
Calling GDScript methods from C#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Calling GDScript methods from C#
To call GDScript methods from C# you'll need to use
`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
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
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
`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
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.
Editor-defined templates
~~~~~~~~~~~~~~~~~~~~~~~~
### Editor-defined templates
These are available globally throughout any project. The location of these
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
templates in case you've accidentally overwritten them.
Project-defined templates
~~~~~~~~~~~~~~~~~~~~~~~~~
### Project-defined templates
The default path to search for templates is the
`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
ignored.
Language support and overriding behavior
----------------------------------------
## Language support and overriding behavior
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
@ -60,8 +55,7 @@ Note:
The built-in editor templates are automatically shadowed by the project-specific
templates given both scripts have the same filename.
Default template
----------------
## Default template
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
@ -89,45 +83,37 @@ gdscript GDScript
# pass
```
List of template placeholders
-----------------------------
## List of template placeholders
The following describes the complete list of built-in template placeholders
which are currently implemented.
Base placeholders
~~~~~~~~~~~~~~~~~
### Base placeholders
+-------------+----------------------------------------------------------------+
| Placeholder | Description |
+=============+================================================================+
| `%CLASS%` | The name of the new class (used in C# only). |
+-------------+----------------------------------------------------------------+
| `%BASE%` | The base type a new script inherits from. |
+-------------+----------------------------------------------------------------+
| `%TS%` | Indentation placeholder. The exact type and number of |
|-------------|----------------------------------------------------------------|
| `%CLASS%` | The name of the new class (used in C# only). |
| `%BASE%` | The base type a new script inherits from. |
| `%TS%` | Indentation placeholder. The exact type and number of |
| | whitespace characters used for indentation is determined by |
| | the `text_editor/indent/type` and `text_editor/indent/size`|
| | settings in the `EditorSettings` |
| | the `text_editor/indent/type` and `text_editor/indent/size` |
| | settings in the `EditorSettings` |
| | respectively. |
+-------------+----------------------------------------------------------------+
Type placeholders
~~~~~~~~~~~~~~~~~
### Type placeholders
These are only relevant for GDScript with static typing. Whether these
placeholders are actually replaced is determined by the
`text_editor/completion/add_type_hints` setting in the
`EditorSettings`.
+-------------------+--------------+
| Placeholder | Value |
+===================+==============+
| `%INT_TYPE%` | `: int` |
+-------------------+--------------+
| `%STRING_TYPE%` | `: String` |
+-------------------+--------------+
| `%FLOAT_TYPE%` | `: float` |
+-------------------+--------------+
| `%VOID_RETURN%` | `-> void` |
+-------------------+--------------+
|-------------------|--------------|
| `%INT_TYPE%` | `: int` |
| `%STRING_TYPE%` | `: String` |
| `%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.
@ -19,8 +18,7 @@ Note:
The Expression class is independent from GDScript.
It's available even if you compile Pandemonium with the GDScript module disabled.
Basic usage
-----------
## Basic usage
To evaluate a mathematical expression, use:
@ -33,22 +31,18 @@ To evaluate a mathematical expression, use:
The following operators are available:
+------------------------+-------------------------------------------------------------------------------------+
| Operator | Notes |
+========================+=====================================================================================+
| Addition `+` | Can also be used to concatenate strings and arrays: |
| | - `"hello" + " world"` = `hello world` |
| | - `[1, 2] + [3, 4]` = `[1, 2, 3, 4]` |
+------------------------+-------------------------------------------------------------------------------------+
| Subtraction (`-`) | |
+------------------------+-------------------------------------------------------------------------------------+
| Multiplication (`*`) | |
+------------------------+-------------------------------------------------------------------------------------+
| Division (`/`) | Performs and integer division if both operands are integers. |
|------------------------|-------------------------------------------------------------------------------------|
| Addition `+` | Can also be used to concatenate strings and arrays: |
| | - `"hello" + " world"` = `hello world` |
| | - `[1, 2] + [3, 4]` = `[1, 2, 3, 4]` |
| Subtraction (`-`) | |
| 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. |
+------------------------+-------------------------------------------------------------------------------------+
| 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
`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
```
Passing variables to an expression
----------------------------------
## Passing variables to an expression
You can pass variables to an expression. These variables will then
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,
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
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
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:
@ -209,8 +200,7 @@ The output from the script will be:
0
```
Built-in functions
------------------
## Built-in functions
Most methods available in the `@GDScript` scope are available in the
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.
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.
1. **We can delete the existing scene.**
`SceneTree.change_scene()` and
`SceneTree.change_scene_to()`
`SceneTree.change_scene()` and `SceneTree.change_scene_to()`
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
`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
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.
Shooting example
----------------
## Shooting example
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

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
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
Pandemonium.
How pausing works
-----------------
## How pausing works
To pause the game the pause state must be set. This is done by assigning
`true` to the `SceneTree.paused` property:
@ -32,8 +29,7 @@ Note:
The physics servers can be made active while the game is
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
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
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
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 well-designed file system also allows multiple developers to edit the
same source files and assets while collaborating. Pandemonium stores
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
PNG image is a resource to the engine. If a resource contains properties
@ -32,12 +29,11 @@ Example of file system contents:
/project.pandemonium
/enemy/enemy.tscn
/enemy/enemy.gd
/enemy/enemysprite.png)
/enemy/enemysprite.png
/player/player.gd
```
project.pandemonium
-------------
## project.pandemonium
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
@ -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
a blank project.
Path delimiter
--------------
## Path delimiter
Pandemonium only supports `/` as a path delimiter. This is done for
portability reasons. All operating systems support this, even Windows,
so a path such as `C:\project\project.pandemonium` needs to be typed as
`C:/project/project.pandemonium`.
Resource path
-------------
## Resource path
When accessing resources, using the host OS file system layout can be
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
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
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
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
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
tools in Pandemonium.
Drawbacks
---------
## Drawbacks
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
@ -102,8 +93,8 @@ to be fixed manually (Pandemonium detects this and helps you fix them anyway, bu
go the hard route?).
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)`,
but then references it as `myfile.png)`, it will work fine on their platform, but not
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
on other platforms, such as Linux, Android, etc. This may also apply to exported binaries,
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`
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`
or an `.scn` file), an image, a script... Here are some `Resource` examples:
`Texture`, `Mesh
( Mesh )`, `Animation`, `AudioStream
( AudioStream )`, `Font`, `Translation
( Translation )`.
`Texture`, `Mesh( Mesh )`, `Animation`, `AudioStream( AudioStream )`, `Font`,
`Translation( Translation )`.
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
@ -35,8 +31,7 @@ resources as properties:
![](img/nodes_resources.png)
External vs built-in
--------------------
## External vs built-in
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:
Even if you save a built-in resource, when you instance a scene multiple
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:
@ -92,8 +85,7 @@ gdscript GDScript
get_node("sprite").texture = res
```
Loading scenes
--------------
## Loading scenes
Scenes are also resources, but there is a catch. Scenes saved to disk are
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
scene instances.
Freeing resources
-----------------
## Freeing resources
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,
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
inherit the ability to freely translate between object properties and serialized
@ -272,4 +262,4 @@ Warning:
# This will NOT serialize the 'value' property.
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
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:
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.
Tip:
If you're creating an autoload as part of an editor plugin, consider
`registering it automatically in the Project Settings ( doc_making_plugins_autoload )`
when the plugin is enabled.
AutoLoad
--------
## AutoLoad
You can create an AutoLoad to load a scene or a script that inherits from
`Node`.
Note:
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
other scenes are loaded.
@ -106,8 +100,7 @@ Warning:
Autoloads must **not** be removed using `free()` or `queue_free()` at
runtime, or the engine will crash.
Custom scene switcher
---------------------
## Custom scene switcher
This tutorial will demonstrate building a scene switcher using autoloads.
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.
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
scene contains a label displaying the scene name and a button with its
`pressed()` signal connected. When you run the project, it starts in
`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`.
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
nodes. Scenes are collections of nodes. They become active once
they enter the *scene tree*.
MainLoop
--------
## MainLoop
The way Pandemonium works internally is as follows. There is the
`OS` class,
@ -29,8 +26,7 @@ methods, for initialization, idle (frame-synchronized callback), fixed
(physics-synchronized callback), and input. Again, this is low
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
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
`Node.get_tree()`.
Root viewport
-------------
## Root viewport
The root `Viewport`
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
user. It's created automatically inside SceneTree.
Scene tree
----------
## Scene tree
When a node is connected, directly or indirectly, to the root
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
*scene tree*, they lose these abilities.
Tree order
----------
## Tree order
Most node operations in Pandemonium, such as drawing 2D, processing, or getting
notifications are done in tree order. This means that parents and
@ -108,25 +101,23 @@ the current node.
![](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.
#. The root node of that scene (only one root, remember?) is added as
1. A scene is loaded from disk or created by scripting.
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
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
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
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
bottom-to-top order
Changing current scene
----------------------
## Changing current scene
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

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
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
its path is changed.
Creating and using them
-----------------------
## Creating and using them
In the Scene tree dock, right-click on a node and select
**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
engine.
@ -14,14 +13,12 @@ in the running game.
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.
Debugger Panel
--------------
## Debugger Panel
Many of Pandemonium's debugging tools are part of the Debugger panel, which you can
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
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:
Deploy with Remote Debug
++++++++++++++++++++++++
#### Deploy with Remote Debug
When exporting and deploying, the resulting executable will attempt to connect
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.
@ -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.
Visible Collision Shapes
++++++++++++++++++++++++
#### Visible Collision Shapes
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.
Sync Scene Changes
++++++++++++++++++
#### Sync Scene Changes
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
with the network filesystem.
Sync Script Changes
+++++++++++++++++++
#### Sync Script Changes
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.
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
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 )`.
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
which control different things.
Settings
++++++++
#### Settings
These are some general settings such as printing the current FPS
to the **Output** panel, the maximum amount of functions when profiling
and others.
GDScript
++++++++
#### GDScript
These settings allow you to toggle specific GDScript warnings, such as for
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
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**
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
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.
Debugger
++++++++
#### Debugger
The Debugger tab opens automatically when the GDScript compiler reaches
a breakpoint in your code.
@ -39,15 +37,13 @@ Warning:
`running in a thread ( doc_using_multiple_threads )`.
This is a current limitation of the GDScript debugger.
Errors
++++++
#### Errors
This is where error and warning messages are printed while running the game.
You can disable specific warnings in **Project Settings > Debug > GDScript**.
Profiler
++++++++
#### Profiler
The debugger comes with three profilers for your processor, network operations,
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
from the graph.
Network Profiler
++++++++++++++++
#### Network Profiler
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
outgoing network interactions. It also features a bandwidth meter that displays
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
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
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.
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)
Misc
++++
#### Misc
The **Misc** tab contains tools to identify the control nodes you are clicking
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
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
flexibility for content creation and integration.
History
~~~~~~~
### History
Note:
@ -22,8 +19,7 @@ Note:
Documentation about GDScript's history has been moved to the
`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
here's a simple example of how GDScript looks.
@ -107,28 +103,26 @@ here's a simple example of how GDScript looks.
print("Constructed!")
var lv = Something.new()
print(lv.a)
```
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
read this tutorial: `doc_gdscript_more_efficiently`.
Language
--------
## Language
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
the linked class descriptions.
Identifiers
~~~~~~~~~~~
### Identifiers
Any string that restricts itself to alphabetic characters (`a` to
`z` and `A` to `Z`), digits (`0` to `9`) and `` qualifies
as an identifier. Additionally, identifiers must not begin with a digit.
Identifiers are case-sensitive (`foo` is different from `FOO`).
Keywords
~~~~~~~~
### Keywords
The following is the list of keywords supported by the language. Since
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 )`
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.
+------------------------------------------------------------------------+-----------------------------------------+
| **Operator** | **Description** |
+------------------------------------------------------------------------+-----------------------------------------+
| `x[index]` | Subscription (highest priority) |
+------------------------------------------------------------------------+-----------------------------------------+
| `x.attribute` | Attribute reference |
+------------------------------------------------------------------------+-----------------------------------------+
| `foo()` | Function call |
+------------------------------------------------------------------------+-----------------------------------------+
| `is` | Instance type checker |
+------------------------------------------------------------------------+-----------------------------------------+
| `~` | Bitwise NOT |
+------------------------------------------------------------------------+-----------------------------------------+
| `-x` | Negative / Unary negation |
+------------------------------------------------------------------------+-----------------------------------------+
| `*` `/` `%` | Multiplication / Division / Remainder |
|------------------------------------------------------------------------|-----------------------------------------|
| `x[index]` | Subscription (highest priority) |
| `x.attribute` | Attribute reference |
| `foo()` | Function call |
| `is` | Instance type checker |
| `~` | Bitwise NOT |
| `-x` | Negative / Unary negation |
| `*` `/` `%` | Multiplication / Division / Remainder |
| | |
| | These operators have the same behavior |
| | 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), |
| | and is additionally used for Format |
| | Strings |
+------------------------------------------------------------------------+-----------------------------------------+
| `+` | Addition / Concatenation of arrays |
+------------------------------------------------------------------------+-----------------------------------------+
| `-` | Subtraction |
+------------------------------------------------------------------------+-----------------------------------------+
| `<<` `> )` | Bit shifting |
+------------------------------------------------------------------------+-----------------------------------------+
| `&` | Bitwise AND |
+------------------------------------------------------------------------+-----------------------------------------+
| `^` | Bitwise XOR |
+------------------------------------------------------------------------+-----------------------------------------+
| `|` | Bitwise OR |
+------------------------------------------------------------------------+-----------------------------------------+
| `<` ` )` `==` `!=` `>=` `<=` | Comparisons |
+------------------------------------------------------------------------+-----------------------------------------+
| `in` | When used with the `if` keyword it |
| `+` | Addition / Concatenation of arrays |
| `-` | Subtraction |
| `&lt;&lt;` `&gt; )` | Bit shifting |
| `&` | Bitwise AND |
| `^` | Bitwise XOR |
| `|` | Bitwise OR |
| `&lt;` ` )` `==` `!=` `&gt;=` `&lt;=` | Comparisons |
| `in` | When used with the `if` keyword it |
| | checks if a value is within a string, |
| | 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 |
| | string, list, range, dictionary or node.|
+------------------------------------------------------------------------+-----------------------------------------+
| `!` `not` | Boolean NOT |
+------------------------------------------------------------------------+-----------------------------------------+
| `and` `&&` | Boolean AND |
+------------------------------------------------------------------------+-----------------------------------------+
| `or` `||` | Boolean OR |
+------------------------------------------------------------------------+-----------------------------------------+
| `if x else` | Ternary if/else |
+------------------------------------------------------------------------+-----------------------------------------+
| `as` | Type casting |
+------------------------------------------------------------------------+-----------------------------------------+
| `=` `+=` `-=` `*=` `/=` `%=` `&=` `|=` `<<=` `>>=` | Assignment (lowest priority) |
+------------------------------------------------------------------------+-----------------------------------------+
| `!` `not` | Boolean NOT |
| `and` `&&` | Boolean AND |
| `or` `||` | Boolean OR |
| `if x else` | Ternary if/else |
| `as` | Type casting |
| `=` `+=` `-=` `*=` `/=` `%=` `&=` `|=` `&lt;&lt;=` `&gt;&gt;=` | Assignment (lowest priority) |
Literals
~~~~~~~~
+--------------------------+----------------------------------------+
### Literals
| **Literal** | **Type** |
+--------------------------+----------------------------------------+
| `45` | Base 10 integer |
+--------------------------+----------------------------------------+
| `0x8f51` | Base 16 (hexadecimal) integer |
+--------------------------+----------------------------------------+
| `0b101010` | Base 2 (binary) integer |
+--------------------------+----------------------------------------+
| `3.14`, `58.1e-10` | Floating-point number (real) |
+--------------------------+----------------------------------------+
| `"Hello"`, `"Hi"` | Strings |
+--------------------------+----------------------------------------+
| `"""Hello"""` | Multiline string |
+--------------------------+----------------------------------------+
| `@"Node/Label"` | `NodePath` or StringName |
+--------------------------+----------------------------------------+
| `$NodePath` | Shorthand for `get_node("NodePath")` |
+--------------------------+----------------------------------------+
|--------------------------|----------------------------------------|
| `45` | Base 10 integer |
| `0x8f51` | Base 16 (hexadecimal) integer |
| `0b101010` | Base 2 (binary) integer |
| `3.14`, `58.1e-10` | Floating-point number (real) |
| `"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
```
12_345_678 # Equal to 12345678.
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.
```
Comments
~~~~~~~~
### Comments
Anything from a `#` to the end of the line is ignored and is
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
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
passed as values.)
Basic built-in types
~~~~~~~~~~~~~~~~~~~~
### Basic 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
be assigned any other value.
`bool`
^^^^^^^^^^^^^^^^^^^^^^^^
#### `bool`
Short for "boolean", it can only contain `true` or `false`.
`int`
^^^^^^^^^^^^^^^^^^^^^^
#### `int`
Short for "integer", it stores whole numbers (positive and negative).
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.
It is stored as a 64-bit value, equivalent to "double" in C++.
Note: Currently, data structures such as Vector2, Vector3, and
PoolRealArray store 32-bit single-precision "float" values.
`String`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `String`
A sequence of characters in `Unicode format ( https://en.wikipedia.org/wiki/Unicode )`.
Strings can contain the following escape sequences:
+---------------------+---------------------------------+
| **Escape sequence** | **Expands to** |
+---------------------+---------------------------------+
| `\n` | Newline (line feed) |
+---------------------+---------------------------------+
| `\t` | Horizontal tab character |
+---------------------+---------------------------------+
| `\r` | Carriage return |
+---------------------+---------------------------------+
| `\a` | Alert (beep/bell) |
+---------------------+---------------------------------+
| `\b` | Backspace |
+---------------------+---------------------------------+
| `\f` | Formfeed page break |
+---------------------+---------------------------------+
| `\v` | Vertical tab character |
+---------------------+---------------------------------+
| `\"` | Double quote |
+---------------------+---------------------------------+
| `\'` | Single quote |
+---------------------+---------------------------------+
| `\\` | Backslash |
+---------------------+---------------------------------+
| `\uXXXX` | Unicode codepoint `XXXX` |
|---------------------|---------------------------------|
| `\n` | Newline (line feed) |
| `\t` | Horizontal tab character |
| `\r` | Carriage return |
| `\a` | Alert (beep/bell) |
| `\b` | Backspace |
| `\f` | Formfeed page break |
| `\v` | Vertical tab character |
| `\"` | Double quote |
| `\'` | Single quote |
| `\\ ` | Backslash |
| `\uXXXX` | Unicode codepoint `XXXX` |
| | (hexadecimal, case-insensitive) |
+---------------------+---------------------------------+
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
accessed as an array.
`Rect2`
^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Rect2`
2D Rectangle type containing two vectors fields: `position` and `size`.
Also contains an `end` field which is `position + size`.
`Vector3`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Vector3`
3D vector type containing `x`, `y` and `z` fields. This can also
be accessed as an array.
`Transform2D`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Transform2D`
3×2 matrix used for 2D transforms.
`Plane`
^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Plane`
3D Plane type in normalized form that contains a `normal` vector field
and a `d` scalar distance.
`Quat`
^^^^^^^^^^^^^^^^^^^^^^^^
#### `Quat`
Quaternion is a datatype used for representing a 3D rotation. It's
useful for interpolating rotations.
`AABB`
^^^^^^^^^^^^^^^^^^^^^^^^
#### `AABB`
Axis-aligned bounding box (or 3D box) contains 2 vectors fields: `position`
and `size`. Also contains an `end` field which is
`position + size`.
`Basis`
^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Basis`
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
vectors.
`Transform`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Transform`
3D Transform contains a Basis field `basis` and a Vector3 field
`origin`.
Engine built-in types
~~~~~~~~~~~~~~~~~~~~~
### Engine built-in types
`Color`
^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Color`
Color data type contains `r`, `g`, `b`, and `a` fields. It can
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
easily assigned to, and from, a String.
`RID`
^^^^^^^^^^^^^^^^^^^^^^
#### `RID`
Resource ID (RID). Servers use generic RIDs to reference opaque data.
`Object`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Object`
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).
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.
- `PoolColorArray` objects.
`Dictionary`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
#### `Dictionary`
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
assign to it
```
var d = {} # Create an empty Dictionary.
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
`Object.set()` methods instead.
Data
----
## Data
Variables
~~~~~~~~~
### Variables
Variables can exist as class members or local to functions. They are
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
it's possible to omit the type name
```
var my_vector2 := Vector2() # 'my_vector2' is of type 'Vector2'.
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).
- Script classes declared with the `name` keyword.
Casting
^^^^^^^
#### Casting
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
@ -665,6 +553,7 @@ engine will raise an error.
Casting is also useful to have better type-safe variables when interacting with
the scene tree
```
# Will infer the variable to be of type Sprite.
var my_sprite := $Character as Sprite
@ -673,8 +562,7 @@ the scene tree
($AnimPlayer as AnimationPlayer).play("walk")
```
Constants
~~~~~~~~~
### Constants
Constants are values you cannot change when the game is running.
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
possible to add explicit type specification
```
const A: int = 5
const B: Vector2 = Vector2()
@ -711,8 +600,7 @@ Note:
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.
Enums
^^^^^
#### Enums
Enums are basically a shorthand for constants, and are pretty useful if you
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
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
@ -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
value. Types for arguments can be added in a similar way to variables
```
func my_function(a: int, b: String):
pass
If a function argument has a default value, it's possible to infer the type
```
func my_function(int_arg := 42, String_arg := "string"):
pass
The return type of the function can be specified after the arguments list using
the arrow token (`- )`)
```
func my_int_function() -> int:
return 0
@ -788,6 +678,7 @@ return early with the `return` keyword, but they can't return any value.
```
Note:
Non-void functions must **always** return a value, so if your code has
branching statements (such as an `if`/`else` construct), all the
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
valid value to return.
Referencing functions
^^^^^^^^^^^^^^^^^^^^^
#### Referencing functions
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
@ -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
pass it to another function as an argument) one must use the `call` or
`funcref` helpers
```
# Call a function by name in one step.
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
access to the instance member variables or `self`. This is mainly
useful to make libraries of helper functions
```
static func sum2(a, b):
return a + b
```
Statements and control flow
~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Statements and control flow
Statements are standard and can be assignments, function calls, control
flow structures, etc (see below). `;` as a statement separator is
entirely optional.
if/else/elif
^^^^^^^^^^^^
#### if/else/elif
Simple conditions are created by using the `if`/`else`/`elif` syntax.
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!")
```
while
^^^^^
#### while
Simple loops are created by using `while` syntax. Loops can be broken
using `break` or continued using `continue`:
@ -915,8 +803,7 @@ using `break` or continued using `continue`:
statement(s)
```
for
^^^
#### for
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
@ -951,8 +838,7 @@ in the loop variable.
statement # Similar to range(ceil(2.2))
```
match
^^^^^
#### match
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.
@ -1102,8 +988,7 @@ There are 6 pattern types:
print("Yep, you've taken damage")
```
Classes
~~~~~~~
### Classes
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
@ -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
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
knowing.
Inheritance
^^^^^^^^^^^
#### Inheritance
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.
Inheritance uses the `extends` keyword
```
# Inherit/extend a globally available class.
extends SomeClass
@ -1235,8 +1119,7 @@ Note:
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
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
```
Inner classes
^^^^^^^^^^^^^
#### Inner classes
A class file can contain inner classes. Inner classes are defined using the
`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
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()
```
Exports
~~~~~~~
### Exports
Note:
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
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
with the new value. Vice versa, when `variable` is accessed, the *getter* function
(`getterfunc` above) must `return` the desired value. Below is an example
```
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
```
# Only a setter.
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
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
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
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
`Character` node to a `Game` node. When the `Character` node emits the
signal, the game node's `on_Character_health_depleted` is called
```
# 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
a `Game` node higher up our scene tree, we connect it to the `Lifebar` using
the `Object.connect()` method
```
# Character.gd
@ -1584,6 +1464,7 @@ the `Character` node.
You can write optional argument names in parentheses after the signal's
definition
```
# Defining a signal that forwards two arguments.
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
damage. So when we connect the signal to the in-game console, we can add the
character's name in the binds array argument
```
# 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
```
# 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 )`
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
function returns. Once resumed, the state object becomes invalid. Here is
an example
```
func my_func():
print("Hello")
@ -1658,6 +1541,7 @@ an example
```
Will print
```
Hello
my dear
@ -1666,6 +1550,7 @@ Will print
It is also possible to pass values between `yield()` and `resume()`,
for example
```
func my_func():
print("Hello")
@ -1681,6 +1566,7 @@ for example
```
Will print
```
Hello
world
@ -1688,6 +1574,7 @@ Will print
```
Remember to save the new function state, when using multiple `yield`\s
```
func co_func():
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.
`yield` can accept two arguments, an object and a signal. When the
signal is received, execution will recommence. Here are some examples
```
# Resume execution the next 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
into an invalid state, for example
```
func my_func():
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
the arguments
```
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
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
defers initialization of a member variable until `ready()` is called. It
can replace the above code with a single line
```
onready var my_label = get_node("MyLabel")
```
Assert keyword
~~~~~~~~~~~~~~
### Assert keyword
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

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
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
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
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
a performance boost.
Variables & assignment
~~~~~~~~~~~~~~~~~~~~~~
### Variables & assignment
All variables in a dynamically typed language are "variant"-like. This
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.
```
As function arguments:
~~~~~~~~~~~~~~~~~~~~~~
### As function arguments:
Functions are of dynamic nature too, which means they can be called with
different arguments, for example:
@ -103,8 +97,7 @@ Dynamic:
print_value("Hello") # Valid.
```
Pointers & referencing:
~~~~~~~~~~~~~~~~~~~~~~~
### Pointers & referencing:
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
@ -172,7 +165,6 @@ if inheriting manually from `Object`.
Note:
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
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,
rather than modifying the value in-place.
Arrays
------
## Arrays
Arrays in dynamically typed languages can contain many different mixed
datatypes inside and are always dynamic (can be resized at any time).
@ -279,8 +270,7 @@ Or unordered sets:
print("We have a winner!")
```
Dictionaries
------------
## Dictionaries
Dictionaries are a powerful tool in dynamically typed languages.
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.
```
For & while
-----------
## For & while
Iterating in some statically typed languages can be quite complex:
@ -456,8 +445,7 @@ Becomes:
pass
```
While
-----
## While
while() loops are the same everywhere:
@ -469,8 +457,8 @@ while() loops are the same everywhere:
i += 1
```
Custom iterators
----------------
## Custom iterators
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`
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
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
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
with the resource (such as the `scene`) they're
@ -28,15 +26,13 @@ special export syntax is provided.
Note:
Exporting properties can also be done in other languages such as C#.
The syntax varies depending on the language.
..
See ref `doc_c_sharp_exports` for information on C# exports.
Examples
--------
## Examples
```
# 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
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)
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.
If in doubt, use boolean variables instead.
Exporting arrays
----------------
## Exporting arrays
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]
```
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
`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()`
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
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
handled and how they can be customized with
`set()`,
`get()`, and
`get_property_list()` methods as
`set()`, `get()`, and `get_property_list()` methods as
described in `doc_accessing_data_or_logic_from_object`.
See also:
@ -245,8 +235,7 @@ Warning:
The script must operate in the `tool` mode so the above methods
can work from within the editor.
Properties
~~~~~~~~~~
### Properties
To understand how to better use the sections below, you should understand
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`.
Note:
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
in scripts), you need to create a variable with the exact same name as the
property or else you may need to override the
`set()` and
`get()` methods. Attaching
`set()` and `get()` methods. Attaching
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 acts just like a regular gdscript export.
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
```
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.
@ -326,12 +313,12 @@ To define default values for advanced exports, you need to override the `propert
return 5
```
Adding script categories
~~~~~~~~~~~~~~~~~~~~~~~~
### Adding script categories
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
example of a built-in category.
```
func _get_property_list():
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
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.
```
func _get_property_list():
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
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:
```
class_name StateMachine
extends Node
@ -89,21 +89,16 @@ Here is a complete class example based on these guidelines:
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 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 **Tabs** instead of spaces for indentation. *(editor default)*
Indentation
~~~~~~~~~~~
### Indentation
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
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,}
```
Blank lines
~~~~~~~~~~~
### 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
in short code snippets in this documentation.
Line length
~~~~~~~~~~~
### Line length
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
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,
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"
```
Format multiline statements for readability
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Format multiline statements for readability
When you have particularly long `if` statements or nested ternary expressions,
wrapping them over multiple lines improves readability. Since continuation lines
@ -345,8 +335,7 @@ end of the previous line.
pass
```
Avoid unnecessary parentheses
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Avoid unnecessary parentheses
Avoid parentheses in expressions and conditional statements. Unless
necessary for order of operations or wrapping over multiple lines,
@ -366,8 +355,7 @@ they only reduce readability.
queue_free()
```
Boolean operators
~~~~~~~~~~~~~~~~~
### Boolean operators
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")
```
Comment spacing
~~~~~~~~~~~~~~~
### Comment spacing
Regular comments should start with a space, but not code that you comment out.
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
of the selected lines.
Whitespace
~~~~~~~~~~
### Whitespace
Always use one space around operators and after commas. Also, avoid extra spaces
in dictionary references and function calls.
@ -452,8 +438,7 @@ Don't use spaces to align expressions vertically:
velocity = 500
```
Quotes
~~~~~~
### Quotes
Use double quotes unless single quotes make it possible to escape fewer
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\"")
```
Numbers
~~~~~~~
### Numbers
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
@ -527,15 +511,13 @@ readable.
.. _naming_conventions:
Naming conventions
------------------
## Naming conventions
These naming conventions follow the Pandemonium Engine style. Breaking these will make
your code clash with the built-in naming conventions, leading to inconsistent
code.
File names
~~~~~~~~~~
### File names
Use snake_case for file names. For named classes, convert the PascalCase class
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
from Windows to other platforms.
Classes and nodes
~~~~~~~~~~~~~~~~~
### Classes and nodes
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")
```
Functions and variables
~~~~~~~~~~~~~~~~~~~~~~~
### Functions and variables
Use snake\_case to name functions and variables:
@ -588,8 +568,7 @@ override, private functions, and private variables:
func _recalculate_path():
```
Signals
~~~~~~~
### Signals
Use the past tense to name signals:
@ -598,8 +577,7 @@ Use the past tense to name signals:
signal score_changed
```
Constants and enums
~~~~~~~~~~~~~~~~~~~
### Constants and enums
Write constants with CONSTANT\_CASE, that is to say in all caps with an
underscore (\_) to separate words:
@ -621,8 +599,7 @@ are constants:
```
Code order
----------
## Code order
This first section focuses on code order. For formatting, see
`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.
Class declaration
~~~~~~~~~~~~~~~~~
### Class declaration
If the code is meant to run in the editor, place the `tool` keyword on the
first line of the script.
@ -686,8 +663,7 @@ and how other developers should use it, for example.
# Longer description.
```
Signals and properties
~~~~~~~~~~~~~~~~~~~~~~
### Signals and properties
Write signal declarations, followed by properties, that is to say, member
variables, after the docstring.
@ -726,22 +702,19 @@ Note:
child nodes in the scene that your class relies on. This is what the example
above shows.
Member variables
~~~~~~~~~~~~~~~~
### Member variables
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
variables in the method's body.
Local variables
~~~~~~~~~~~~~~~
### Local variables
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
variable was declared.
Methods and static functions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
### Methods and static functions
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 )`.
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
```
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:
```
Inferred types
~~~~~~~~~~~~~~
### Inferred types
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:
@ -17,11 +16,9 @@ and return types.
Note:
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
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
be left with no autocomplete suggestions:
.. figure:: img/typed_gdscript_code_completion_dynamic.png)
:alt: code completion options for dynamic
![code completion options for dynamic](img/typed_gdscript_code_completion_dynamic.png)
code completion options for dynamic
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
however, you will get all public methods and variables from the node:
.. figure:: img/typed_gdscript_code_completion_typed.png)
:alt: code completion options for typed
![code completion options for typed](img/typed_gdscript_code_completion_typed.png)
code completion options for typed
In the future, typed GDScript will also increase code performance:
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
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
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:
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
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
```
Variable casting
~~~~~~~~~~~~~~~~
### Variable casting
Type casting is a key concept in typed languages.
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:
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
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
green at the left of the script editor.
.. figure:: img/typed_gdscript_safe_unsafe_line.png)
:alt: Unsafe vs Safe Line
![Unsafe vs Safe Line](img/typed_gdscript_safe_unsafe_line.png)
Unsafe line (line 7) vs Safe Lines (line 6 and 8)
Unsafe line (line 7) vs Safe Lines (line 6 and 8)
Note:
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
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
```
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
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
dynamic style:
```
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
`Bullet`, the `bullet` variable will be `null`.
Warning system
--------------
## Warning system
Note:
Documentation about the GDScript warning system has been moved to
`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
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
```
Summary
-------
## Summary
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

View File

@ -1,7 +1,5 @@
GDScript warning system
=======================
# GDScript warning system
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
@ -11,18 +9,16 @@ to runtime errors.
You can configure warnings in the Project Settings under the section
called **Gdscript**:
.. figure:: img/typed_gdscript_warning_system_settings.png)
:alt: Warning system project settings
![Warning system project settings](img/typed_gdscript_warning_system_settings.png)
Warning system project settings
Warning system project settings
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:
.. figure:: img/typed_gdscript_warning_example.png)
:alt: Warning system example
![Warning system example](img/typed_gdscript_warning_example.png)
Warning system example
Warning system example
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
@ -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
anymore:
.. figure:: img/typed_gdscript_warning_system_ignore.png)
:alt: Warning system ignore example
![Warning system ignore example](img/typed_gdscript_warning_system_ignore.png)
Warning system ignore example
Warning system ignore example
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
@ -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
warnings as errors turned on:
.. figure:: img/typed_gdscript_warning_system_errors.png)
:alt: Warnings as errors
![Warnings as errors](img/typed_gdscript_warning_system_errors.png)
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
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.
Usage in GDScript
-----------------
## Usage in GDScript
Examine this concrete GDScript example:
@ -67,8 +65,7 @@ There are other `format specifiers`, but they are only applicable when using
the `%` operator.
Multiple placeholders
---------------------
## Multiple placeholders
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
@ -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.
Format specifiers
-----------------
## Format specifiers
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
@ -95,61 +91,51 @@ They consist of one or more characters. Some of them work by themselves like
values or characters.
Placeholder types
~~~~~~~~~~~~~~~~~
### Placeholder types
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.
+-------+---------------------------------------------------------------------+
| `s` | **Simple** conversion to String by the same method as implicit |
| | |
|-------|---------------------------------------------------------------------|
| `s` | **Simple** conversion to String by the same method as implicit |
| | 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. |
+-------+---------------------------------------------------------------------+
| `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). |
+-------+---------------------------------------------------------------------+
| `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). |
+-------+---------------------------------------------------------------------+
| `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). |
+-------+---------------------------------------------------------------------+
| `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). |
+-------+---------------------------------------------------------------------+
| `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
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 |
| | starts with `0` in an integer or real number placeholder. |
| | The leading `0` is ignored if `-` is present. |
| | When used after `.`, see `.`. |
+---------+-------------------------------------------------------------------+
| `.` | Before `f`, set **precision** to 0 decimal places. Can be |
| | starts with `0` in an integer or real number placeholder. |
| | The leading `0` is ignored if `-` is present. |
| | When used after `.`, see `.`. |
| `.` | Before `f`, set **precision** to 0 decimal places. Can be |
| | followed up with numbers to change. Padded with zeroes. |
+---------+-------------------------------------------------------------------+
| `-` | **Pad to the right** rather than the left. |
+---------+-------------------------------------------------------------------+
| `*` | **Dynamic padding**, expect additional integral parameter to set |
| | padding or precision after `.`, see `dynamic padding`. |
+---------+-------------------------------------------------------------------+
| `-` | **Pad to the right** rather than the left. |
| `*` | **Dynamic padding**, expect additional integral parameter to set |
| | padding or precision after `.`, see `dynamic padding`. |
Padding
-------
## Padding
The `.` (*dot*), `*` (*asterisk*), `-` (*minus sign*) and digit
(`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
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
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
`String.format` method.
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| **Type** | **Style** | **Example** | **Result** |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| 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 | 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! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
| 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! |
+------------+-----------+------------------------------------------------------------------------------+-------------------+
|------------|-----------|------------------------------------------------------------------------------|-------------------|
| 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 | 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! |
| 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
examples of that functionality.
+-----------------+------------------------------------------------------+------------------+
| **Type** | **Example** | **Result** |
+-----------------+------------------------------------------------------+------------------+
| 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 |
+-----------------+------------------------------------------------------+------------------+
| Prefix | `"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 |
| 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
`String.format` does not have a way to manipulate the representation of numbers.
+---------------------------------------------------------------------------+-------------------+
| **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
work in Pandemonium. For a detailed reference of the engine's shading language, see
@ -42,11 +41,9 @@ look like this.
Note:
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
(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
platforms.
Shader types
------------
## Shader types
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
@ -92,8 +88,7 @@ Here are the available types:
* `canvas_item ( doc_canvas_item_shader )` for 2D rendering.
* `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
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
type for a complete list of render modes.
Processor functions
-------------------
## Processor functions
Depending on the shader type, you can override different processor functions.
For `spatial` and `canvas_item`, you have access to `vertex()`,
`fragment()`, and `light()`. For `particles`, you only have access to
`vertex()`.
Vertex processor
^^^^^^^^^^^^^^^^
#### Vertex processor
The `vertex()` processing function is called once for every vertex in
`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
example.
Fragment processor
^^^^^^^^^^^^^^^^^^
#### Fragment processor
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
@ -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
not use.
Light processor
^^^^^^^^^^^^^^^
#### Light processor
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

View File

@ -1,10 +1,8 @@
Shader materials
================
# Shader materials
Introduction
------------
## Introduction
For the most common cases, Pandemonium provides ready to use materials for
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
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
"Material" property and create a ShaderMaterial.
@ -63,12 +60,9 @@ your visual shader to a text shader.
![](img/visual_shader_code.png)
Note:
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
ParticlesMaterial to ShaderMaterial. To do so, go to the material properties
@ -78,6 +72,5 @@ and select the convert option.
Note:
Using the convert option will turn the SpatialMaterial into a ShaderMaterial
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
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
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).
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
devices.
SCREEN_TEXTURE example
~~~~~~~~~~~~~~~~~~~~~~
### SCREEN_TEXTURE example
`SCREEN_TEXTURE` can be used for many things. There is a
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
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)
.. warning:
Warning:
Materials that use `SCREEN_TEXTURE` are considered transparent themselves and
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
`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
Pandemonium:
@ -141,8 +134,7 @@ Pandemonium:
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,
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
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
`Shading Language ( doc_shading_language )` reference.
GLSL
----
## GLSL
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
available in Pandemonium's shading language.
Shader programs
^^^^^^^^^^^^^^^
#### Shader programs
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
@ -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
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
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
reference ( doc_shading_language )`.
gl_Position
^^^^^^^^^^^
#### gl_Position
`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
@ -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
space.
Varyings
^^^^^^^^
#### Varyings
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
`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.
Main
^^^^
#### Main
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
shader, rename `main` to `vertex` and if you are copying a fragment shader,
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
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
`#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
compilation.
Variables
#### Variables
^^^^^^^^^
GLSL has many built-in variables that are hard-coded. These variables are not
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
same coordinate system. If using UV in Pandemonium, the y-coordinate will be flipped
upside down.
Precision
^^^^^^^^^
#### Precision
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
@ -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 )`
reference.
Shadertoy
---------
#### Shadertoy
`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
@ -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
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.
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.
`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
copied into the `fragment` function when porting to Pandemonium.
Variables
^^^^^^^^^
#### Variables
In order to make writing fragment shaders straightforward and easy, Shadertoy
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
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
<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 )`
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
in various frameworks.
Types
^^^^^
#### Types
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
macros.
Main
^^^^
#### Main
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
into Pandemonium's `fragment` function.
Variables
^^^^^^^^^
#### Variables
The Book of Shaders sticks closer to plain GLSL than Shadertoy does. It also
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
`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
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 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 **Tabs** instead of spaces for indentation. *(editor default)*
Indentation
~~~~~~~~~~~
### Indentation
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
`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:
@ -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.
Line length
~~~~~~~~~~~
### Line length
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
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.
@ -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.
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
the selected lines.
Whitespace
~~~~~~~~~~
### Whitespace
Always use one space around operators and after commas. Also, avoid extraneous spaces
in function calls.
@ -248,8 +238,7 @@ Don't use spaces to align expressions vertically:
EMISSION.r = 1.0;
```
Floating-point numbers
~~~~~~~~~~~~~~~~~~~~~~
### Floating-point numbers
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
@ -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
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);
```
Naming conventions
------------------
## Naming conventions
These naming conventions follow the Pandemonium Engine style. Breaking these will make
your code clash with the built-in naming conventions, leading to inconsistent
code.
Functions and variables
~~~~~~~~~~~~~~~~~~~~~~~
### 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
underscore (\_) to separate words:
@ -319,8 +304,7 @@ underscore (\_) to separate words:
const float GOLDEN_RATIO = 1.618;
```
Code order
----------
## Code order
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"
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
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.
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
Viewports do not maintain depth information.
Full screen quad
----------------
## Full screen quad
In the `custom post-processing tutorial ( doc_custom_postprocessing )`, we
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.
You can also use both options.
Depth texture
-------------
## Depth texture
To read from the depth texture, perform a texture lookup using `texture()` and
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
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
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
- Setting a Roughness map from a `Viewport Texture`
Setting up the Viewport
-----------------------
## Setting up the Viewport
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
apply to the sphere.
Applying the texture
--------------------
## Applying the texture
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
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
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
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
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)
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.
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
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:
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
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
`Viewport` on the screen. You can use a `ViewportContainer
@ -34,7 +29,6 @@ another `Control` node.
Note:
Rendering using a `Viewport` gives you control over
how the scene render, including the framerate, and you can use the
`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:
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
manually, like so:
@ -62,7 +55,7 @@ Note:
```
// Inside the Shader.
uniform sampler2D ViewportTexture;
```
```
And you can pass the texture into the shader from GDScript like so:
@ -70,7 +63,7 @@ Note:
# In GDScript.
func _ready():
$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
`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:
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
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)
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
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:
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.

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.
@ -9,8 +8,7 @@ The aim is to not focus on the modelling techniques (there are plenty of tutoria
![](img/tree_sway.gif)
Start with a tree
-----------------
## Start with a tree
I took this tree from SketchFab:
@ -20,8 +18,7 @@ https://sketchfab.com/models/ea5e6ed7f9d6445ba69589d503e8cebf
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:
@ -31,8 +28,7 @@ This is a bit exaggerated, but the idea is that color indicates how much sway af
![](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:
@ -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.
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
(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