Background
Embedded scripting engines have applications in several areas, including the ability to extend or modify the core functionality of a software application. In the game development world, scripting provides a means for the game engine developer to hand over control to the designer, allowing him or her to implement the game's plotline events, NPC behaviour, and so on, without the intervention of the game engine developer who may otherwise need to hard-wire game play logic into the game engine.
Introduction
The final article relating to the Conscript embeddable scripting engine for .NET presents an implementation of an IDE for Conscript, with functionality and look-and-feel reminiscent of Microsoft Visual Studio and other similar IDEs.
The IDE Windows application is included with this article in C# source form, and consists of the code for the scripting engine itself, the IDE, and additionally, an illustrative host function module to provide trigonometric functions and the ability to render 2D graphics. By default, the IDE application itself is a host function module that provides a Print
function to allow for text output within the IDE's output window. Details for extending the scripting language with host functions is illustrated in the Dungeon of Despair scripted-game article presented as part of the Conscript article series. Techniques applied to integrate the Conscript scripting engine within the IDE application are illustrated in the previous articles, and hence will not be repeated here.
Using the Conscript IDE
The IDE window layout consists of a script source panel on the left-hand side, a virtual machine details panel on the right-hand side, and an output window at the bottom. In addition, a status bar beneath the output window provides compilation status and text cursor coordinates.
The script panel is a tabbed control that allows editing of multiple scripts. The IDE provides a ScriptLoader
implementation that overrides the default script loading behaviour by giving priority to scripts loaded in the IDE. This allows one script within the IDE to include another script in the IDE even if it is not committed to disk.
The VM panel is also a tabbed control that provides access to compiled Conscript byte code, global, script, and local scopes, calling and parameter stacks, and thread locking states. The Byte Code tab within the VM panel allows setting of breakpoints, and also highlights the currently executing instruction during debugging.
The Scope tabs allow viewing and editing of variables in the Global, Script, and Local scopes during debugging. The Stack tabs allow viewing of the current call stack and the parameter stack that regulates variable scoping within functions. Finally, the Locks tab displays the state of synchronisation locks used in multi-threaded scripts.
The output panel provides compilation logs, and also acts as an output device for the Print()
host function provided by default.
The menu strip of the application is organised in a traditional layout, and consists of the menus File, Edit, Build, Debug, and Help. The File menu provides script source management and termination of the IDE. The Edit menu provides standard Undo/Redo and Cut/Copy/Paste functionality. The Build menu allows incremental or full re-building of scripts. Incremental building essentially only compiles modified scripts, while re-building discards all compiled scripts and recompiles them from scratch. The Build menu also provides access to a Build Settings dialog to control debug code generation and code optmisiation, and to a Host Environment dialog to allow registration of host function module plug-ins. The Debug menu provides standard debugging functionality including single-stepping, monitored execution, the ability to step into, over, and out of functions, and toggling and clearing of breakpoints. Finally, the Help menu provides access to an informative dialog box.
Using the Graphics Host Function Module
The illustrative module plug-in included in the source code implements two host function modules: one for basic trigonometric functions, and the other for simple 2D graphics. The trig functions provided are:
any math_abs(any);
float math_acos(float);
float math_asin(float);
float math_atan(float);
float math_atan2(float, float);
float math_ceiling(float);
float math_cos(float);
float math_cosh(float);
float math_e();
float math_floor(float);
float math_log(float);
float math_log2(float, float);
float math_max(float);
float math_min(float);
float math_pi();
int math_round(float);
float math_round2(float, int);
any math_sign(any);
float math_sin(float);
float math_sinh(float);
float math_sqrt(float);
float math_tan(float);
float math_tanh(float);
float math_rand(float);
The functions provided by the graphics module are:
bool Gfx_Initialise(int, int);
bool Gfx_Shutdown();
bool Gfx_Clear();
bool Gfx_SetColour(int, int, int);
bool Gfx_SetLineWidth(int, int, int);
bool Gfx_DrawLine(int, int, int, int);
bool Gfx_DrawRectangle(int, int, int, int);
bool Gfx_FillRectangle(int, int, int, int);
bool Gfx_DrawEllipse(int, int, int, int);
bool Gfx_FillEllipse(int, int, int, int);
bool Gfx_DrawString(int, int, string);
The following script, also included with the module plug-in, illustrates the use of the Graphics host functions:
function main()
{
Gfx_Initialise(640, 480);
var intensity = 0;
for (var index = 0; index < 400; index += 10)
{
Gfx_SetColour(255 - intensity, 0, intensity);
intensity += 5;
Gfx_DrawLine(0, index, 400 - index, 0);
Gfx_SetColour(intensity, 255, 0);
Gfx_FillEllipse(index, 200, index / 4, index / 4);
Gfx_SetColour(0, 0, 0);
Gfx_DrawEllipse(index, 200, index / 4, index / 4);
}
for (var pause = 0; pause < 200000; pause++);
Gfx_Shutdown();
}
Related articles
History
- 14/Mar/2008 - First version released.