Legend of Grimrock

Legend of Grimrock

Not enough ratings
Editor: Tips and Tricks
By Manyminiguns
Insightful and helpful editor information on scripting and level design.

  • For tips and tricks on Legend of Grimrock's gameplay, take a look at Gameplay: Tips and Tricks.
  • For additional dungeons (including gameplay implementation of this guide's scripts), check out the Stronghold of Ordar map on Steam Workshop.
  • For a comprehensive starters guide, visit the editor's help website[www.grimrock.net] or visit the community modding website[www.grimrock.net].

Continue to check back for updates and new information.
   
Award
Favorite
Favorited
Unfavorite
Level Design
Creativity

So many possbilities about what to build but cannot start? The easiest way solve this problem is by designing your dungeon based on a theme. A theme gives you key level design traits such as direction, order and consistency. There are two ways to gain inspiration for a theme: think for a while or name generators. Luckily, the editor has one best suited for you. When starting a new project, there is a generate dungeon name button. These names can give you excellent ideas for themes.

Dungeon Difficulty

Test. Test. Test. An important aspect level design is difficulty. Typically, you want a challenging dungeon, not incredibly easy or tough. So, using the preview window, do some playthroughs. Keep two critical pieces of information in mind:
  • Depending on the length of the dungeon, leveling can skew difficulty quite a bit
    • Scale monsters and item handouts based on playthroughs
  • Developer knowledge gives you an advantage
    • It is vital for other people to play your dungeon and give you feedback

Hotkeys

Hotkeys are important for two reasons: allows the developer to use basic features of the editor much more quickly and does not interupt train of thought. Repeated distractions or hassles when trying to focus can make this a bad experience. If you are a coder, designer, developer, or really anyone that requires great deal of thought and concentration when working on a project, you may have felt like this before. Here are some important hotkeys to avoid this frustration:
  • Important designing hotkeys
    • Selector - 1
    • Add object - 2
    • Draw walls - 3
    • Set starting location - Y
    • Rotate selection clockwise - E
    • Rotate selection counterclockwise - Q
  • Important ingame hotkeys
    • Fullscreen - Ctrl-F
    • Open door - Z
    • Kill monster - K
    • Heal party - H
Scripting
Introduction

Scripting allows the developer to do design much more unique dungeons than just using basic tools. The concept of scripting and coding in general are taught elsewhere. You need not know any prior knowledge of coding languages or experience in coding to make some basic scripts (especially using the editor's introduction to scripting section[www.grimrock.net]). It is difficult to learn and remember everything in one sitting so have a willingness to learn and some time on your hands to be successful.

Lua scripting help:

Basics

Below are some pieces of code broken apart to be better explained.
  • --
    • Comments (allows the coder to explain parts of code)
  • function
    • Contained objects within scripts (simply put, names of pieces of code)
  • end
    • Completes loops and functions (this keyword is needed to finish certain keywords)
  • :
    • Colon is a special character in lua scripting. It is used for calling methods. An example is an object being manipulated by a method, in the below case, a door opening.
      • door:open()
  • .
    • Used to call functions under certain scripts.
      • scriptOne.functionOne(arg1, arg2...)
  • ..
    • Used for string concatenation
      • hudPrint(champ[4]..": This will end badly...")
  • Assets
    • Big contributor to how dungeons are creative and unique. These assets were made by the game developers and include sounds, particle effects, spells, materials and wallsets. I suggest using the help website for a list of all predefined assets. Here are a couple of examples.
      • playSound("sound_name")
      • hudPrint("text")

Real example

Enough of what each part is, the best way to learn is through example. Let's say questing is one of the characteristics in your dungeon. You may want the player to be notified that quest has been completed, play some sounds, allow them to return back to a quest hub quickly, and maybe even drop some sweet blueberry pie on them. Here is simple function that is called when a player hits a player the last button in the level thereby completing the level.
-- Quest One Completion function questcomplete() quest1CompletionDoor:open() hudPrint("Quest One Complete!") playSound("discover_spell") quest1Portal:activate() end

Troubleshooting

An excellent and widely used troubleshooting tactic is printing text in areas of code where you believe it is broken. Below is a function that display the text, "Test" whenever the function is called.
-- Troubleshooting script function test() print("Test") end

Here is a real application of this troubleshooting tactic. Below is some code from the editor's website.
-- 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

This script requires 3 levers be in these states (activated/deactivated) in order for the door to open, otherwise, the door will be (or continue to be) closed. A legitimate question to ask is, "How do I know if my code is actually closing the door is closing when the combination is wrong?"

Here is where our other function comes in. Below is the modified code that prints "Test" everytime the combination is wrong to prove that the above code is correct.

-- Troubleshooting script function test() print("Test") end -- combination lock puzzle function pullLever() if combinationLever1:getLeverState() == "activated" and combinationLever2:getLeverState() == "deactivated" and combinationLever3:getLeverState() == "activated" then combinationDoor:open() else test() combinationDoor:close() end end
Advanced Scripting
Introduction

This section is dedicated to intermediate level scripting.

Creating Custom Items

Custom items (assets) are typically cloned from other in game items. A common mistake developers make is that code for custom items are written in dungeon editor script entities. Incorrect. These objects must be written within appropriate lua file (swords, orbs, and so on should be written in the items.lua file). These lua files are in plain text (meaning they can be opened with any text editor) and are found under the scripts folder which is under mod_assets of the Legend of Grimrock Dungeons folder.

The following code is an example (from the official help page[www.grimrock.net]) of how to make a more powerful version of the machete.
cloneObject{ name = "super_machete", baseObject = "machete", uiName = "Super Machete", attackPower = 12, damageType = "shock", description = "This machete radiates with strange energy.", }

These are a few common definitions under the item category. The purpose of these definitions do as they suggest. For example, in this case baseObject stems all relevant information from machete (statistics, models and so on) and builds from there.

Since there are many more asset definitions than presented above, it is highly suggested to take a look at the whole list[www.grimrock.net]. However, this is no ordinary list. Information from the asset definition reference page can help create new ideas and guide developers to clearer and narrower paths.

Changing Light Colors

Changing light colors can be pretty simple. There are multiple methods of manipulating light. Here is one that is easy to understand.
cloneObject{ baseObject = "temple_ceiling_lamp", name = "red_light", particleSystem = false, lightColor = vec(1,0.20,0.20), lightRange = 4, brightness = 20, } cloneObject{ baseObject = "temple_ceiling_lamp", name = "green_light", particleSystem = false, lightColor = vec(0.20,1,0.20), lightRange = 4, brightness = 20, }
NOTE: Please be aware that the above code is within a lua file (specifically material.lua) while the code below is for a dungeon editor script entity.
function changeLight() red_light_1:destroy() spawn("green_light",1,1,1,1) end

Consider this: you want to change a light from a halting red color to a "good to go" green. How do you do that? Destroy the red light and then instantaneously spawn a green light that is on level 1, coordinates 1,1 and facing east (which direction it is facing does not matter for this situation). The above code does this exactly.

Party Dialogue

Here is one that can get tricky. In this example, a conversation between champion 1, 3 and 4 commences after a certain event has happened.
champ = {} champ[1] = party:getChampion(1):getName() champ[2] = party:getChampion(2):getName() champ[3] = party:getChampion(3):getName() champ[4] = party:getChampion(4):getName() function convoStarter() hudPrint(champ[4]..": I think we are trapped... This can't be happening.") end function response1() hudPrint(champ[1]..": Focus. How do we get out of here?") convoTimer1:destroy() end function response2() hudPrint(champ[3]..": Find the way back obviously.") convoTimer2:destroy() end

The first part to notice is the champion array. This stores all the party's names into an array that is accessible via all the functions within the script. Also notice that the timers are destroyed, this is because they are no longer needed after each timer has activated their appropriate response.

There is one key feature that cannot be shown in code: timers. The timers convoTimer1 and 2 are set to varying seconds so the text doesn't pop up all at once. So, when the event is triggered it activates the function convoStarter, the first and second convoTimers. There are no wait or sleep functions available so timers are our best tools at having a legitimate conversation.
3 Comments
Magnussen 29 Dec, 2018 @ 1:27pm 
Thanks Manyminiguns.

I am new to modding. So far I am advancing and I did some conversations but they appear all at once and came across your post. Creating several functions seems to messy and I wonder if there is any other way to pause the conversations or to wait between each line. For example, for the following prints, how can I make that each line appears after 2 seconds? or better, after I click with the mouse?

hudPrint("Unknown voice: Hey there!!!")
hudPrint(party.party:getChampion(1):getName()..": ?")
hudPrint("Unknown voice: Please, help me!")

I could use tricks like an invisible huge button and check for clicks and new lines... but I wonder if there is any command like WaitForMouseDown or something similar.... or an easy wait to do it.

Thanks in advance!

gazboys91 2 Nov, 2013 @ 4:11am 
verry good your guide
need help
lva script please

i want to create a door with full of lock (2 or 4 key to open 1 door)
i will find for combination lever but i don't find for it for lock
i search i to create for head with 2 gem
i search list of sound for editeur( i don't want create sound just utlise the sound of editor)
fx i to i search
please contact me or give me adresse please
(sorry for my english i'm french)
Ultra Smurf 13 Jul, 2013 @ 6:11pm 
This really helped when I wanted to make a few custom weapons thanks!