Turpidge Developer's Guide

Turpidge is a javascript game engine for powering web-based tactical role-playing games.

A game is built on Turpidge by setting variables and instantiating objects in various javascript files. User interface elements are set as variables in the userInterface.js file. Characters, both good guys and bad guys, are created in the characters.js file. The maps that make up the world your game takes place in are created in the locations.js file. Items are created in items.js, spells and status conditions are created in spells.js, and battles are created in battles.js. There are also some important variables to set in settings.js.

All of the javascript files, as well as the stylesheet, are brought together in the html file (e.g., TheAdventuresOfStickman.html). The html file does little more than this, actually, so it is advisable to just copy the code from TheAdventuresOfStickman.html and change the title tag indicate the title of your game.

Settings

Most of the variables in settings.js are pretty straight-forward, but there are a few that warrant a bit of an explanation. The first is tileSize. This variable determines the size of everything in the game. Locations are comprised of tiles [tileSize] pixels square. All of the graphics you will need to create will be this size, the only exception being the sprite sheets for characters, which will be comprised of 12 tiles, each tile being [tileSize] pixels square.

The other two variables that may need some explanation are centerOffsetX and centerOffsetY. These offset where the center of the action is to adjust for user interface elements that might otherwise get in the way.

Interface

User interface elements are set in userInterface.js. There are splash screen elements: startScreen, prologue, and epiloge; and control elements: nonbattleControls, battleControls, and scoreBoard. These elements are just html code put into javascript string variables. You can use whitespaceStripper.html to conveniently remove line breaks and escape quotation marks from your html code. You can also use interfaceViewer.html to see a preview of how these elements will appear in your game.

The startScreen element is the first thing the player sees when your game starts. If it is smaller than the player's browser window it will be positioned in the center of the window. The startScreen should have a button or link that calls newGame(), to start a new game, one that calls continueGame(), to continue a saved game, and one that calls openGuide(), so the player can see the game guide.

The prologue and epilogue elements are similar to the startScreen, except that they are arrays of screens. Each screen in the array should have a button or link that calls prologueNext() and epilogueNext(), respectively. Calling prologueNext() from the last screen of the prologue will begin the actual game. Calling epilogueNext() from the last screen of the epilogue will take the user back to the startScreen.

The nonbattleControls element defines the control panel for when the player is not in battle. It must contain an html element with id "controlsHead", an html element with id "panel", and an html element with id "controlButtons". The controlButtons element must contain buttons with ids "teamButton", "magicButton", "itemButton", and "cancelButton". These buttons should call teamHandler(), magicHandler(), itemHandler(), and closeControls(), respectively. There is also an itemControlButtons element that defines buttons that are specific to item-related functions. The ids of these buttons should be "useButton", "giveButton", "equipButton", "unequipButton", "dropButton", and "cancelButton". These buttons do not need to be set to call any functions, because that is handled by Turpidge. The unequipButton should be disabled by default, though.

The battleControls element defines the control panel for when the player is in battle. It must contain an html element with id "controlsHead", and an html element with id "panel". It must also contain buttons with ids "attackButton", "magicButton", and "itemButton", that call attackHandler(), magicHandler(), and itemHandler(), respectively. It must also contain a button that calls endTurn(). An id is not necessary on the endTurn button.

The scoreBoard element, along with the scoreBoardPlayerChar and scoreBoardEnemyChar elements, defines the scoreboard that keeps track of the combatants in battle. These elements are a bit more complicated than the others, so it is advisable to just copy the text from the demo game and change the appearance with the stylesheet. These elements do need to exist, however, so if you decide not to use the scoreboard just set it to hidden in the stylesheet.

The nonbattleControls, battleControls, and scoreBoard elements also have corresponding functions for positioning them on the screen (positionNonbattleControls(), positionBattleControls(), and positionScoreBoard(), respectively). These functions are optional, but they do need to exist, so if you decide not to use one just leave the function empty or return null.

Characters

Characters are created in characters.js. There are two kinds of characters: player characters and enemy characters. This file is also where level templates are set up. The level templates determine what changes occur to player characters when they level up. The level template section must come first in the file, which may seem counter-intuitive, but it doesn't actually have to be written first (This will be explained below).

You will need to create images for your characters in the form of sprite sheets. The sprite sheets should be comprised of four rows of three tiles. The rows correspond to the four directions the character can be facing. The top row is facing down, or toward the player. The second row is facing right. The third row is facing left. The bottom row is facing up, or away from the player. Columns of the sprite sheet correspond to states of action. The left column is the character just standing there, the middle column is the character taking a step, and the right column is the character attacking. You can use characterViewer.html to see a preview of how the characters will appear in your game.

The first step of setting up player characters is to instatiate the playerCharacters object. Then, individual characters are added using the addCharacter() method of that object. The addCharacter() method requires the following parameters, in the following order:

name - String. Each character must have a unique name.
attack - Integer. Attack power.
defense - Integer. Resistance to attack.
maxHP - Integer. Maximum HP.
maxMP - Integer. Maximum MP.
speed - Integer. Determines how frequently the character gets a turn in battle.
moveRange - Integer. Determines how far the character can move each turn in battle.
attackRange - Integer. Determines how close the character must be to an opponent to attack it.
image - String. The filename of the sprite sheet image.
charClass - String. Determines which level template the character uses. Also determines which items the character can be equipped with.

