The latest version of the ScriptENGINE 2010: 3D Engine is now available.
Download it now! No obligations or time limitations. Purchase a license at any time to activate the full version.

Basic Program Framework

ScriptENGINE: Lua 3D Engine Article SeriesIn this article, we'll examine the basic framework used in most ScriptENGINE programs. It initialises the engine components, starts processing states, waits for processing to complete and then releases resources to exit the program.

In the upcoming articles we will be exploring demos available with the ScriptENGINE SDK. If you don't own the ScriptENGINE SDK, then now's a good time to buy it from our website.

 

Creating your own ScriptENGINE Framework Code

The ScriptENGINE SDK World Editor has a menu item called [File->Create Standalone Program]. It saves your 3D World and auto-generates a main.e76script to run your world from outside the editor.

The main.e76script works similarly to the runDemo.e76script that we'll be discussing in this article.

 

View the Demo Framework Code

Open the runDemo.e76script from the ScriptENGINE SDK/Scripts folder in the SciTE code editor. This script holds the basic framework used to run all the demos.

This script is used to run the ScriptENGINE demos. The runDemo.e76script does the standard program initialisation, cleanup, world loading etc.

 

Starting the Script

To run a script, double-click it from Windows Explorer of press F5 from inside SciTE.

Any code defined outside any functions is executed when the script is loaded. Typically we would place IApp:loadScript(), IApp:addSearchPath() and other related functions in the script's base code to ensure it is executed when the file is loaded into the engine. The runDemo.e76script doesn't define any base code.

 

Startup State: OnStateRun_runDemo

After executing the base code, the ScriptENGINE searches for a startup state matching the script's filename. In this case, it searches for a global function called OnStateRun_runDemo(). If it's defined (which it is), then it is automatically queued and run (otherwise, the ScriptENGINE searches for a default OnStateRun() function).

See the IState interface in the ScriptENGINE's Programmer's Reference for more information about the OnStateRun() functions.

The startup OnStateRun...() function is passed the command-line parameters as parameters to the function.

 

Initialising the graphics/physics/sound engines

The runDemo.e76script initialises the graphics/physics/sound engines via the _engineInitialise() function. It loads extra scripts into the engine using IApp:loadScript(), and adds search paths to the ScriptENGINE using IApp:addSearchPath().

Before it initialises the engines, the runDemo.e76script asks the user to select a demo from its list.

After the user has selected a demo, the runDemo.e76script initialises the graphics engine using the IGraphics:init() function. This creates the program's graphical window. The runDemo.e76script initialises the physics engine using the IPhysics:init() function. The runDemo.e76script the initialises the sound engine using the ISound:init() function.

 

Handling GUI events

The runDemo handles ScriptENGINE GUI events. It subscribes to GUI events using the IEvents:subscribeGui() function passing it's callback function name as a parameter.

Event callback signatures are defined in the ScriptENGINE Programmer's Reference and can be accessed directly from the SciTE editor by selecting the Edit->Insert Abbreviation menu or pressing Ctrl+Shift+R.

The ScriptENGINE automatically notifies all registered subscribers when events occur by invoking their callback functions.

Remember to IEvents:unsubscribe() when you're finished handling an event! Otherwise the ScriptENGINE will continue to invoke your callback function.

 

Loading GUIs

GUI controls can manually be created from code using the IGraphics:create...() functions. Typically, they are created using the SDK GUI Editor and loaded into the engine using IGraphics:loadGui().

 

Loading 3D worlds

The runDemo.e76script loads the 3D world and its entities using the IWorld:load() function. It loads the worldData file (describing the 3D world entities), and the world.e76script script (defining any specific code for the demo). The loaded files are specified in the IWorld:load() function.

Typically, 3D worlds are created in the SDK World Editor. The editor creates a default world.e76script when the world is first saved. It also creates a worldIds.e76script to map entity names to their unique identitiers. The entity ids are unique random strings with no direct meaning. So it's easier to load the worldIds.e76script into your programs and refer to the world entities with user-friendly names (as defined in the world editor, eg. Camera Name:cam1 = Identifier:idCamera_cam1, Unit Name:box = Identifier:idUnit_box).

The runDemo.e76script calls the OnWorldLoad() function defined in the world.e76script. This gives each demo a chance to perform any specific initialisation.

 

Running the Main Program Loop

There are two main ways to create your ScriptENGINE program loop. You can manually create a loop calling the IGraphics:draw() function. A simpler alternative is to call the IApp:run() function. This will auto-run the graphics/physics/sound engines at your desired frame rates, pump all messages thru the system and deliver all events to registered subscribers. The IApp:run() function is a blocking call. It will return once the IApp:stop() function is called, usually from an event subscriber's callback function (eg. a button was clicked).

In the runDemo.e76script, the IApp:run() is stopped by calling IApp:stop() when the File->Exit menu is selected.

 

Unloading the 3D world

After the IApp:run() function returns, the runDemo.e76script calls the OnWorldUnload() function defined in the world.e76script. This gives a chance to perform any specific cleanup.

It then unloads the 3D world entities using IWorld:unload(). They are removed from the graphics/physics/sound engines as appropriate.

 

The Gui Subscriber callback : __OnGui

The __OnGUI() callback function is invoked by the ScriptENGINE whenever a GUI event occurs in the system. It is used to process the menu clicks. Normally, you should return 'true' from your subscribers to notify the ScriptENGINE that you have handled the event and to bypass any default processing.

 

Cleaning up Resources

After the IApp:run() returns and the world is unloaded, the program calls _engineCleanup() to destroy the graphics/physics/sound engines it initialised on startup.

Alternatively, the program could have called IState:queue() one or more times to queue other states in the ScriptENGINE. The ScriptENGINE automatically starts the next state once the current one completes, by looking for another compatible OnStateRun...() function.

Once all queued states have been processed, the program will end.