How to Script a Combination Lock

combination_lockWith 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 an 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 combination_lever_1 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 combination_door. Alright, now we should have all the building blocks in place so let’s add the script:

-- combination lock puzzle
function checkLevers()
    if combination_lever_1.lever:isActivated() and not combination_lever_2.lever:isActivated() and combination_lever_3.lever:isActivated() then
        combination_door.door:open()
    else
        combination_door.door: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 checkLevers 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 “onToggle” event in the connector.

In the script, within the checkLevers function, we have one if-then-else conditional. Within the conditional, we ask from the lever component of the each object that is the lever activated using the isActivated method. If all the conditions 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 (note that we use the “not” boolean operation with the second lever). 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 and when 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.

In this script, we called methods of various types on different sorts of assets and if you want to find out more, you can see all the supported methods and functions in the scripting reference. Now that you have the power of scripting at your fingertips, you should read about save games and variables in order to make custom dungeons that are compatible with save games.