by Jon (Updated on 2015-10-25)
Engine Extensions |
Advanced Topics |
Toolset Extensions |
Extensions are small applications or controls that add new functionality to Stencyl. They serve the same purpose as extensions for web browsers, such as Firefox and Chrome. Extensions allow the community to extend the utility of Stencyl itself to fit its unique needs.
The most notable extension created with Stencyl at the moment is the Dialog Extension, a powerful, easy to use dialog system that supports pretty much every feature you'd need.
Although we provide an API that makes it simple to build a GUI with no Swing knowledge, knowing it will give you the ability to create more powerful extensions.
As long as the extension has something to do with Stencyl, it's generally doable. If you're looking to extend the engine, look here instead.
For source code examples of existing extensions, you can see the polydes collection of extensions.
If you have an idea for an extension but you need some new hooks, callbacks, or capabilities on Stencyl's side, let us know and we'd be happy to work together to bring your extension to life!
Developing an extension is simple once you master two key concepts: hooks and callbacks.
Hooks determine where your extension is displayed in Stencyl's GUI. At this time, the available places where an extension an hook into include:
Callbacks are functions that you implement inside your extension. These callback functions are called at specific times in Stencyl's lifecycle.
For example, there are callbacks for these activities:
Every callback is documented at the end of this manual and inside our API docs.
You will need the following before you begin.
ANT is a task running system for Java. We'll go through it when we reach the point where it's needed.
Use this as a template to base your own extension off of.
Download the Sample Extension.
Place it under [WORKSPACE]/extensions/ - This folder contains all of your toolset extensions.
Create a project for the extension using your IDE of choice.
After that is done, run the dist ANT task from the IDE. This builds a Java JAR file that Stencyl recognizes as an extension.
Now that the sample extension runs, open up SampleExtension.java, the source that defines the extension itself.
Do you see how it implements a bunch of callback functions that all start with "on"?
Make a simple edit to it. For example, change menuName = "Extension Name";
to a different value.
dist
ANT task) and relaunch Stencyl. Does your change show up?The name, description, icon location, and other basic details of the extension are saved in {extension}.jar/META-INF/MANIFEST.MF
. These details can be edited in the ant task used to build your extension by using the nested <manifest>
element. Example.
Attribute | Value |
---|---|
Extension-ID | Unique ID for the extension, such as com.example.extension |
Extension-Main-Class | Main class extends BaseExtension or GameExtension. ex: com.example.extension.MyExtension |
Extension-Version | 1.0.0 (use a valid semantic version) |
Extension-Icon | Path to icon image from base folder. ex: resources/icon.png |
Extension-Dependencies | Comma-seperated list of dependencies |
Extension-Type | normal, game, or java_library |
Extension-Name | The common name for your extension. ex: "My Extension" |
Extension-Description | A short description |
Extension-Author | Name of the autor |
Extension-Website | http://extension.example.com/ |
Extension-Repository | Optional, connect to this repository for extension updates |
Extension-Internal-Version | 1 (increasing this causes updateFromVersion to be called for GameExtensions) |
Extensions are distributed through our Developer Center. Extensions must be manually approved to show up on that site. To do this, you must do two things.
Include the following details in the forum topic.
It's preferable that you either build documentation into the forum topic or provide a link to a site that does.
View the Javadocs for our API.
We cover the main parts of this API in the following sections.
Callbacks are functions that you implement inside your extension. These callback functions are called at specific times in Stencyl's lifecycle. Consult the API for the full list of callbacks.
onStartup()
Called when Stencyl is launching. Try not to do anything intense, or it will slow down launch.
onActivate()
Called when the extension is told to display or "do work"
onDestroy()
Called when Stencyl is being quit out of. Usually, you'd use this to save stuff out.
onGameSave(Game game)
Happens whenever a game is saved.
onGameOpened(Game game)
Happens whenever a game is opened.
onGameClosed(Game game)
Happens whenever a game is closed.
onGameBuild(Game game)
Happens whenever a game is compiled. Use this to modify the resulting project.
DefinitionMap getDesignModeBlocks()
Provide a set of blocks to be added to the palette.
boolean hasOptions()
Return true if this extension has options that can be configured with the onOptions
panel.
OptionsPanel onOptions()
Returns a configuration panel for this extension that's shown when the Options button is clicked in the extensions manager. View the API for the Options Panel as well as the source to the Sample Extension for usage samples.
onInstall()
Happens when the extension is first installed.
onUninstall()
Happens when the extension is uninstalled. Do cleanup.
We provide a set of functions to help you build a GUI or perform common tasks.
showMessageDialog(String title, String text)
Pops up a modal dialog with the given title and text.
doLongTask(final Runnable mainTask, final Runnable onFinish)
Perform a long task that would have hung/frozen the GUI. Pass in 2 Runnables. Runnables look like this:
Runnable r = new Runnable() {
public void run() {
//Do Stuff
}
};
setProgressMessage(final String msg)
Sets the message shown inside the progress spinner. Keep it brief!
showProgressSpinner()
Shows the progress spinner. Use it in conjunction with doLongTask.
hideProgressSpinner()
Hides the progress spinner.
Extensions store data in the following locations:
Name | Location | Purpose |
---|---|---|
Prefs | {workspace}/prefs/{id}.eprefs | Dictionary of key-value pairs |
Data | {workspace}/prefs/{id}.edata | Any data (as a single file) |
Game Prefs | {workspace}/games/{game}/extension-data/{name}/.prefs | Game-specific preferences |
Game Data | {workspace}/games/{game}/extension-data/{name} | Folder containing game-specific data |
Game Extras | {workspace}/games/{game}/extras/{name} | Game-specific data needed by the engine at runtime |
If you need to store data, use our data API to save out this data to disk. Do not attempt to write out to other locations using the plain Java API's. We may reject your extension if you do so.
int readIntProp(String key, int defaultValue)
double readDoubleProp(String key, double defaultValue)
float readFloatProp(String key, float defaultValue)
String readStringProp(String key, String defaultValue)
Read properties as different data types from Prefs
.
properties.put(String key, Object value)
Add a property to Prefs
.
String readData()
Reads Data
into a String.
byte[] readDataAsBytes()
Reads Data
into a byte array.
boolean saveData(String data)
Saves data, provided as text, to Data
.
boolean saveDataAsBytes(byte[] b)
Saves data, provided as a byte array, to Data
.
In addition to the above data stores, you can store data that is game-specific if you're creating a GameExtension
.
Name | Location | Purpose |
---|---|---|
Game Prefs | {workspace}/games/{game}/extension-data/{name}/.prefs | Game-specific preferences |
Game Data | {workspace}/games/{game}/extension-data/{name} | Folder containing game-specific data |
Game Extras | {workspace}/games/{game}/extras/{name} | Game-specific data needed by the engine at runtime |
int readIntGameProp(String key, int defaultValue)
double readDoubleGameProp(String key, double defaultValue)
float readFloatGameProp(String key, float defaultValue)
String readStringGameProp(String key, String defaultValue)
Read properties as different data types from Game Prefs
.
extensionGameProperties.put(String key, Object value)
Add a property to Game Prefs
.
File getDataFolder()
Returns the file Game Data
.
File getExtrasFolder()
Returns the file Game Extras
.