Once a character is created, there are functions that can be called to get it further set up. However, these functions require other parts of the game to be defined first. For instance, after you have defined spells (in spells.js) you can use the learnSpell() method of the character object to give it spells. The learnSpell() method requires one string parameter: the name of the spell. Similarly, after you have defined items (in items.js) you can use the giveCharacterItem() or giveCharacterEquipment() method of the items object to outfit your character with items. These methods require two parameters: the character object that will get the item and the name of the item (as a string). The difference between these methods is that giveCharacterEquipment() equips the item after giving it to the character.

Another helpful function is the levelUpTo() method of the character object. The only parameter it requires is the level you want the character to start at, as an integer. The levelUpTo() method uses the level template for that character's class, so the level template section of characters.js must be written before this method can be called.

To begin setting up the level templates you must instantiate the levelTemplates object. You must also set the levelingConstant variable. The levelingConstant is factored into an equasion that determines how many exp a character needs to get to the next level. Then, templates are created by calling the addTemplate() method of the levelTemplates object. This method only requires one parameter: the charClass that the template corresponds to, as a string. Once created, a template doesn't actually do anything until you add stats and spells to it.

Stats are added to the template by calling the addStat() method of the template object. This method requires two parameters: the name of the stat (e.g., "attack" or "maxHP"), and the percent by which it should increase each level, as an integer (e.g., 15 for 15%). Spells are added to the template by calling the addSpell() method of the template object, which also requires two parameters: the name of the spell and the level at which the character should learn it.

Enemy characters are a little bit different from player characters. They are prototypes, in the sense that a battle may include many copies of a single enemy character. Creating enemy characters is very similar to creating player characters. Start by instantiating the enemyCharacters object, then call the addCharacter method of that object to create the characters. This method requires the same first nine parameters as the playerCharacters.addCharacter() method (name, attack, defense, maxHP, maxMP, speed, moveRange, attackRange, and image), plus the following three parameters, in the following order:

mode - String. Lowercase letters a, d, and s, in order of priority of attacking, defending and supporting. For instance, an enemy character with mode "ads" will be most likely to attack and least likely to support, and an enemy character with mode "sad" will be most likely to support and least likely to defend.
money - Integer. How much money a player character gets for defeating this enemy character.
exp - Integer. How much exp a player character gets for defeating this enemy character.

Once an enemy character is created you can use the learnSpell() method of that character to give it spells, and the giveCharacterItem() method of the items object to give the character items, the same as with player characters. You cannot use the giveCharacterEquipment() or levelUpTo() methods, however, because enemy characters do not level up and cannot use equipment.

There are two methods of an enemy character object that can be defined in characters.js: onDefeat(), and bossStrategy(). You can set these methods up to do whatever you want, but they cannot require any parameters.

The onDefeat() method is called by Turpidge when the character is killed in battle, allowing you to define an action to take place when the character is defeated. The bossStrategy() method is a bit more complicated. If defined, this method overrides all of the functions in Turpidge that determine and execute that character's strategy. This gives you complete control to make that character do anything, but you will have to write it all yourself. Unfortunately, a discussion of everything this entails is beyond the scope of this guide.

Spells

Spells are created in spells.js. This is also where status conditions are created. Status conditions are inflicted on characters and alter the characters' stats temporarily.

Start by instantiating the spells object, then create spells by calling the addSpell() method of that object. The addSpell() method requires the following parameters, in the following order:

name - String. Each spell should have a unique name.
image - String. Filename of the spell's image. This image should be [tileSize] pixels square.
canTarget - String. "ally" or "enemy". Determines who the spell can be cast on.
mp - Integer. Cost of casting the spell.
range - Integer. Determines how close a character must be to cast the spell on it in battle.
splashRange - Integer. Determines how close a character must be to the spell's target to also be affected.
effects - String. A comma delimited list of numbers that determine the spell's effect on various stats of the target character.
effectStats - String. A comma delimited list of character stats corresponding to the effects, that determines which stats are effected.
cures - String. A comma delimited list of status conditions the spell cures.
inflicts - String. A status condition that the spell inflicts.

To create status conditions, first instatiate the statusConditions object, then call the addCondition() method of that object. This method requires the following parameters, in the following order:

name - String. Each condition should have a unique name. The name should describe a character in that condition (i.e., "This character is [name].").
effects - String. A comma delimited list of numbers that determine the condition's effect on various stats of the target character.
effectStats - String. A comma delimited list of character stats corresponding to the effects, that determines which stats are effected.
counters - Integer. Determines how long it will take for the condition to wear off. Conditions last at least one turn. After that, one counter is removed each turn and the fewer counters are left the more likely the condition will wear off that turn. When there are zero counters left there is 100% chance the condition will wear off.

Items

Items are created in items.js. There are two kinds of items: usable items and equippable items. An item can be given to a character in characters.js, so the character starts out with the item, but items can also be bought, won, and found during the course of the game.

