Game Engine C++

2D Game Engine C++ Cross-Platform Games Engine

Mitorah Games Engine™ Documentation - Version 0.8

MGE is still in development.

Table of Contents


Introduction

Quite a lot of game developing with the engine is done without touching code at all by editing and adding various text data files which for example tell what graphics to load and how and when to use them.

Those data files are designed with simplicity and flexibility in mind.

The MGE GUI Tool add-on can even create those MGE text data files for you.

The Mitorah Games Engine is robust, fast and yet very easy to use.

To get your feet wet, we recommend going through the included tutorials after installing the engine.

After that, this documentation will give you more knowledge on how to use the engine and how it works.

Table of Contents

Technical Basis

The game engine is written in C++ and it targets DirectX 5 and above on Windows 95 and newer.

The Windows version of the sound system requires DirectX 6. No sounds will be played by it if the user has DirectX 5 but everything else should work.

It works with Limited User Accounts too, so the end user doesn't have to be admin.

Some of the engine's behavior changes by editing the easily readable options.ini file, which if not present, forces the loading of default settings.

The rendering architecture supports two modes, a hardware accelerated mode for modern effects and a 2D non-accelerated compatibility mode for older computers.

Both modes use the same basic interface for drawing, but the underling hardware accelerated mode uses Direct3D7 and the non-accelerated mode uses custom DirectDraw rendering code that internally writes directly to the bits of a system memory off-screen surface.

Both modes support alpha source, alpha destination, alpha modulation, color modulation, additive blending, rotation, line drawing, filled polygons, and both bilinear and nearest-point scaling.

Table of Contents

Installation

Windows:
  • If you want to use the .lib version of the engine: Add the path to the Visual C++ libraries to the common project settings. For example the line: C:\MGEngine\MGE_VCLib\release. This is to make things easier.
  • Necessary project configuration properties: (You can also just copy a tutorial's project file's settings)
    • Whole Program Optimization: Use Link Time Code Generation
    • C/C++ -> Preprocessor definitions: WIN32;NDEBUG;_WINDOWS
    • C/C++ -> Code generations -> Run-time library: Multi-threaded (/MT)
    • C/C++ -> Language -> Enable run-time type info: Yes
    • Linker -> Input -> Additional dependencies: zdll.lib vorbisfile_static.lib vorbis_static.lib ogg_static.lib randomac.lib If you want to use the .lib version of the engine: MitorahGamesEngine.lib (or one of the other MGE libraries if using the static library version of MGE.)
Table of Contents

Installation Notes

Windows:

The most common reason why the Mitorah Games Engine fails to build is due to the lack of required software to build it. Ensure that you have the following before building:
  • The Microsoft DirectX SDK (not just the runtime).
    http://www.microsoft.com/directx

  • The Windows Platform SDK (VS2005 Express does NOT include this by default but Pro does).

    Click to Download.

    Do not be alarmed by the title "Windows Server 2003 SP1 Platform SDK Web Install".
    This allows you to develop for not just Windows Server 2003 but Windows XP/x64/etc.

    You will then need to manually add the paths for the Platform SDK to your search paths in
    Visual Studio:

    Go to Tools->Options->Projects And Solutions->VC++ Directories
    Add the paths to the appropriate subsection:

    Executable files - C:\Program Files\Microsoft SDK\Bin
    Include files - C:\Program Files\Microsoft SDK\include
    Library files - C:\Program Files\Microsoft SDK\lib

  • If you are using Visual Studio 2005 Express, make sure you add these additional libraries to your
    Linker's include settings: gdi32.lib advapi32.lib shell32.lib
Table of Contents

System Requirements for most games using this engine

Windows:
  • Windows 95 or newer
  • DirectX 5 drivers or newer. DirectX 7 or newer recommended.
  • 4 MB or more of video card memory
  • 64 MB or more of RAM
  • CPU: 350 MHz Pentium or better
Macintosh:
  • Mac OS X or newer
  • OpenGL 1.x drivers or newer
  • ...
Linux:
  • OpenGL 1.x drivers or newer
  • ...
Table of Contents

Resource loading

The game engine can load .jpg, .png and .gif images.

It can load resources from Bon packs or from normal files as usual.

Those Bon packs are ZLib compressed .zip like packs which only WinBon and Mitorah Games Engine can open.

