Master Modules Part One : The Starter Project
by Simon Love · 04/25/2016 (4:00 pm) · 7 comments
The Starter Project is a bare-bones, stripped down Torque2D project which contains a few utility modules which should be useful as a starting point for most T2D projects.
This project does not cover the creation of a Scene, SceneWindow or any game logic; it provides a skeleton for you to build upon.
!!!Grab the Starter Project here!!!
You will have to use your own executable and .dlls (if you are on Windows) and create your own Torsion project.
Let us start with an overview of the changes in the Appcore module.
The schema file is used to facilitate the creation and edition of TAML files in an XML editor; simply point your XML editor of choice to the schema file to use this functionality.
Microsoft's XML Notepad 2007, showing all possible elements of an ImageAsset.
The schema should only be updated if you create new asset types in C++ or add new fields to existing ones. In other words : Not that often unless you are actively extending T2D's source code.
As every file needs to be executed via the exec function to be taken into consideration by the engine, this process can become extremely tedious and frustrating.
This script allows you to load all script files in a given directory, without needing to execute each file manually.
Simply call loadDirectory("^MyModule/scripts"); and voila! All script files will be loaded. As you will see in further modules, this is best called in the create function of a module.
Note that the caret(^) and current module name must be specified as such for the function to work properly. I've never managed to make it work using the ./ and / relative path nomenclature.
This enables joystick and gamepad(Xbox 360 controllers) support. A more complex initialization routine might be desireable but placing it here ensures that all devices are fired up and ready to go.
These Utility modules will be described below. It is important to load them in this order as each one of these depends on the one loaded before it.
The Standard ToyAssets Module is included in the starter project as it greatly helps when quickly prototyping new ideas. The only difference is that the module's group has been set to "Assets".

Any Assets you create for your game simply need to be catalogued in a module belonging to the "Assets" Group and they will be automatically loaded at startup.
This is a relatively new addition to the engine which caps the framerate to your monitor's refresh rate (usually 60Hz/60 fps). On certain devices, running T2D without this will emit audible artifacts, notably a high-pitched whine through your monitor or TV.
While it may be argued that the above-mentioned functionality should be separated into other modules, all projects should benefit from these, whether during development or after the game has shipped. Onwards to the other modules!
Two new GuiProfiles were added, GuiSceneWindowProfile and GuiModalProfile. The first one should be used for all SceneWindows in your game (see Console Module below for details) while the latter allows the transparent areas of GuiControls to send mouse clicks to controls beneath them on the Gui stack.
This system automatically creates a /screenshots directory at the root of your project and manages the file naming, ensuring that your screenshots aren't overwritten with each new session.
This functionality requires custom preferences stored under $pref::ScreenShots::. Modifying these preferences allows screenshots to be saved in other directories.
The console is still bound to "ctrl ~" but its script has been streamlined and modified to circumvent a scripting bug present in its original incarnation.
A quick explanation : I've recently fixed bugs in the ActionMap which exposed an issue where closing the Console did not shift focus away from it, making ActionMap bindings (especially the Enter key) still be captured by the invisible console.
IMPORTANT NOTE
Make sure that your game's main SceneWindow uses the GuiSceneWindowProfile. If you plan on using your own custom GuiProfile, simply make sure that its canKeyFocus field is set to true;
That's it for the boring part! I hope that this saves you time and headaches for your next T2D project.
In the next few days, we will start tackling the fun stuff. First up, the InputMatrix, an input layer which will change the way you handle player input.
This project does not cover the creation of a Scene, SceneWindow or any game logic; it provides a skeleton for you to build upon.
!!!Grab the Starter Project here!!!
You will have to use your own executable and .dlls (if you are on Windows) and create your own Torsion project.
Let us start with an overview of the changes in the Appcore module.
Appcore
The Appcore module saw a few modifications from the one included with the Sandbox demo. Here is a rundown of the new files included.- SchemaUtils.cs
This file contains a single wrapper for the GenerateTamlSchema() C++ function.The schema file is used to facilitate the creation and edition of TAML files in an XML editor; simply point your XML editor of choice to the schema file to use this functionality.
Microsoft's XML Notepad 2007, showing all possible elements of an ImageAsset.The schema should only be updated if you create new asset types in C++ or add new fields to existing ones. In other words : Not that often unless you are actively extending T2D's source code.
- DirectoryUtils.cs
Whenever you start working on a new module, chances are that you will create a bunch of new script files and behaviors, deleting and renaming them, moving them around, etc.As every file needs to be executed via the exec function to be taken into consideration by the engine, this process can become extremely tedious and frustrating.
This script allows you to load all script files in a given directory, without needing to execute each file manually.
Simply call loadDirectory("^MyModule/scripts"); and voila! All script files will be loaded. As you will see in further modules, this is best called in the create function of a module.
Note that the caret(^) and current module name must be specified as such for the function to work properly. I've never managed to make it work using the ./ and / relative path nomenclature.
- Main.cs
Appcore's main.cs file has been modified. Most of it is pretty self-explanatory but I want to bring your attention to the following lines :ActivateDirectInput(); $enableDirectInput = true; enableJoystick(); enableXInput();
This enables joystick and gamepad(Xbox 360 controllers) support. A more complex initialization routine might be desireable but placing it here ensures that all devices are fired up and ready to go.
ModuleDatabase.loadExplicit("Prefs");
ModuleDatabase.loadExplicit("GuiModule");
ModuleDatabase.loadExplicit("Console");These Utility modules will be described below. It is important to load them in this order as each one of these depends on the one loaded before it.
ModuleDatabase.loadGroup("Assets");The Standard ToyAssets Module is included in the starter project as it greatly helps when quickly prototyping new ideas. The only difference is that the module's group has been set to "Assets".

