Legend of Grimrock 1 Modding
Posted: Fri Oct 06, 2023 5:58 pm
by Sir Tawmis
Posting it here because it used to be on the site - prior to the redesign - for preservation purposes.
Modding Grimrock 1
This series of documents and guides is intended for anyone who wishes to create their own Legend of Grimrock custom dungeons and mods. But if you wish to just play mods, you can simply subscribe to them in Steam Workshop or downloading them to your “
Documents\Almost Human\Legend of Grimrock\Dungeons” -folder from
Grimrock Nexus or elsewhere.
Legend of Grimrock comes with a built in dungeon editor and the getting started -guides describe all you need to know if you want to create your own dungeons, complete with monsters, items, puzzles and traps. If you are a little bit more adventurous and if you want to create even more extensive modifications, we have guides for you that will help you get started with scripting in the editor and creating new assets but, due to the breadth of these subjects, we can only scratch the surface here.
The modding and asset usage terms detail what you are and are not allowed to do with mods, custom dungeons and custom assets. You should be familiar with the usage terms before sharing any content you have created. We also cover how you can use and modify the original Legend of Grimrock assets.
Dungeon Editor Basics
When starting the editor you are presented with an empty editor screen and to get going, we should create a new project by going to the “File” -drop down menu and selecting “New Project…”.
In the New Project dialog all we need to do for now is to enter a name for the dungeon and hit create and you should be presented with a blank map with a small room in the middle, where the player party starts in, that we can start working on! First, we’re going to need the draw tunnels tool to carve some empty spaces in the rock so let’s take a brief look at the tools palette: in the top left hand corner we have three buttons: select entity, add asset and draw tunnels. You’ll be switching between these tools pretty frequently so it’s good to learn their shortcuts which can be accessed by pressing 1, 2 and 3 on your keyboard.
Let’s pick the draw tunnels tool and carve some hallways and rooms for the player to get lost in! While this tool is active, left clicking on the map draws tunnels and right clicking draws walls.
Preview
To try out the dungeons you are creating, all you need to do is to press the play button above the preview or F5 on the keyboard. The game will start running and you can move around in the dungeon in the usual fashion with W, A, S and D. You can access fullscreen mode by pressing Ctrl-F while in the preview.
You can freely edit the level while the preview is running. Any changes you make to the level will be instantly reflected in the preview when you press play again. Pressing the stop button will stop the preview and move the player party back to the starting location. The starting location can be easily changed by hovering over the map and pressing Y.
While running the preview in the editor, the player is equipped with a torch that never runs out to ease the testing of the dungeon. This torch will be present only in the editor so when the dungeon is exported, the player party will start without items.
Using Assets
A dungeon with nothing but empty hallways in it isn’t terribly exciting so what we need to liven up the place is some assets! Objects like items, monsters, doors and decorations are all assets and there’s a few assets that are only directly visible to the level designer such as script entities, blockers and timers. Asset browser is used to add instances of assets, which are called entities, to the level and you can use the search or the filter drop down menu to make finding them easier. Adding entities to the level is as simple as picking them from the browser, at which point your active tool is automatically changed to adding assets, and clicking on the map.
The select entities tool (shortcut 1) can be used to select entities so that you can move them around or manipulate their parameters in the Inspector. When one or more entities are selected, they can be moved with W, A, S and D and their orientation can be changed with Q and E. You can delete selected entities with the delete key and the entities can also be cut, copied and pasted with ctrl-X, ctrl-C and ctrl-V.
Re: Legend of Grimrock 1 Modding
Posted: Fri Oct 06, 2023 6:07 pm
by Sir Tawmis
Inspector and Connectors
When a single entity is selected, its properties such as ID, position and facing are displayed in the inspector window. Many entities also have parameters that are specific to the asset type so for the sake of example, let’s run through a few different types of assets and their parameters by adding
torch_holder, snail, dungeon_alcove and
scroll entities to the level.
The torch holder has an “Add Torch” parameter which, when the checkbox is ticked, will add a burning torch which will illuminate the surroundings and which the player can pick up.
You can change a monster’s behaviour with the “AI State” drop down box: the default state is that the monster will wander around in the dungeon by itself and the guard state will make the monster stand in place until it sees or otherwise senses the player.
In the alcove’s inspector you can add items for the player to discover from the alcove. Just start typing the name of an asset (say, a
dagger for instance) in the “Add New Item” text field and the text will autocomplete itself as you type to make it quicker to locate and add items to it. You can add items into sacks and other containers the same way.
And finally, you can add a text on a scroll for the player to read. If you want to have text on multiple lines, typing
\n inserts a line break.
Connectors
When looking at the parameters of the torch holder and the alcove you might have noticed a peculiar looking “Add Connector” button. It is a simple but powerful way of creating all sorts of contraption, puzzles, traps and logic into the levels. To try it out, add a
dungeon_pressure_plate and a
dungeon_door_portcullis into the dungeon and select the pressure plate and click on “Add Connector”. Connectors are simply a way of creating gameplay logic by defining that when an event happens to the pressure plate, a target entity performs an action. In this case for example, we can make the portcullis to open when a weight is placed on the pressure plate and to close when the weight is taken off. To start off, let’s first define the portcullis as the target of the connector by pressing the “?” button by the “Target” text field and then clicking on the portcullis on the Map View. This will add the ID of the portcullis into the target text field and, to illustrate the connection, an arrow is drawn between the entities on the map view.
Now, the pressure plate is already functional and you can try it out in the preview but it’s not doing exactly what we want it to do quite yet: now when you step on it the door opens as it should but when you step off the plate the door still stays open. If we take a closer look, we can spot two problems: 1) we only have an action that opens the door and 2) we only perform an action when the pressure plate is activated. Pressure plates, alcoves, levers and similar assets have two events: activate and deactivate. The activate event happens when a weight is put on a pressure plate or an alcove, a lever is pulled down and deactivate happens when the opposite is done. In this case we need the door to open when the plate is activated and the door to close when the plate is deactivated. You could simply add a second connector to the pressure plate that closes the door when the plate is deactivated but an alternate, and perhaps a little more elegant solution, would be if we just use a single connector with the event type of “any” (so that the action is taken on both activate and deactivate) and then send a “toggle” (which will open the door if is closed and vice versa) action to the portcullis.
Hidden Pressure Plates, Secrets and Spawners
If you ever need to trigger events without the player noticing that he has just stepped on a pressure plate, a good way to do it is to use
pressure_plate_hidden asset: it has the same functionality as the normal pressure plate has but you just simply can’t see it. Just keep in mind that if you don’t want monsters or thrown items to accidentally trigger the hidden pressure plate, be sure to disable those parameters from the inspector. Good example cases where you often want to use hidden pressure plates are when you need to activate a
secret or a
spawner entity. Secrets are a special asset whose purpose are indicating it for the player when he has discovered a secret area and then tallying up the total number of secrets discovered in his game statistics. Spawners are a little more interesting since not only can you spawn monsters from it but you can use it to launch spells as well to create traps or puzzles. The cooldown parameter in a spawner defines in seconds how much time is needed before the spawner can spawn again if it is activated again. This can be useful in controlling the size of monster populations or to limit the total amount of fireballs flying through the air: a great number of spells can be very taxing on the game’s performance. A cooldown value of 0 means that the spawning speed is unlimited.
If you want to create “Spectral Relay” -style puzzles, you can spawn a
blob spell (it’s a spell that the player cannot cast and its sole purpose is to be used in puzzles) and then catch the spell with a
receptor and trigger something by adding a connector to it.
Using Counters and Timers
Counting things like button presses or triggering an event when a certain amount of keys are inserted into locks is a common occurrence in Legend of Grimrock levels. For most of these cases, using
counter assets are the best, most simple solution. Counters are very straightforward: they just contain a single number that you can increment and decrement with connectors from other entities and you can also add connectors to the counter itself which will be triggered when the counter’s value reaches zero. So if you would want to create a button you need to press three times, you would need a counter whose initial value is 3 and then just make sure that a connector in the button has the counter entity as its target and decrement as its action. This means that any time you would press the button, the counter’s value goes down by 1 and after three presses the counter would reach 0 and any connectors added to the counter entity would be activated.
Doors that open with a delay or carefully timed sequences of events can be created by using
timer assets. Timers are quite simple: if a timer is active, it waits for the duration of its timer interval -parameter (in seconds) and then activates its connectors. Once a timer is activated, it will not stop until something deactivates it so by default its connectors will be activated perpetually, once per timer interval. If you wish to stop the timer after a single completed cycle, just add a connector with the timer entity itself as the target and deactivate as the event.
More intricate sequences can be created by using counters along with timers. You can set a counter as the target of a timer’s connector, so it decrements a counter every time a timer ticks and then the counter triggers once reaching 0. You can even use multiple counters with different values to create even more intricate scenarios but when working on complex sequences, scripting can very easily be the easier, more elegant solution.
Re: Legend of Grimrock 1 Modding
Posted: Fri Oct 06, 2023 6:19 pm
by Sir Tawmis
Introduction to Scripting
Scripting is a vast topic so in the scope of these documents we can merely introduce you to the subject. Even though you can do a lot in the Dungeon Editor without ever touching scripting, I would encourage you to try it out since doing scripts, even very simple ones, will open a lot of new possibilities for your level designs. If you want to get started in programming in general, I think scripting in the Dungeon Editor and maybe creating a custom asset or two on the side is a good starting point since you can start off with very easy and simple scripts and then build up from there.
Level scripting in Legend of Grimrock is done using a programming language called Lua which is a very flexible language with a simple syntax and it’s a great language for getting started in programming too. Prior knowledge of Lua won’t be absolutely necessary here but I won’t be covering the details of Lua programming here either so even a cursory knowledge of scripting or programming in general will be helpful. But I’m sure you can get quite far even with just copying and pasting these examples and modifying them for your purposes too. I’m certain the modding community will also produce a great amount of scripts that will be available for anyone to use.
The game console is a very helpful tool when it comes to scripting (or for level design in general) and you can enable the console by editing the grimrock.cfg file (usually located in your “\Documents\Almost Human\Legend of Grimrock”). Then, you can access the console in the game preview window by pressing the tilde key (under Esc and above Tab) and run lines of script there. Also, messages that are printed from scripts will be displayed on the console and to get started with some practical stuff, let’s learn how to print a traditional “Hello world!” message!
Hello world
Scripts in the levels are contained in
script_entity assets that you add to the map. Their location in the level typically doesn’t affect their functionality but for the sake of clarity it is usually a good idea to place the script entity close to what the script relates to. The scripts will be run when the dungeon is started for the first time but we can also run functions from the script entities by using the connectors from buttons, pressure plates, timers and other actuators. If we want to create a script that prints a message to the console any time when a button on a wall is pressed we would need to add a script entity to the level with the following script in it:
Code: Select all
-- hello world script
function hello()
print("Hello world!")
end
The first line of the script is a comment, as indicated by the two dashes in front of the line, and therefore it will not be interpreted as code. In the following line we define a new function that we decide to simply call “hello” and next, between the function definition and its end statement, we have the piece of script that actually runs when some event in the game calls the hello-function.
The script is now completed but at this point if you would run the preview, the script would essentially do nothing since we don’t call the hello function from anywhere in the level yet, so let’s add a
wall_button somewhere into the level and add a connector to the button and set the script entity as its target. At this point, the Action-field of the connector should show the name of the function (“hello”) so we can start the preview and press the wall button to see if “Hello world!” is printed to the console on top of the screen.
Any text printed using the
print() function will only be visible on the console. If you need to output text that the player will also see, you should use
hudPrint() instead.
So in practice, functions are a handy way for you to run pieces of script triggered by events (such as button presses) in the game. One script entity can contain multiple functions: just remember to pick the correct one when adding a connector.
Re: Legend of Grimrock 1 Modding
Posted: Fri Oct 06, 2023 6:22 pm
by Sir Tawmis
How to Script a Combination Lock
With this script, we will learn how to interact with other assets via script by doing a classic combination lock puzzle. To get started, we need three
lever entities for the lock and a door of your choice we want to get open and a
script_entity. Referring to an entity in the level from the script is done by using a unique ID. All the entities you add into a level will have an automatically generated unique ID assigned to them but when it comes to scripting, it often is helpful to rename them yourself so that they are easier to type and to remember. All IDs must contain only alphanumeric characters and underscores and the ID must start with a letter. You’ll also have to make sure that the IDs you define are unique so it generally is a good idea to avoid names that are too generic such as “door” or “lever”. So, for this puzzle let’s go to the first lever’s inspector and set its ID as combinationLever1 and do the same for the rest of the levers but just increment the number in the end of the IDs. And then, let’s set the ID of the door as combinationDoor. Alright, now we should have all the building blocks in place so let’s add the script:
Code: Select all
-- combination lock puzzle
function pullLever()
if combinationLever1:getLeverState() == "activated" and
combinationLever2:getLeverState() == "deactivated" and
combinationLever3:getLeverState() == "activated" then
combinationDoor:open()
else
combinationDoor:close()
end
end
Before this script does anything, we need to add connectors to the levers: in each of the levers, add a connector with the script entity as its target and make sure that the pullLever function is defined as the action. And since we want to check if the puzzle is solved every time a lever is operated (instead of being only checked when a lever is pulled down) we need to use the event type of “any”.
In the script, within the pullLever function, we have one if-then-else conditional. We basically ask the state of each of the levers using the getLeverState method and if all the methods return a boolean value of true, then the script within the “then” block is run and if not, the script within the “else” block is run. In this case, the expected positions of the levers are down-up-down (activated levers have their handles in a downright position and vice versa). If the combination is deemed correct, we open the door and if not, we try to close it. Naturally the door will only actually close if the player has already managed to get it open once and therefore it can seem a little unnecessary to take closing the door into account too but paying attention to details like these can be important if you want the dungeon to appear to work logically from the player’s point of view.
If you encounter any problems when creating a script like this, you can use the print commands we learned previously to help us spot any potential problems. You could, for example, see what parts of the script are run by printing messages, for example
print("hello!"), from them or we could see what states the levers actually return by adding
print(combinationLever1:getLeverState(), combinationLever2:getLeverState(), combinationLever3:getLeverState()) within the pullLever function.
Re: Legend of Grimrock 1 Modding
Posted: Fri Oct 06, 2023 6:30 pm
by Sir Tawmis
Scripting Reference
You are reading the Lua scripting reference manual for Legend of Grimrock. The focus of this document is on completeness rather than brevity. Refer to the tutorials for more detailed examples on how to use the material described here.
The Lua functions and methods described here can be accessed from a script entity and typed on the console.
In addition the following standard Lua functions can be used: tonumber, tostring, type, pairs, ipairs, and all functions in table, math and string modules. See the Lua reference manual for more details about their usage.
Accessing Entities
Almost all things in Legend of Grimrock are modeled as objects. There are two types of objects. Entities are game objects which are spawned in the dungeon either by placing them in the dungeon using the level editor or spawning them dynamically from a script. For example buttons, pressure plates, teleporters and the party are all entities. Each entity has an id, a string which identifies the entity uniquely. You can refer to an entity by simply typing it’s id. For example, the following script calls the rest() method on an entity with the id “party”:
party:rest()
All entities have the following properties that can be accessed with the dot operator:
“name” returns the name of the entity
“id” returns the unique identifier of the entity
“x” returns the x-coordinate of the entity on the map
“y” returns the y-coordinate of the entity on the map
“facing” returns the facing of the entity (0=north, 1=east, 2=south, 3=west)
“level” returns the dungeon level index of the entity
“class” returns the class name of the entity
For example, “torch1.x” would return the x-coordinate of the entity named “torch1”.
You can also refer to the script entity itself from its own script code using the implicit “self” variable. This can be handy if you need to refer to it’s coordinates. For example the following script prints the x- and y-coordinates of the script entity to the console:
print(self.x, self.y)
The second class of objects are objects that have no direct representation of them in the dungeon. For example, a Champion is an object that is contained inside the Party entity. You have no direct access to these objects but various functions return references to them. For example, the following script retrieves the first champion in the party and changes his name:
party:getChampion(1):setName("Jakob")
Global Functions
Entity Management
spawn(object, level, x, y, facing, [id])
Spawns a new object at given position on a dungeon level where x and y specify the x- and y-coordinates on the map and level is a level index. facing must be a number between 0 and 3 and it indicates the following directions: 0=north, 1=east, 2=south, 3=west. id parameter is optional. If given it must be an unique id in the context of the dungeon. If not given an unique id is automatically generated.
findEntity(id)
Returns an entity with given name or nil if no such entity exists.
entitiesAt(level, x, y)
Returns an iterator for entities at x,y in a given level.
allEntities(level)
Returns an iterator for all entities in a given level.
User Interface
hudPrint(text)
Prints a line of text to the text area at the bottom of the screen.
setMouseItem(item)
Sets the given item as mouse item, or destroys the mouse item if item is nil.
getMouseItem()
Returns the “mouse item”, the item attached to the mouse pointer. If there is no mouse item, nil is returned.
Sounds
playSound(sound)
Plays a sound effect. sound must be a name of a built-in or custom sound effect.
playSoundAt(sound, level, x, y)
Plays a sound effect at given position. sound must be a name of a built-in or custom sound effect.
Game Mechanics
rollDamage(power)
Returns a random amount of damage for an attack with given power.
damageTile(level, x, y, direction, flags, damageType, power)
Damages all creatures including the party in a given tile. direction specifies the direction of the attack for projectiles or melee attacks (0=north, 1=east, 2=south, 3=west). damageType must be one of the following: “physical”, “fire”, “poison”, “cold”, “shock”. Damage is rolled individually for all creatures using the power as base value. flags is a numeric bit field:
bit 0: monsters recoil from the impact
bit 1: ongoing damage such as poison cloud
bit 2: damage originated from champion with ordinal index 1
bit 3: damage originated from champion with ordinal index 2
bit 4: damage originated from champion with ordinal index 3
bit 5: damage originated from champion with ordinal index 4
bit 6: ignore immunities
bit 7: halve damage of back row party members
Bits 2-5 are used when dealing experience point awards. See also Champion:getOrdinal().
shootProjectile(projectile, level, x, y, direction, speed, gravity, velocityUp, offsetX, offsetY, offsetZ, attackPower, ignoreEntity, fragile, championOrdinal)
Shoots a projectile item. The parameters are:
projectile: the name of the item to shoot.
level,x,y: the initial position of the projectile in a level.
direction: the shooting direction (0=north, 1=east, 2=south, 3=west).
speed: the speed of the projectile (metres/second). Typical values around 10.
gravity: the gravity force in y-direction. Typical values around 0.
velocityUp: the initial velocity in y-direction. Typically set to 0.
offsetX,offsetY,offsetZ: 3D offset in world space from the center of cell.
attackPower: attack power of the projectile.
ignoreEntity: the entity to be ignored for collisions (or nil if the entity should not ignore any collisions).
fragile: a boolean flag, if set the projectile is destroyed on impact.
championOrdinal: a champion ordinal number, used for dealing experience points. This parameter is optional.
Misc
print(…)
Prints all arguments to the console.
completeGame([cinematicsFile])
Completes the game and optionally plays back a cinematics file. cinematicsFile must be a valid cinematics filename. Note, in the Dungeon Editor this function only prints “Game Completed” to the console.
getForward(direction)
Converts direction, a number between 0 and 3 corresponding to a compass direction, to delta-x and delta-y values.
getMaxLevels()
Returns the number of levels in the dungeon.
isWall(level, x, y)
Returns true if the given square contains solid wall.
getStatistic(stat)
Returns the value of a built-in statistic. Possible statistics are: “play_time”, “monsters_killed”, “items_found”, “secrets_found”, “treasures_found”, “toorum_notes_found”, “skulls_found”, “grimrock_doors_opened”, “tiles_moved”, “pit_falls”, “melee_attacks”, “ranged_attacks”, “unarmed_attacks”, “rocks_thrown”, “spells_cast” and “potions_mixed”.
Alcove
Alcove:addItem(item)
Adds an item to the alcove. For example Alcove:addItem(spawn(“dagger”)).
Alcove:containedItems()
Returns an iterator for items contained in the alcove.
Alcove:getItemCount()
Returns the number of items in the alcove.
Alcove:setActivateAlways(enable)
Enables the activate always mode for the alcove. Normally when an item is placed on an alcove, the alcove is triggered only if it was empty. Likewise the alcove is triggered when the last item is removed from it. With activate always the alcove is triggered every time an item is placed or removed from the alcove.
Alcove:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
Alcove:destroy()
Removes the entity from the level.
Altar
Altars share the same scripting API with Alcoves. The only difference is that an alcove is a wall item while an altar is placed in the middle of a cell.
Blocker
Blocker:activate()
Activates the blocker. An active blocker prevents monsters from moving through the square where the blocker is located.
Blocker:deactivate()
Deactivates the blocker.
Blocker:toggle()
Toggles the blocker on and off.
Blocker:destroy()
Removes the entity from the level.
BurstSpell
BurstSpell:setAttackPower(power)
Overrides the attack power of the burst spell.
BurstSpell:destroy()
Removes the entity from the level.
Button
Button:setActivateOnce(once)
If set to true, the button can only be triggered once.
Button:push()
Simulates a push of the button as if the button had been operated by the player.
Button:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
Button:destroy()
Removes the entity from the level.
Champion
Champion:setEnabled(enabled)
Enables or disables the champion. A disabled champion is essentially an empty party slot.
Champion:setName(name)
Sets the name of the champion.
Champion:setRace(race)
Sets the race of the champion. The race must be one of the following: “Human”, “Minotaur”, “Lizardman” or “Insectoid”.
Champion:setClass(class)
Sets the class of the champion. The class must be one of the following: “Fighter”, “Rogue”, “Mage” or “Ranger”.
Champion:setSex(gender)
Sets the gender of the champion. The gender must be either “male” or “female”. The gender determines the sounds to be played when the champion is damaged.
Champion:getEnabled()
Returns true if the champion is enabled and false if the champion is disabled.
Champion:getName()
Returns the name of the champion.
Champion:getRace()
Returns the race of the champion.
Champion:getClass()
Returns the class of the champion.
Champion:getSex()
Returns the gender of the champion.
Champion:getLevel()
Returns the current level of the champion.
Champion:getOrdinal()
Returns champion’s ordinal index between 1 and 4. The ordinal index is an unique identifier for the champion. It is guaranteed that the ordinal index never changes after character creation.
Champion:setPortrait(filename)
Sets the image file to be used as champion’s portrait. The portrait must be a valid TGA file of size 128*128 pixels. The file must be located in “mod_assets” folder or contained in the base game archive.
Champion:isAlive()
Returns true if the champion is alive.
Champion:gainExp(amount)
Gives a number of experience points to the champion.
Champion:levelUp()
Gives just enough experience points to get to the next level.
Champion:getSkillPoints()
Returns the number of unused skill points.
Champion:addSkillPoints(amount)
Gives a number of skill points to the champion.
Champion:getSkillLevel(skill)
Returns the current level of a skill. The skill must be one of the following: “air_magic”, “armors”, “assassination”, “athletics”, “axes”, “daggers”, “dodge”, “earth_magic”, “fire_magic”, “ice_magic”, “maces”, “missile_weapons”, “spellcraft”, “staves”, “swords”, “throwing_weapons” and “unarmed_combat”.
Champion:trainSkill(skill, levels, dontSpendPoints)
Increases a skill by a number of levels. If dontSpendPoints is true, skill points are not spent for leveling up the skill.
Champion:consumeFood(amount)
Consumes an amount of food taking racial food consumption rate and other factors into account.
Champion:modifyFood(amount)
Adds amount to current food stat directly without applying any modifiers. Amount can be a signed value.
Champion:getFood()
Returns champion’s current food value.
Champion:setCondition(condition, value)
Sets the value of a condition. The interpretation of value depends on the condition but it corresponds roughly to the number of seconds that the condition should last. The condition must be one of the following: “poison”, “diseased”, “paralyzed”, “haste”, “rage”, “fire_shield”, “shock_shield”, “poison_shield”, “frost_shield”, “invisibility”.
Champion:setConditionCumulative(condition, value)
Sets the value of a condition to the maximum of current value and the parameter value. I.e. this method has the same effect as:
champion:setCondition(condition, math.max(champion:getCondition(condition), value)).
Champion:getCondition(condition)
Returns the current value of a condition, or zero if the champion does not have the condition.
Champion:hasCondition(condition)
Returns true if the champion has a condition, i.e. the condition value is greater than zero.
Champion:damage(amount, type)
Deals damage to the champion. Type must be “physical”, “fire”, “shock”, “poison” or “cold”.
Champion:playDamageSound()
Plays the damage sound which is determined by champion’s race and gender.
Champion:setStat(stat, value)
Sets the base value of a statistic. The value of a stat cannot exceed its maximum value and the new value is clamped to the maximum value. Stat must be one of the following: “health”, “energy”, “strength”, “dexterity”, “vitality”, “willpower”, “protection”, “evasion”, “resist_fire”, “resist_cold”, “resist_poison”, “resist_shock”.
Champion:setStatMax(stat, value)
Sets the maximum value of a statistic.
Champion:modifyStat(stat, amount)
Adds amount to the value of a statistic. Same as calling
champion:setStat(stat, champion:getStat(stat) + amount).
Champion:modifyStatCapacity(stat, amount)
Adds amount to the maximum value of a statistic. Same as calling
champion:setStatMax(stat, champion:getStatMax(stat) + amount).
Champion:getStat(stat)
Returns the value of a statistic.
Champion:getStatMax(stat)
Returns the maximum value of a statistic.
Champion:getProtection()
Returns the current protection value of the champion.
Champion:getEvasion()
Returns the current evasion value of the champion.
Champion:getResistance(element)
Returns the elemental damage resistance value for an element. Element must be “fire”, “shock”, “poison” or “cold”.
Champion:getLoad()
Returns the current load of the champion in kilograms.
Champion:getMaxLoad()
Returns the maximum carrying capacity of the champion in kilograms.
Champion:insertItem(slot, item)
Inserts an item to an equipment slot. Slot must be one of the following: 1 (head), 2 (torso), 3 (legs), 4 (feet), 5 (cloak), 6 (neck), 7 (left hand), 8 (right hand), 9 (gaunlets), 10 (bracers), 11-31 (backpack slots).
Champion:removeItem(slot)
Removes an item from an equipment slot.
Champion:getItem(slot)
Returns an item in an equipment slot.
Champion:addTrait(trait, silent)
Gives a given trait to the champion. If silent is true there is no hud print. Trait must be one of the following:
“aggressive”, “agile”, “athletic”, “aura”, “cold_resistant”, “evasive”, “fire_resistant”, “fist_fighter”, “head_hunter”, “healthy”, “lightning_speed”, “natural_armor”, “poison_resistant”, “skilled”, “strong_mind”, “tough”.
Champion:removeTrait(trait)
Removes a given trait from the champion.
Champion:hasTrait(trait)
Returns true if the champion has a given trait.
Counter
Counter:setValue(value)
Sets the value of the counter.
Counter:getValue()
Returns the current value of the counter.
Counter:reset()
Resets the counter to the initial value.
Counter:increment()
Increments the value of the counter by 1.
Counter:decrement()
Decrements the value of the counter by 1.
Counter:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
Counter:destroy()
Removes the entity from the level.
Door
Door:open()
Opens the door.
Door:close()
Closes the door.
Door:activate()
Same as Door:open().
Door:deactivate()
Same as Door:close().
Door:toggle()
Opens the door if it is closed, otherwise closes it.
Door:isOpen()
Returns true if the door is open.
Door:isClosed()
Returns true if the door is closed.
Door:addPullChain()
Adds a pullchain to the door. This function is intended to be used internally by the editor. Do not attempt to add a pullchain dynamically to a door from a script because it may cause problems with save games. This function is listed here only for completeness.
Door:setDoorState(state)
Sets door’s state immediately without playing animation and sound effects. State must be “open” or “closed”.
Door:setOpenedBy(key)
Sets the name of the item which can be used to unlock this door. Works only with doors with built-in locks.
Door:destroy()
Removes the entity from the level.
FX
FX:setParticleSystem(name)
Sets the particle system to be played when the FX is first updated.
FX:setLight(red, green, blue, brightness, range, time, castShadow)
Sets the light effect to be played when the FX is first updated. Red, green and blue define the color of the emitted light in range 0-1, brightness is light’s brightness typically in range 0-20, range is light’s range in world units (meters), time is the length of the effect in seconds, castShadow is a boolean flag which enables shadow casting for the light source. Large range and shadow casting can cause drops in frame rate.
FX:translate(x, y, z)
Translates (i.e. moves) the FX by x,y,z in world space. This function is typically used to lift particle system off the ground.
FX:destroy()
Removes the entity from the level.
Item
Item:setScrollText(text)
Sets the text for a scroll item. Lines are separated with ‘\n’ characters.
Item:setScrollImage(filename)
Sets custom scroll image to be displayed in the tooltip.
Item:setSubtileOffset(x, y)
Sets item’s relative position to the center of tile.
Item:setCharges(charges)
Sets the number of charges remaining.
Item:setFuel(fuel)
Sets the remaining fuel (in seconds) for torches.
Item:setStackSize(stackSize)
Sets the stack size for stackable items.
Item:getScrollText()
Returns the text of a scroll item.
Item:getScrollImage()
Returns the filename of the custom scroll image if it exists.
Item:getWeight()
Returns the weight of the item. Returns the total weight of a stack for stackable items.
Item:getUIName()
Returns the user interface name of the item.
Item:getCharges(charges)
Returns the number of charges remaining.
Item:getFuel(fuel)
Returns the remaining fuel (in seconds) for torches.
Item:getStackSize()
Returns the stack size for stackable items or 0 if the item is not stackable.
Item:containedItems()
Returns an iterator for contained items.
Item:addItem(item)
Adds a given item to a free container slot.
Item:insertItem(slot, item)
Inserts an item into given container slot.
Item:removeItem(slot)
Removes an item from a container slot.
Item:getItem(slot)
Returns the item in a given container slot.
Item:destroy()
Removes the entity from the level.
Lever
Lever:setLeverState(state)
Sets lever’s state immediately without playing animation and sound effects. State must be “activated” or “deactivated”.
Lever:setInverted(inverted)
Inverts the message to be sent when the lever is toggled, e.g. “activate” becomes “deactivate” and vice versa.
Lever:toggle()
Simulates a pull of the lever as if the lever had been operated by the player.
Lever:getLeverState()
Returns the state of the lever, either “activated” or “deactivated”.
Lever:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
Lever:destroy()
Removes the entity from the level.
LightSource
LightSource:activate()
Turns on the light source.
LightSource:deactivate()
Turns off the light source.
LightSource:toggle()
Toggles the light source on and off.
LightSource:destroy()
Removes the entity from the level.
Lock
Lock:setOpenedBy(key)
Sets the name of the item which can be used to unlock this lock.
Lock:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
Lock:destroy()
Removes the entity from the level.
Monster
Monster:setAIState(state)
Sets the AI state of the monster, which can be one of the following:
“default” the monster wanders lazily around in the dungeon, or
“guard” the monster waits in place until it sees or otherwise senses the party.
Monster:setHealth(health)
Sets monster’s health. Increases max health to accommodate the new health value if necessary.
Monster:setLevel(level)
Advances the monster in levels by giving it more health as specified by its level health adjustment property.
Monster:getHealth()
Returns monster’s current health.
Monster:getLevel()
Returns monster’s experience level.
Monster:addItem(item)
Adds an item to be carried by the monster. When the monster dies all items carried are dropped to ground.
Monster:destroy()
Removes the entity from the level.
Monster:setPosition(x, y, facing, level)
Instantly moves the monster to given location in the dungeon.
Party
Party:heal()
Restores all characters to full health and removes all harmful conditions.
Party:rest()
Puts the party to sleep.
Party:wakeUp(immediate)
Wakes up the party. If the immediate parameter is true, it indicates that the rest was interrupted abruptly, e.g. a monster attacked the party. The screen fades from black much quicker in this case.
Party:isResting()
Returns true if the party is resting.
Party:swapChampions(slot1, slot2)
Swaps the champions in slots slot1 and slot2. Slots must be in range 1-4.
Party:getChampion(slot)
Returns the champion in given slot (1-4).
Party:shakeCamera(intensity, duration)
Shakes the camera. Intensity is in the range 0-1 and duration is a length of the camera shake in seconds.
Party:playScreenEffect(particleSystem)
Plays an on-screen particle system. particleSystem refers to a particle system defined using the defineParticleSystem function.
Party:setPosition(x, y, facing, level)
Instantly moves the party to given location in the dungeon.
Pit
Pit:open()
Opens the pit. This has no effect if the pit does not have a trap door.
Pit:close()
Closes the pit. This has no effect if the pit does not have a trap door.
Pit:activate()
Same as Pit:open().
Pit:deactivate()
Same as Pit:close().
Pit:toggle()
Opens the pit if it is closed, otherwise closes it.
Pit:setPitState(state)
Sets the state of the pit immediately without playing animations or sound effects. State must be either “open” or “closed”.
Pit:isOpen()
Returns true if the pit is open.
Pit:isClosed()
Returns true if the pit is closed.
Pit:addTrapDoor()
Adds a trap door to the pit so that it can be closed. This function is intended to be used internally by the editor. Do not attempt to add a trap door dynamically to a pit from a script because it may cause problems with save games. This function is listed here only for completeness.
Pit:destroy()
Removes the entity from the level.
PressurePlate
PressurePlate:setTriggeredByParty(enable)
Sets whether the pressure plate is activated when the party steps on the plate.
PressurePlate:setTriggeredByMonster(enable)
Sets whether the pressure plate is activated when a monster steps on the plate.
PressurePlate:setTriggeredByItem(enable)
Sets whether the pressure plate is activated when an item is placed on the plate.
PressurePlate:setActivateOnce(enable)
If set to true, the pressure plate can only be triggered once.
PressurePlate:setInverted(enable)
Inverts the message to be sent when the pressure plate is activated, e.g. “activate” becomes “deactivate” and vice versa.
PressurePlate:setSilent(enable)
Sets whether the pressure plate makes a sound when it activates.
PressurePlate:isDown()
Returns true if the pressure plate is down.
PressurePlate:isUp()
Returns true if the pressure plate is up.
PressurePlate:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
PressurePlate:destroy()
Removes the entity from the level.
ProjectileSpell
ProjectileSpell:setAttackPower(power)
Overrides the attack power of the projectile spell.
ProjectileSpell:destroy()
Removes the entity from the level.
Receptor
Receptor:setEntityType(entityType)
Sets the entity type which triggers the receptor. The receptor is a special wall trigger which activates when an entity of the specified type hits it.
Receptor:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
Receptor:destroy()
Removes the entity from the level.
Secret
Secret:activate()
Marks the secret as found.
Secret:destroy()
Removes the entity from the level.
Spawner
Spawner:activate()
Spawns a new entity as specified by the spawned entity property. The spawner is then temporarily disabled for a period of time specified by the cool down property.
Spawner:setSpawnedEntity(name)
Sets the name of the entity to be spawned when the spawner is activated.
Spawner:setCoolDown(time)
Sets the cool down time in seconds.
Spawner:destroy()
Removes the entity from the level.
Teleporter
Teleport:activate()
Activates the teleporter.
Teleport:deactivate()
Deactivates the teleporter.
Teleport:toggle()
Toggles the teleporter on and off.
Teleport:isActivated()
Returns true if the teleporter is activated.
Teleport:setTriggeredByParty(enable)
Sets whether the teleporter teleports the party. Default is true.
Teleport:setTriggeredByMonster(enable)
Sets whether the teleporter teleports monsters. Default is true.
Teleport:setTriggeredByItem(enable)
Sets whether the teleporter teleports items. Default is true.
Teleport:setTeleportTarget(x, y, facing, [level])
Sets the target for teleportation. The level parameter is optional. It can be a level index, or “up” or “down”, in which case the parameter is interpreted as the level above and below the teleporter.
Teleport:setChangeFacing(enable)
If enabled teleported entities have their facing turned according to the teleport target. This property is set by default. If the parameter is false, the teleporter does not change the facing of teleported entities.
Teleport:setInvisible(enable)
Makes the teleporter invisible if the parameter is true, or visible if the parameter is false.
Teleport:setHideLight(enable)
Hides or unhides the dynamic light source attached to the teleporter. Useful for improving performance when there is a lot of teleporters close together in a level.
Teleport:setSilent(enable)
Makes the teleporter silent if the parameter is true, or audible if the parameter is false.
Teleport:setScreenFlash(enable)
Sets the state of the screen flash effect which is played when the party steps into the tele porter. If the parameter is true the screen flash effect is enabled, otherwise the effect is disabled.
Teleport:destroy()
Removes the entity from the level.
Timer
Timer:activate()
Activates the timer.
Timer:deactivate()
Deactivates the timer.
Timer:toggle()
Toggles the timer on and off.
Timer:isActivated()
Returns true if the timer is activated.
Timer:setTimerInterval(interval)
Sets the timer interval in seconds.
Timer:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
Timer:destroy()
Removes the entity from the level.
TorchHolder
TorchHolder:addItem(item)
Adds an item to the torch holder. The item must be of type torch and only one torch may be inserted into the torch holder at one time.
TorchHolder:addTorch()
Shortcut for “TorchHolder:addItem(spawn(“torch”))”.
TorchHolder:hasTorch()
Returns true if there is a torch in the torch holder.
TorchHolder:setSilent(enable)
If the parameter is true the crackling flame sound is turned off. False makes the torch holder audible again.
TorchHolder:addConnector(event, target, action)
Adds a new connector from the entity to a target entity. Event, target and action are strings. Using this method is equivalent to creating a connector in the inspector.
TorchHolder:destroy()
Removes the entity from the level.
WallText
WallText:setWallText(text)
Sets the text which is display when the wall text is clicked with the mouse. Multiple lines can be separated with ‘\n’ characters.
WallText:getWallText()
Returns the wall text string.
WallText:destroy()
Removes the entity from the level.