Permalink
f61f525 Sep 9, 2018
1 contributor

Users who have contributed to this file

152 lines (88 sloc) 10.4 KB

Writing extensions for GDevelop 5

GDevelop editor and games engines are designed so that all objects, behaviors, actions, conditions and expressions are provided by extensions. These extensions are composed of two parts:

  • the declaration of the extension, traditionally done in a file called JsExtension.js.
  • the implementation of the extension for the game engine (also the "Runtime"), containing the functions corresponding to the actions/conditons/expressions and the classes used for the objects or behaviors. The implementation is traditionally in files called extensionnametools.js, objectnameruntimeobject.js or objectnameruntimebehavior.js.

Note that some GDevelop extensions are declared in C++, in files called JsExtension.cpp. If you want to edit them, refer to the paragraph about them at the end.

Getting started

To modify extensions, you need to have the development version of GDevelop running. Make sure to have Git and Node.js installed. Yarn is optional.

git clone https://github.com/4ian/GD.git
cd GD/newIDE/app
npm install #or yarn

Refer to the GDevelop IDE Readme for more information about the installation.

Development

  • First, run GDevelop with Electron.

    When GDevelop is started, the developer console should be opened. Search for the message Loaded x JS extensions. that indicates the loading of extensions.

  • You can now open an extensions contained in the folder Extensions at the root of the repository. For example, you can open Extensions/FacebookInstantGames. Edit the JsExtension.js file or a runtime file. After any change, you must import them in GDevelop:

    cd scripts
    node import-GDJS-Runtime.js #This copy extensions declaration and runtime into GDevelop.
  • Finally, verify that the changes are applied:

    • If you modified the declaration (JsExtension.js), reload GDevelop by pressing Ctrl+R (or Cmd+R on macOS) in the developer console.
    • If you modified a Runtime file, relaunch a preview. Open the developer console if you want to check for any errors.
  • You can now iterate and relaunch the script to develop the extension! 🚀

    ⚠️ Always check the developer console after reloading GDevelop. If there is any error signaled, click on it to see what went wrong. You may have done a syntax error or mis-used an API.

Implement your feature for the game engine

ℹ️ Implement your extension in file called extensionnametools.js (for general functions), objectnameruntimeobject.js (for objects) or behaviornameruntimebehavior.js (for behaviors). See then the next section for declaring these files and the content of the extension to the IDE.

Check the GDJS game engine documentation here. It's also a good idea to check the Runtime folder of GDJS to see directly how the game engine is done when needed.

How to create functions to be called by events

See examples in examplejsextensiontools.js.

Read about gdjs.RuntimeScene, the class representing a scene being played, as lots of events can need it.

How to create a behavior by extending gdjs.RuntimeBehavior

See examples in dummyruntimebehavior.js (or dummywithshareddataruntimebehavior.js for an example with shared data between behaviors).

You'll be interested in the constructor (to initialize things), onDeActivate (called when behavior is deactivated), doStepPreEvents and doStepPostEvents (to run logic before/after the events at each frame).

Read about gdjs.RuntimeBehavior, the base class inherited by all behaviors, to see everything that is available.

How to create an object by extending gdjs.RuntimeObject

👋 There is still no examples for objects, as declaring objects is not yet fully exposed to JavaScript extensions. Your help is welcome to expose this feature!

Read about gdjs.RuntimeObject, the base class inherited by all objects.

How to declare your extension to the IDE

ℹ️ Declaration must be done in a file called JsExtension.js. Your extension must be in Extensions folder, in its own directory.

The API to declare extensions is almost 100% equivalent to the way extensions are declared in C++, so most links will redirect to this documentation.

Declare the extension information

Use extension.setExtensionInformation to declare basic information about your extension.

👉 See an example in the example extension JsExtension.js file.

Declare actions, conditions and expressions

Use addAction, addCondition, addExpression or addStrExpression to declare actions, conditions or expressions.

  • Chain calls to addParameter to declare the parameters of your action/condition/expression.
  • Call getCodeExtraInformation() and then functions like setFunctionName and setIncludeFile to declare the JavaScript function to be called and the file to be included.

You can call these functions on the extension object, or on the objects returned by extension.addObject (for objects) or extension.addBehavior (for behaviors). See below.

⚠️ Always double check that you've not forgotten an argument. Such errors/mismatchs can create silent bugs that could make GDevelop instable or crash while being used.

👉 See an example in the example extension JsExtension.js file.

Declare behaviors

Add a behavior using addBehavior. The last two parameters are the gd.Behavior and the gd.BehaviorsSharedData object representing the behavior and its (optional) shared data

  • For the behavior, create a new gd.BehaviorJsImplementation() and define updateProperty and getProperties.
  • For the shared data (which are properties shared between all behaviors of the same type), if you don't have the need for it, just pass new gd.BehaviorsSharedData(). If you need shared data, create a new gd.BehaviorSharedDataJsImplementation() and define updateProperty and getProperties.

⚠️ Like other functions to declare extensions, make sure that you've not forgotten to declare a function and that all arguments are correct.

👉 See an example in the example extension JsExtension.js file.

Declare objects

👋 Declaring objects is not yet fully exposed to JavaScript extensions. Your help is welcome to expose this feature!

Add an object using addObject. The last parameter is the gd.Object representing the object:

  • Create a new gd.ObjectJsImplementation() and define updateProperty and getProperties (for the object properties) and updateInitialInstanceProperty and getInitialInstanceProperties (for the optional properties that are attached to each instance).

👉 See an example in the example extension JsExtension.js file.

Declare events

👋 Declaring events is not yet exposed to JavaScript extensions. Your help is welcome to expose this feature!

Starting a new extension from scratch

If you want to start a new extension:

  • Choose a unique and descriptive name. Create a folder with this name in Extensions.
  • Create a file in it named JsExtension.js and copy the content of the JsExtension.js of another extension.
  • Change the extension information (extension.setExtensionInformation). The first argument is the extension internal name and should be the same name as your folder for consistency.
  • Remove all the actions/conditions/expressions declarations and tests, run node import-GDJS-Runtime.js and reload GDevelop to verify that your extension is loaded.
  • Create a file called for example yourextensionnametools.js in the same directory.
  • Add back the declarations in your extension. Use setIncludeFile when declaring your actions/conditions/expressions and set the name of the js file that you've created, prefixed by the path from the root folder. For example:
    .setIncludeFile("Extensions/FacebookInstantGames/facebookinstantgamestools.js")

Current status and how to contribute

Declaring extensions in JavaScript is still new, and enhancements are possible to exploit the full potential of extensions:

  • Add support for objects and events
  • Document how to add custom icons
  • Add a button to reload extensions without reloading GDevelop IDE entirely.
  • Create a "watcher" script that automatically run node import-GDJS-Runtime anytime a change is made.

Development of extensions declared in C++ (JsExtension.cpp or Extension.cpp)

The majority of extensions are still declared in C++ for being compatible with GDevelop 4. Check the sources in Extensions folder and install GDevelop.js. You'll then be able to make changes in C++ source files and have this reflected in the editor.