Any Assets you create for your game simply need to be catalogued in a module belonging to the "Assets" Group and they will be automatically loaded at startup.
ModuleDatabase.loadGroup("Master");The Master Modules are the modules which will I will provide and discuss in the coming weeks.setVerticalSync(true);
This is a relatively new addition to the engine which caps the framerate to your monitor's refresh rate (usually 60Hz/60 fps). On certain devices, running T2D without this will emit audible artifacts, notably a high-pitched whine through your monitor or TV.
While it may be argued that the above-mentioned functionality should be separated into other modules, all projects should benefit from these, whether during development or after the game has shipped. Onwards to the other modules!
Prefs Module
A simple module which exports all preferences on application shutdown and loads them back up when the application is launched. The preferences.cs file will be created in the root directory of your project.GuiModule
The GuiModule contains all of the GuiProfiles, images and Gui-related assets which were in the Sandbox demo. Most profiles were linked to the Sandbox Module, making it a hassle to reuse in non-Sandbox projects.Two new GuiProfiles were added, GuiSceneWindowProfile and GuiModalProfile. The first one should be used for all SceneWindows in your game (see Console Module below for details) while the latter allows the transparent areas of GuiControls to send mouse clicks to controls beneath them on the Gui stack.
- ScreenShots
A useful functionality that was missing from the Sandbox was the ability to take screenshots. With this Starter Project, users can simply press F5 to take a screenshot of the game in .png format.This system automatically creates a /screenshots directory at the root of your project and manages the file naming, ensuring that your screenshots aren't overwritten with each new session.
This functionality requires custom preferences stored under $pref::ScreenShots::. Modifying these preferences allows screenshots to be saved in other directories.
Console Module
The Console has been ripped from the Sandbox demo. It depends on profiles and assets found in the GuiModule instead.The console is still bound to "ctrl ~" but its script has been streamlined and modified to circumvent a scripting bug present in its original incarnation.
A quick explanation : I've recently fixed bugs in the ActionMap which exposed an issue where closing the Console did not shift focus away from it, making ActionMap bindings (especially the Enter key) still be captured by the invisible console.
IMPORTANT NOTE
Make sure that your game's main SceneWindow uses the GuiSceneWindowProfile. If you plan on using your own custom GuiProfile, simply make sure that its canKeyFocus field is set to true;
new SceneWindow(){
Profile = GuiSceneWindowProfile;
};That's it for the boring part! I hope that this saves you time and headaches for your next T2D project.
Next Issue : The InputMatrix
In the next few days, we will start tackling the fun stuff. First up, the InputMatrix, an input layer which will change the way you handle player input.
About the author
I am here to help. I've worked at every imaginable position in game development, having entered the field originally as an audio guy.
#2
The reason I haven't used module dependency is simply for increased readability. I found it simpler to look at Appcore/main.cs and see at a glance what was being loaded vs. having to go through the module definition files and seeing which module depended on which. Same result, different approaches based on preference.
04/25/2016 (5:41 pm)
:) I actually said to myself "Bah, no need to explain why I'm not using module dependencies", a whole paragraph that was written in my initial draft.The reason I haven't used module dependency is simply for increased readability. I found it simpler to look at Appcore/main.cs and see at a glance what was being loaded vs. having to go through the module definition files and seeing which module depended on which. Same result, different approaches based on preference.
#3
However, dependencies might be worth a detour later on.
Another thing to note - I'm sure everyone noticed that these modules all have <module>/1/<stuff>. Versioning! The caveat? I don't know if dependencies were set up to resolve by version. It was on the roadmap, just don't recall if they got there.
04/25/2016 (6:58 pm)
Yeah, I see the reasoning behind that approach. Just "straightforward and simple."However, dependencies might be worth a detour later on.
Another thing to note - I'm sure everyone noticed that these modules all have <module>/1/<stuff>. Versioning! The caveat? I don't know if dependencies were set up to resolve by version. It was on the roadmap, just don't recall if they got there.
#4
As for module/1/, I have found it much simpler to have a backup folder with older version of modules in it. Much less clutter than having the /1/, /2/, /3/ structure, which is, by the way, absolutely irrelevant to how the versioning system works and is entirely based on preference. Not sure why it came up in this thread as my modules don't use the /1/ structure at all.
04/25/2016 (7:31 pm)
@Richard : Dependencies cannot be declared without specifying the version of the target module as well.<ModuleDefinition
ModuleId="Game"
VersionId="1"
Dependencies="GameCore=1"/>As for module/1/, I have found it much simpler to have a backup folder with older version of modules in it. Much less clutter than having the /1/, /2/, /3/ structure, which is, by the way, absolutely irrelevant to how the versioning system works and is entirely based on preference. Not sure why it came up in this thread as my modules don't use the /1/ structure at all.
#5
04/26/2016 (5:58 am)
It's been a long time since I looked at it - thanks for the reminder!
#6
I didn't realize you could leave the /1/ folder out if you wanted to! I personally don't see the need for a versioning system. I understand the original reasoning, but I don't think it translates well to real life. So far I've only seen modules in version 1.
On the other hand, I like the dependency system. To be honest though, in my game I don't use it because all my modules pretty much depend on either other to work. Like you, I just list out my modules.
04/26/2016 (7:51 am)
It is off topic, but that tends to happen in comments. I didn't realize you could leave the /1/ folder out if you wanted to! I personally don't see the need for a versioning system. I understand the original reasoning, but I don't think it translates well to real life. So far I've only seen modules in version 1.
On the other hand, I like the dependency system. To be honest though, in my game I don't use it because all my modules pretty much depend on either other to work. Like you, I just list out my modules.
#7
The only real difference between versions is the entry file (main.cs) and the create and destroy functions. I think (haven't tested it yet) that you could have several module definitions in the same directory, each one reusing 90% of the same code but pointing to a different script file for initialization or use different create and destroy methods. I don't see the benefits or application of this, but T2D allows it.
04/26/2016 (10:08 am)
@Peter : versioning would greatly facilitate updating an existing game. Copying all modules and rebranding them as version 2, you could simply edit them as you went along, always keeping version 1 on disk if you mess things up. Easier than completely starting over from scratch. The "patch" would thus only contain newer versions of the modified modules and an updated script file which would load the appropriate versions.The only real difference between versions is the entry file (main.cs) and the create and destroy functions. I think (haven't tested it yet) that you could have several module definitions in the same directory, each one reusing 90% of the same code but pointing to a different script file for initialization or use different create and destroy methods. I don't see the benefits or application of this, but T2D allows it.

Associate Peter Robinson
Having the console available to little personal projects is probably the most important part of this. My first two days with the MIT version of T2D were spent reading and splitting out the console.
Thanks!