All Bon packs must be in the "res" sub-folder of the game's installation folder by default. You can modify the folder name by modifying the MGE_ResourceLoader::BonPacksDir.

If you use the LoadGraphic(), the text data file's name without file extension is set to be the image name. Same goes with the other types of resources.

For more information, see the below section and MGE_ResourceLoader.h.

Table of Contents

Reloading of modified resources when the game is running

Summary: This happens automatically when you have DEVELOPMENTMODE defined as TRUE and PLATFORM defined as WINDOWS (and if you don't have the source version, link with the MitorahGamesEngine_DevMode.lib).

When you first load any MGE resource file except those in .bon files, the last modified time gets recorded along with the file name.
When you switch out of the game and go back to the game, the game automatically re-loads all modified and already loaded files so you can see the changes immediately.

For example: You have LoadAlertBoxes(AlertBoxes.mab); in your loading function.
If you launch the game, switch to notepad which has opened the file AlertBoxes.mab, modify it, save, and go back to the game, the changes become effective immediately without having to restart the game.

Table of Contents

Image Opacity

The alpha channel in .png images is loaded if present.

You can also automatically load the alpha channel of an image from another image with the name -BaseImageName. (With all image types.)

The alpha channel images should be pure black and white. So the R, B and G values of a pixel should be equal.

All other images' pixels of color Magenta (FFFF00FF) are set to transparent.

Table of Contents

Loading Thread

Using the loading thread is optional but recommended for smooth displaying of progress.

The progress % is updated automatically based on the user's previous time taken to execute the specific loading screen.
So the first estimate will be inaccurate unless you happen to guess the time it will take on someone else's computer.

It is optional but recommended to install or create a file named LoadingScreenTimes1.tim in the folder where the game's executable is.
The file should only have a rough (double number) estimate of the seconds the loading will take.

It is recommended that you run the loading on your own computer and just add your LoadingScreenTimesX.tim file to the installer.
The number of .tim files you need is equal to the number of loading screens you have. Most 2D games have only one.

To be able to use the loading thread, you need to create a new version of the ProcessLoadingThread() Function.

void Game::ProcessLoadingThread()
{
Sounds->StartSoundThread();
// etc.
}

A simple way to use the loading thread:

StartLoadingThread();
while(!g_LoadingThreadFinished)
{
Update();
Nap(10); // This is a cross-compatible version of the Sleep function
}

After the loading thread has finished, you should have this code:

ResourceLoader->FinishLoading();
#if DEVELOPMENTMODE == TRUE && PLATFORM == WINDOWS
ResourceLoader->EndLoading();
#else
delete ResourceLoader;
ResourceLoader = NULL;
#endif

See a tutorial's code for a complete example of using the loading thread.

Table of Contents

Things you shouldn't do in the loading thread because of multi-thread safety:

  • Change the screen state.
  • Change the game state.
  • Call ResourceLoader->LoadFont(...).
  • Call ResourceLoader->LoadAlertBoxes(...).
  • Add something to containers such as DrawingOrder or Images and other containers of Graphics which are used by the main thread.
    However it is safe to use all of the ResourceLoader functions (except LoadFont and LoadAlertBoxes) because they have been made multi-thread safe.
  • Draw anything manually. For example don't use Graphics->DrawRect(...) or Animations->Draw(...). All functions like that add an element in the DrawingOrder.
  • Use ScrollBars->Add(...) or ProgressBars->Activate(...).
  • Call an alert box.
  • Modify Graphics->AlignTextToRect
Table of Contents

Demo recording and play-back

The Mitorah Games Engine has full demo recording and play-back; great for bug fixing and tutorials.

Every action of the recorder is recorded and then displayed on play-back.

The demos are as easy to watch as watching someone else playing.

Optimized low output file size and no performance penalty.

While each of the platforms supports this functionality, a demo recorded in Windows for example can't be played on Mac.

Related mouse actions:

RECORDDEMO // Demos->Record(theMouseActionParameter);
PLAYDEMO // Demos->Play(theMouseActionParameter);
STOPRECORDINGDEMO // Demos->StopRecording();

For example: Functionality on left-click: RECORDDEMO "UserDemo.mgd";

If DEVELOPMENTMODE == TRUE && ENABLEDEMOS == TRUE:

Press F6 to start recording to LastRecordedDemo.mgd. (Blocked while playing.)
Press F7 to start playing LastRecordedDemo.mgd. (Blocked while recording.)
Press F8 to stop playing/recording.

You can also of course manually call the functions in MGE_Demos.h.

Table of Contents

The Sound System

The sound system of the engine supports .ogg files and is running on its own thread using a message-based system, so you can even start playing your game before the sounds have been loaded etc.

The sound system has been ensured to be multi-thread safe.

You can load (and play) a sound by calling MGE_ResourceLoader::LoadSound(const char *theFilename, bool MusicTrack, bool Play = false, bool FromBonPack = true).

If FromBonPack, the sound will be loaded from MGE_ResourceLoader::BonPacksDir + ("music.bon" or "sfx.bon").

You can also play a sound with the PLAYSOUND "sound name without file extension"; Mouse Action (Use PLAYSOUND_LOOP if you want it to be looped) and by calling Sounds->Play(string theName, bool Loop = false).

For example: Functionality on mouse over: PLAYSOUND "woodknock1";

In options.ini:

Soundeffects volume attenuation:
0

Music volume attenuation:
0

Music muted:
0

Soundeffects muted:
0

Wait for sounds when loading:
1

(If 1, the loading won't finish before the sound messages have been processed. If 0, the game proceeds without waiting for the sounds to be loaded but the game's performance will be low before the sound messages have been processed on many systems.)

See MGE_Sound.h for more information.

Table of Contents

MGE Font Data Builder

Creates the text-based font data file for you from an image with all of the default chars.

Example font image

Remember that there absolutely has to be one pixel between all characters of a font image so that the font builder knows when a character's pixels end.

So for example the " char area often ends up having to be manually corrected (and the next char area row deleted) or you need to draw a near transparent pixel in between the ' and ' on the font image before using the tool.

All characters of a font image should be in a single row with a transparent background.

All font images should be in the .png format at least until the font data has been built because the font data builder can only read .png files.
You are free to convert it to some other format afterwards.

You can also build the font data manually which is easy but takes time.

When loading a font, the font image and font data should be in the same folder or pack.

Table of Contents

Drawing

Drawing happens automatically for MGE Data files.

You can add something to the DrawingOrder manually by calling Graphics->DrawX();
That something will be drawn automatically until you either remove it from the drawing order
(using the mouse action REMOVE or by calling MGE_ResourceManager::RemoveFromDrawingOrder(string theName) or change the screen state.

You can also manually draw something using the Graphics->ReallyDrawX() functions
but then you would have to call them on every update and in the proper order, eliminating the usefulness of MGE_ResourceManager and the partial drawing on update optimization.
So it is not recommended to use those functions unless you want to port a certain type of game to use the engine.

See MGE_Graphics.h for more information.

Table of Contents

Timing and updating

The MGE_Base::Update method is called as fast as possible and the screen in re-drawn on every update if necessary.

Often over 100000 times a second if g_AlwaysFullRedraw is false and 3D accelerated but often less than 200 times a second if g_AlwaysFullRedraw is true and not 3D accelerated.

So you can't base your game's timing logic on update call counts or refresh rate and you should instead use the MGE_Timer.

You can easily use fixed timing with the engine by limiting the amount of Update calls.

To do this you have to call your own MGE_Base::Start like function in main() and never call MGE_Base::Start.

For example:

Timer BloodDropRate;

Timers->SetTimer(BloodDropRate, 0.025); // Seconds
...
if(Timers->HasTimeElapsed(BloodDropRate))
{
DoSomething(Timers->GetTimeElapsed(BloodDropRate));
Timers->ResetTimer(BloodDropRate);
}

In addition, the MGE_Timer class has the following functions:

void GetCurrentCount() // Updates the internal count, this is called automatically by MGE_Base::Update() so unless you want extreme precision, you don't need to call this manually.
double GetTimeLeft(Timer &theTimer) // Returns how much time is left from the setting or resetting of the timer in seconds.
double GetMSLeft(Timer &theTimer) { return (GetTimeLeft(theTimer) * 0.001); }

GameVar Timers and timers related mouse actions and HasTimeElapsed mouse action condition are also supported:

SETTIMER // GameVars->SetTimer(string theName = theMouseActionParameter.substr(0, FirstComma) , the double after the , in theMouseActionParameter);
RESETTIMER // GameVars->ResetTimer(string theName = theMouseActionParameter);

When using HasTimeElapsed as a mouse action condition, use {} instead of ().

For example:

Functionality on mouse over: if(HasTimeElapsed{TestTimer}) PLAYSOUND "woodknock1"; if(HasTimeElapsed{TestTimer} == ABoolGameVar) SETTIMER "TestTimer,DoubleGameVarSeconds";

Table of Contents

Mouse Cursors

You can load the custom mouse cursor and its variants by calling the MGE_ResourceLoader::LoadMouseCursor(string theFilename, bool LookForAlpha = false, bool FromBonPack = true) function.

If you call the function with FromBonPack true, theFilename needs to only tell the file name in the Bon Pack.

The mouse cursor gets drawn automatically when appropriate.

You can hide the mouse cursor by calling Game::HideMouseCursor() and unhide it by calling Game::UnhideMouseCursor().

You can change the Use Custom Cursors Mode in Options.ini or by calling MGE_Base::SwitchCustomCursorsMode().

You should name your mouse cursor files as defined here:

Normal cursor = "Cursor" + File extension.
Text cursor = "TextCursor" + File extension.
Cursor displayed when the user is able to left-click and right-click something = "CursorAbleToLeftAndRightClick" + File extension.
Cursor displayed when the user is able to left-click something = "CursorAbleToLeftClick" + File extension.
Cursor displayed when the user is able to right-click something = "CursorAbleToRightClick" + File extension.
Cursor displayed on top of the normal cursor when the user is able to drag something = "CursorAbleToDrag" + File extension.

You don't need to have any of these cursor images and the program will still work just fine because it will then use the default OS cursors.

If you include a CursorAbleToDrag, you must include the line CursorAbleToDragOffsets = [X Offset]/[Y Offset] at the bottom of GameAttributes.mge. For example: VersionNumber = 0.8
CursorAbleToDragOffsets = 7/13

Table of Contents

Alert/Dialogue boxes

MGE alert boxes are basically pop up images with a no/close button, optionally a yes button, optionally a cancel button and text aligned on the alert box, much like operating system alert boxes.

Optionally, they are mouse-drag moveable and/or their text editable by the user.

You can load the alert boxes by simply calling MGE_ResourceLoader::LoadAlertBoxes(string theFilename).
theFilename should be the path to the alert boxes text data file from the folder where the executable is.

See AlertBoxesTemplate.txt to learn what to put in the alert boxes text data file and to learn about the functionality of an alert box.

The user can close alert boxes by either pressing Esc (chooses No) or by clicking the Close/No button or the Cancel button or the Yes button or by pressing Return (chooses Yes).

See MGE_AlertBoxes.h for more information.

Table of Contents

Animations

Mitorah Games Engine supports animations in an easy, yet extremely robust way.

What makes it more robust than usual is that you use an MGE image data file to define an individual animation frame and that gives you a lot of options.

Animations can be loaded with MGE_ResourceLoader::LoadAnimation(string theFilename) or MGE_ResourceLoader::LoadFolderContents(string theFolderPath, CONTENT_ANIMATIONS);

For more information, See AnimationTemplate.txt / MGE_Animations.h

You can define when the animation is to be drawn and played automatically in the .mga file or you can use MGE_Animations::Draw(string theName) or the Mouse Action DRAWANIMATION.

Table of Contents

Progress bars

You can use the progress bars to graphically display the loading progress, timer progress, golf hitting speed etc.

You can load a progress bar file with the MGE_ResourceLoader::LoadProgressBar(string theFilename) function.

You are unlikely to manually need to use any of the MGE_ProgressBars methods.

See ProgressBarTemplate.txt / MGE_ProgressBars.h for more information.

Table of Contents

Sliders

You can use the sliders to graphically display and adjust (on the slider by pressing the left mouse button) a variable with a certain maximum value.

You can load a slider file with the MGE_ResourceLoader::LoadSlider(string theFilename) function.

You are unlikely to manually need to use any of the MGE_Sliders methods.

See SliderTemplate.txt / MGE_Sliders.h for more information.

Table of Contents

Check boxes

You can use the check boxes to graphically display and change with a mouse-click a bool variable.

You can load a CheckBox file with the MGE_ResourceLoader::LoadCheckBox(string theFilename) function.

You are unlikely to manually need to use any of the MGE_CheckBoxes methods.

See CheckBoxTemplate.txt / MGE_CheckBoxes.h for more information.

Table of Contents

Scroll bars

All MGE scroll bars are either vertical or horizontal.

If the scroll bar is horizontal, Up is treated as left and Down is treated as right.

You can load the parts of a scroll bar at once by calling the MGE_ResourceLoader::LoadScrollBar(string theFilename, bool LookForAlpha = false, bool FromBonPack = true) function.
theFilename should be without the _Start etc. extension so that the extensions can be added in the name automatically (to right before the file extension).

If you call the function with FromBonPack true, theFilename needs to only tell the file name in the Bon Pack.

A scroll bar gets added on an automatically added image if the image's text doesn't fit completely on the image and the text is to be aligned on the image or its text area.

Alert boxes also get a scroll bar automatically when the text can't fit otherwise.

If you want to enable automatically added scroll bars, you need to call MGE_ResourceManager::SetAutoAddedScrollBar().

You can add a scroll bar to the drawing order with the MGE_ScrollBars::Add function.

The top scroll bar can also be scrolled with the mouse wheel.

On scroll button mouse over, the scroll button gets rendered twice, the second time additively which creates a highlighting effect.
Unless you call MGE_ScrollBars::Add with HighlightScrollButtonOnMouseOver = false

The height of the base scroll bar images is recommended to be 2. (Or width if it's a horizontal scroll bar.)

You should name your scroll bar files as defined here (anything can be in place of "ScrollBar"):

The base scroll bar block's start = "ScrollBar_Start" + File extension.
The base scroll bar block's middle = "ScrollBar_Middle" + File extension. (The scroll bar' block is filled with this image.)
The base scroll bar block's end = "ScrollBar_End" + File extension.
Scroll up button = "ScrollBar_Up" + File extension.
Scroll down button = "ScrollBar_Down" + File extension.
Scroll up button pressed = "ScrollBar_Up_Pressed" + File extension.
Scroll down button pressed = "ScrollBar_Down_Pressed" + File extension.

Example scroll bar, contains a screenshot of a full MGE rendered one and its individual parts.

See MGE_ScrollBars.h for more information.

Table of Contents

Keyboard input

In Windows, the keyboard input of this engine is handled by listening to WM_CHAR, WM_KEYUP and WM_KEYDOWN messages.

In most cases you'll only use MGE Image data file defined input and perhaps the related Mouse Actions to handle text input.

Sample image data file which enables text input.

Start user input by calling g_Game->Input->StartTextInput(...).
Stop user input by calling g_Game->Input->StopTextInput().

The following keyboard input modes are supported:
INPUT_DISABLED,
INPUT_DEFAULT, // Listen to only ctrl up and down, boss key, pause and print screen messages
INPUT_GAME,
INPUT_NAME,
INPUT_TEXT,
INPUT_SINGLELINETEXT,
INPUT_CHANGEHOTKEY

Supported extra functionality which behaves as expected:
* Clipboard copy, paste and cut
* Delete key
* Insert key
* Arrow keys
* Backspace key
* Escape key
* Return key
* Home key
* End key
* Mouse selecting and de-selecting of text.
* You can restrict the text input to a certain Rect area.

Drawing the user inputted text stretched isn't recommended because the text input cursor will move as if it wasn't stretched.

You should not use in-text automatically updating variables in a text that is keyboard input editable by the player because it can easily cause problems.

Uncomment g_Game->Sounds->Play("ErrorSound"); in MGE_Input.cpp if you want to play an error sound when the user tries to input more characters than the input space allows. You also need to have such a sound available.

Table of Contents

Hotkeys

Default:
  • Pause or continue: Pause whenever or Space when Input->KeyInputMode is INPUT_DEFAULT.
  • Take a screenshot: Print Screen to save a lossless quality .png screenshot to the folder specified in Options.ini. On Windows the screenshot is also placed in the clip board as usual.
  • Jump to work or back to game (boss key): F9.
  • Hotkey changeable in Options.ini.
    On Windows; hides the window so that it cannot be seen anywhere except on the running processes list until you press the key again.
  • Esc: Closes (reported as a 'no' click) the top alertbox or stops text input mode or calls the overrideable g_Game->EscReleased().
Custom:

This has been made as easy and expandable as possible.

In Options.ini, games will have something like this:

Hotkey count:
2

Jump: // the hotkey name
Ctrl // the key's display name
17 // the virtual key code

Spin:
Tab
9

You can add as many as you want in the list.

If you add hotkeys manually, you can just throw any key there initially and go change the hotkey in-game to make the engine find the proper display name and virtual key code combination for you.

The MGE GUI Tool makes adding these even easier.

Whenever a hotkey is released, g_Game->HotKeyReleased(Hotkey index) is called.
Whenever a hotkey press is reported, g_Game->HotKeyPressed(Hotkey index) is called.

By default, neither of the above functions does anything so you must override them to define their functionality yourself.

First you need to declare the function in the Game class with: void HotKeyReleased(unsigned long theHotKeyIndex);

Then you can for example have:

void Game::HotKeyReleased(unsigned long theHotKeyIndex)
{
Graphics->CallFadingText("Hotkey Released: " + Options->HotKeys->Names[theHotKeyIndex], "DefaultFont");
}

Input->KeyInputMode must be INPUT_GAME for HotKeyReleased and HotKeyPressed functions to be called.

To change hotkeys in-game:

You can simply use the images' change hotkey functionality by having a line similar to the below example in a .mgg file:

Input: On left-click; Change hotkey: HotKeyName

Then you can for example have this line as the line below the Input line:
Text: User input Font: "DefaultFont" Area: Limit by image to initially display the hotkey name on the field.

or you can manually start hotkey changing key input mode by calling:

Input->StartTextInput(string *theInputString, int theSpaceBetweenChars, int theSpaceBetweenRows, Rect *theTextArea, const string &theFont, INPUT_CHANGEHOTKEY, ScrollBar* theScrollBar = NULL);

Input->ChangeHotkey(unsigned int *theHotkey, string *theHotkeyName);
// For example: Input->ChangeHotkey(&Options->HotKeys->Keys[HotKeyIndex], &Options->HotKeys->KeyNames[HotKeyIndex]);

Table of Contents

Debug keys

#if DEVELOPMENTMODE == TRUE
F1: Switch3DAcceleration();
F2: Switches to Windowed/Full screen mode
F3: SwitchCustomCursorsMode();
F4: g_SoftVSyncWait = !g_SoftVSyncWait;
F5: g_WaitForVSync = !g_WaitForVSync;

#if ENABLEDEMOS == TRUE
F6: Demos->Record();
F7: Demos->Play();
F8: Demos->Stop();

Table of Contents

Game Variables (GameVars)

GameVars are meant to be used by PreparedTexts, Sliders, Check boxes, Images with a variable position and GameVars related mouse actions but you can have all your game's variables as GameVars.

To declare GameVars, use these functions:

void MGE_GameVars::LoadDeclarations(const char* theFileName = "GameVarsDeclared.cpp");

void MGE_GameVars::DeclareBool(string theName, bool theInitialValue = false);

void MGE_GameVars::DeclareInt(string theName, int theInitialValue = 0);

void MGE_GameVars::DeclareDouble(string theName, double theInitialValue = 0);

void MGE_GameVars::DeclareString(string theName);

void MGE_GameVars::DeclareString(string theName, string theInitialValue);

void MGE_GameVars::DeclareStringArrayPointer(string theName, string* theInitialArray = NULL);

void MGE_GameVars::DeclareTimer(string theName);

It is recommended to use the LoadDeclarations function to declare all your GameVars
because you can change the GameVarsDeclared.cpp file or whatever you name it without re-compiling your program.

The file is only a pseudo .cpp file.
In reality it is just a normal text file which is read by the function as if it was a standard .cpp file with only global variable declarations and comments.

See the sample GameVarsDeclared.cpp file.

You can for example use MGE_GameVars::GetInt(string theName); to retreive an int pointer to an int game var.
You can also use functions like MGE_GameVars::MultiplyInt(string theName, double theMultiplier) without having to get a pointer to the int to modify it.
The other types have similar functions.

GameVars must have been declared and initialized to have a value before text which uses them is loaded.

For more information, see MGE_GameVars.h or MGE_ResourceData.h for a list of the related mouse actions.

Table of Contents

Mouse Actions

The Mitorah Games Engine has all the pre-defined mouse actions you can imagine and some,
so we recommend you to get to know the list before using REPORT or manually added mouse zones.

Whenever you define some mouse actions in a MGE data text file, the MGE mouse zones will be added and handled automatically but you can also add your own custom mouse zones with Interface->AddMouseZone(...) which can go beyond the borders of one image or other data file.

If the ActionID of a MGEMouseZone is > MOUSEACTION_CHECKBOX and the mouse zone is hit, MGEMouseZoneHitReported(HitElement) is executed.

Therefore by setting the ActionID to > MOUSEACTION_CHECKBOX you can also use MGE mouse zones in a custom, non-scripted way which enables you to still get the benefits of automatic mouse zone moving, ordering etc.

Some mouse action samples:

REPORT // Calls g_Game->MGEMouseZoneHitReported(...); Use this to code any extra mouse action functionality which you can't achieve with the other mouse actions.

PLAYSOUND // If you put this action to on mouse over, the sound will be played when the user rolls his mouse over once, and not again before the user takes the mouse off.

REMOVE // Removes the element (widget) which's name equals MouseActionParameter or if MouseActionParameter is empty, removes the element from the drawing order.

DRAWANIMATION // Calls Animations->Draw(theMouseActionParameter); (Animations also give you the option to define when you want it to be drawn automatically so not all programs need to use this.)

Mouse action usage samples:

Functionality on right-click: OPENURL "http://www.mitorahgames.com/";

Functionality on mouse over: if(HasTimeElapsed{TestTimer}) PLAYSOUND "woodknock1";
if(HasTimeElapsed{TestTimer2} == ABoolGameVar) RESETTIMER "TestTimer";

Functionality on left-click: CALL_ALERTBOX "FirstAB";
if(Good > 0) DIVIDEINT "Good,2";

Functionality on left-click: PLAYSOUND_LOOP "Options Music";
CALLFADINGDRAWING "0.55";
OPTIONS; // Here OPTIONS is a custom defined screen state name.

For a complete list of the available over 70 mouse actions, read the MGE_ResourceData.h.

Table of Contents

Conditional Mouse Actions

Scripting conditional things like if, if !, &&, ||, if ==, if !=, if <, if >, if >= and if <= is supported with mouse actions:
  • These can have only GameVars or numbers or strings as parameters.
    You can check if a string is empty or not with the if(!string) or if(string).

  • Sample: if(Text == "Hello") DECREMENTINT "Bad,1";

  • The syntax must exactly match the above sample. You can't have more or less spaces before the == for example.

  • You can't have any parentheses in the condition. Use { } with functions.

  • The only supported function is HasTimeElapsed{GameTimer name}.

    So instead of if(Money >= Cost && HasTimeElapsed(BloodDropTimer) && (DifficultyAllows || IsCheating))

    you would type if(Money >= Cost && HasTimeElapsed{BloodDropTimer} && DifficultyAllows || IsCheating)
Table of Contents

To add and use the manual mouse zones:

(Most casual games don't need these.)

enum MOUSEZONE_TYPES // ClickTypes
{
LEFTCLICK,
RIGHTCLICK,
MOUSEOVER,
LEFTDOWN,
RIGHTDOWN,
ANYCLICK,
ONLYMOUSEOVER
};

Interface->AddMouseZone(unsigned int theZoneIndex, short ZoneXpos, short ZoneYpos, short ZoneWidth, short ZoneHeight, short ClickType);

Add the definition of void CustomHandleMouseInput(); in your Game class

and then have something like:

void Game::CustomHandleMouseInput()
{
switch(Interface->ZoneIndexHit)
{
case 0:
Jeehaw();
break;
}
}

For more information see MGE_Interface.h

Table of Contents

Game States

Game states are basically used so that you could have more screen states in a screen state.
All automatically drawn things support defining what game state(s) the element will be drawn on.

For example if an MGE data file reads:

Screenstates: MAINMENU,
Gamestates: ALL,

It means that whenever the screen state is main menu, the element will be active.

If you had for example PLAYING instead of ALL in the Gamestates field, the game state would also have to be PLAYING for the element to be automatically activated/drawn.

So whenever you change the game state, some elements might be removed from the drawing order and some added to it.

To change the game state, call MGE_Base::ChangeGameState(unsigned int theToGameState) (overrideable)
or simply have the game state's name in a mouse action like this: PLAYING;
or you can just use the game state number + screen state count in a mouse action like this: 12;

Define the number of game states, their numerical order and their names in the GameAttributes.mge (Sample).

Changing the game state doesn't remove any manually drawn elements from the screen.

If you are loading, the game state is ideally set to 0.
The 0 is usually defined as LOADINGSCREEN.

The global variable GAMESTATE is initially 0.

(Other related global variables are: unsigned int GameStateCount and shared_array<string> GAMESTATESTRINGS)

Table of Contents

Screen States

Changing the screen state removes all manually drawn elements from the screen, closes all alert boxes, de-activates all automatically added mouse zones, removes all elements from the drawing order, and initializes the screen.

To change the screen state, call MGE_Base::ChangeScreen(unsigned int theToScreenState, double theSecondsToFullDraw = 0 (if this is not 0, fading drawing will be called)) (overrideable)
or simply have the screen state's name in a mouse action like this: MAINMENU;
or you can just use the screen state number in a mouse action like this: 1;

Define the number of screen states, their numerical order and their names in the GameAttributes.mge (Sample).

The global variable SCREENSTATE is initially 0.

(Other related global variables are: unsigned int ScreenStateCount and shared_array<string> SCREENSTATESTRINGS).

These, Log and the game state ones are the only global variables without the g_ prefix.

Table of Contents

Logging

The logging of the Mitorah Games Engine is very simple, both in code and to use.

To write a line to the MGE generated log file MGEngine.log, Call Log->Write(const string &theText, bool WriteCountCheck = true).

The write count check ensures that the log doesn't write tens of megs of data if something goes wrong but if you want something to be logged surely and it isn't early in the program, call the function with WriteCountCheck = false.

#include <MGE_Game_ExternGlobals.h> to use it in a file which doesn't include the MGE_Base header.
Table of Contents

Random Number Generators

By default, no random number generator is constructed. So to use a random number generator, (MGE_Base::)RandomGen = new MGE_RandomNumberGenerator(); (It is deconstructed on exit automatically.)

The normal RandomGen uses Mersenne Twister, which is by popular opinion, the best software random number generator out there and it has been tested to be fast and to have equal distribution.

The secure RandomGen uses a slightly modified version of ISAAC.

It is cryptographically secure (means that no-one can determine what random number will come next from the outputted random numbers)
and no one has been able to crack it yet, so it would take way too long for someone to crack it even with a super computer.

This is useful for casino software and meets the industry's random number generator security standards.

Use int RandomGen->Random(int min, int max) to generate a number between min and max using Mersenne Twister.

Use int RandomGen->SecureRandom(int min, int max) to generate a number between min and max using the modified ISAAC.

You must have first initialized the secure random number generator by either passing true to the RandomGen constructor or by calling RandomGen->SecureRandInit() afterwards.

Table of Contents

Options

These can all be modified by the developer and the end-user in the file options.ini (which is a text file).

However, making in-game options is recommended of course.

The default settings are loaded if the options.ini file is missing, so you don't have to install it.

The options.ini file explains itself, however here are some additional notes:
- Whenever the user moves the window in windowed mode, the options are saved.

- If lots of things are changing constantly on the screen, you might be better off enabling g_AlwaysFullRedraw but usually it should be false for increased performance (something is then only re-drawn when it changes and only that part of the screen gets re-drawn).

Table of Contents

Installing programs made with MGE

Install the files zlib1.dll, Folders.ini and GameAttributes.mge to the folder where the executable is.

Install the options.ini to the Saves folder.

Create an empty sub-folder named temp (On Windows this is a backup temp folder, in most cases not used).

Create the file CurrentDir.ini to the directory where you install the main executable.
The file should contain just the current directory with the last \ char.

Windows specific:
Create an empty folder named MGETemp to CSIDL_APPDATA.

If you use the default paths, create empty Screenshots and Saves folders as defined in Folders.ini to CSIDL_PERSONAL.

If not, create the folders specified in Folders.ini.
Other than that, you can install however you want to.

Table of Contents

Some of the upcoming features

  • Currently image keyboard input with an auto-added vertical scroll bar isn't working properly.
    We will start to work on this again immediately when the first customer or we need it because we know we will need it.

  • Particle system will be added to the engine when we make Battles of Norghan 2.
    We might release this feature for free or as an add-on.
    Let us know if you really need it sooner.
    With source code however, you could easily add particle effects functionality in the engine yourself using the cross-platform drawing functions there are. (If you've made a particle system before.)

  • We won't need 2D physics for the engine anytime soon, but if enough people do, we can develop a compatible physics library for it as an add-on so let us know if you need it and can't do it yourself.
Table of Contents

You can discuss the engine at www.mitorahgames.com/forums/
Bottom left Bottom right