The first step is instantiating the items object. Then, usable items can be created by calling the addUsableItem() method of items. This method requires the following parameters, in the following order:

name - String. Each item created should have a unique name.
image - String. Filename of the item's image. This image should be [tileSize] pixels square.
useEffects - String. A comma delimited list of numbers that determine the item's effect on various stats of the target character.
useEffectStats - String. A comma delimited list of character stats corresponding to the useEffects, that determines which stats are effected.
cures - String. A comma delimited list of status conditions the item cures.
inflicts - String. A status condition that the item inflicts.

Equippable items can be created by calling the addUsableItem() method of items. This method requires the following parameters, in the following order:

name - String. Each item created should have a unique name.
image - String. Filename of the item's image. This image should be [tileSize] pixels square.
equipClasses - String. A comma delimited list of charClasses that determines which characters can be equipped with the item.
equipType - String. The type of equipment the item is (e.g., "Weapon" or "Armor"). A character can only have one item of each type equipped at a time.
equipEffects - String. A comma delimited list of numbers that determine the item's effect on various stats of the equipped character.
equipEffectStats - String. A comma delimited list of character stats corresponding to the equipEffects, that determines which stats are effected.
spell - String. The name of a spell that is cast when a character uses the item in battle.

Locations

The world your game takes place in is created in locations.js. The world is comprised of individual location objects that link together. The location objects are themselves comprised of space objects that represent individual spaces that are each [tileSize] pixels square. Locations can also contain interactive things, represented by thing objects. You can use locationViewer.html to see a preview of your locations as you make them.

First you must instantiate the locations object and set the default space. Set the default space by calling the setDefaultSpace() method of the locations object. This method requires the following parameters, in the following order:

color - String. An html compatible representation of a color (e.g., "#ff0000" or "red").
image - String. Filename of the space's background image. This image should be [tileSize] pixels square. Pass an empty string to give the space no background image.
walk - Integer. 1 indicates that characters can walk in this space. 0 indicates they cannot.

Now locations can be created using the addLocation() method of the locations object. This method requires three parameters: name, width and height. The name is a string that identifies the location. Each location should have a unique name. Width and height are integers that represent the width and height, respectively, of the location in spaces. The coordinates of the spaces start with 0-0 at the top left corner. The x coordinate increases each space to the right, and the y coordinate increases each space down.

All of the spaces in a new location will be the default space. Individual spaces can be set using the setSpace() method of the location object. This method requires five parameters, starting with the x and y coordinates of the space, both integers. The following three parameters are the same color, image, and walk parameters as the setDefaultSpace() method. Rectangular chunks of spaces can be set all at once with the setArea() method of the location object. This method requires seven parameters: the x and y coordinates of the top left space, the x and y coordinates of the bottom right space, and the color, image and walk parameters.

With more than one location created, a link can be created from a space on one location to a space on another using the setLink() method of the location object being linked from. This method requires three parameters, starting with the x and y coordinates of the space on that location. The third parameter is a string that indicates the location and space being linked to. This string is comprised of the name of the location being linked to, followed by the pipe character ("|"), the x coordinate of the space being linked to, a hyphen ("-"), and the y coordinate.

Interactive things can be added to a location using the addThing() method of the location object. This method requires the following parameters in the following order:

name - String. Each thing should have a unique name.
x - Integer. The x coordinate of the space the thing occupies.
y - Integer. The y coordinate of the space the thing occupies.
image - String. Filename of the thing's image. This image should be [tileSize] pixels square.

Things are made interactive by defining the click() method of the thing object. This method requires no parameters and is triggered when the player clicks on the thing. The click() method can call the openDialog() function, which opens a dialog bubble that can be filled with text or html code. This function requires two parameters, starting with the thing object that has been clicked (i.e., "this"). The second parameter is the text or html code as a string.

Battles

Battles are set up in battles.js. First the battles object must be instantiated, then battle objects are created by calling the addBattle() method of the battles object. This method requires the following parameters, in the following order:

name - String. Each battle should have a unique name.
playerPositions - Array of Strings. Each string is comprised of the x and y coordinates of a space separated by a hyphen. Player characters will be placed in these spaces at the beginning of the battle. The array should have at least as many strings as there are player characters.
spoils - Array of Strings. Each string is the name of an item that the player wins upon winning the battle. If an integer is included in the array the player will win that much money upon winning the battle.

Once the battle is created enemy characters are added by calling the addEnemy() method of the battle object. This method requires three parameters: the name of the enemy character, and the x and y coordinates where that character starts.

Battles are attached to locations in locations.js. To attach a battle, simply set the battle attribute of the location object to the battle object. For convenience, the getBattle() method of the battles object returns the battle object. The only parameter this method requires is the name of the battle object. Once the battle is attached to the location it will be triggered whenever the player moves to that location.

By default battles are non-recurring. This means that once the player has won a battle, it is removed from the location. This can be changed by setting the recurring attribute of the battle object to true. Recurring battles just reset every time they are won.

When the player wins a battle the onWin() method of that battle object is called. This method requires no parameters and can be defined to perform whatever actions you want to take place when the battle is over. The onWin() method of the final battle should call endGame().