The purpose of this tutorial is to explain some of the different methods of making a functional door through the use of scripting. It will step you through the process of adding a door to your map and creating a script that will allow the player to open the door and subsequently walk through it. Doors are a simple and natural way to add some interaction to your game!
You'll first need to build a voxel model for your door. Create a new object in the Voxel Editor and build a door model similar to one of those shown in the examples below. For this tutorial, you'll want to have at least two separate frames, one for the door in its closed state and one in its open state. Most of the examples in this tutorial will be be based on the first type of door shown.
The style, orientation, and positioning all depend on what best matches the existing architecture of your game. For example, the top door in the images below is centered depth-wise since it's designed for a game where the walls take up the entire tile block. The bottom door is positioned flush with the grid edge since it's designed for a game where the walls are thinner and aligned with the tile edges.
Be sure to define two animations of type “Clamp” for the door, one named “open” to trigger the opening animation and one named “close” to trigger the closing animation. Even if your model only has one frame for each state like in the examples above, an animation must be defined to instruct the game to switch the door model to the desired frame.
Now that your door model is built, it can be added to a map. Open the desired map in the Map Editor and place the door into a wall opening (removing a wall tile if necessary). Then switch into “Connect” mode and set the appropriate navigation path(s) to “Interact Only” so the player can interact with the door from adjacent tiles. See Navigation and Interaction for more information.
To start off with something simple, let's create a script that will just work once to open the door and keep it in that state. The script will need to trigger the “open” animation, update the navigation paths, optionally play a sound effect, then finally remove the script from the door so the player can no longer interact with it. Two approaches will be explained, one using the Replace Navigation function, which is more straightforward, and the other using the Modify Navigation function, which requires more setup but gives you more specific control over the navigation changes.
From the Map Editor, right-click the door and open its Entity Properties dialog. Select “Quick Script” from the “Script” dropdown then click the “Edit” button () and type the following script into the Quick Script Builder.
play_sound("door_open"); play_animation(self, "open"); replace_navigation(self, INTERACT_ONLY, WALK_AND_INTERACT); set_entity_script(self, "")
The quick script will play the “door_open” sound effect, trigger the model's “open” animation, replace any adjacent navigation paths of type “Interact Only” (relative to the door's tile) with the type “Walk and Interact”, and finally remove the door's script. The Replace Navigation function is key, as it will allow the player to pass through the door once the script has executed.
If you'd prefer, you can also create a visual script in the Script Editor and assign it to the door instead of a quick script. This method of creating the script as its own file can be useful in cases where it's generic enough to be reusable (i.e. no explicit entity IDs are referenced).
Alternatively, you can use the Modify Navigation function instead of the Replace Navigation function. With this method, you must first assign unique entity IDs to any tiles needing their navigation modified. As shown in the image below, the tile on which the door is located has an ID of “door_tile” and the two adjacent tiles have IDs of “tile01” and “tile02”.
This version of the script is very similar to the first one, with the exception of calling the Modify Navigation function to explicity modify each “connection” between the door's tile and the two adjacent ones to set the navigation type to “Walk and Interact”.
play_sound("door_open"); play_animation(self, "open"); modify_navigation("door_tile", "tile01", WALK_AND_INTERACT); modify_navigation("door_tile", "tile02", WALK_AND_INTERACT); set_entity_script(self, "")
The previous scripts work fine for some cases, but most of the time you probably wouldn't want doors to be stuck in an open state. Fortunately we can improve these scripts and allow the door to be toggled between an opened and closed state.
The key to this functionality is maintaining the state of the door in an entity property using Set Entity Property and checking this property with an “if” statement (or the “Evaluate Condition” node in a visual script). According to the door's current state, you will trigger the appropriate animation, modify the navigation paths, and update the entity property with the new state. For example, a property named “open” with a value that gets toggled between true or false could be used to maintain the door's state.
The new versions of the scripts are very similar to the previous ones except there is now a second set of events that can occur to “revert” the door back to a closed state by playing the “close” animation and changing the navigation paths back to their original types.
The improved version of the script using the Replace Navigation method is fairly straightforward. We simply swap the navigation types between “Interact Only” and “Walk and Interact” as the door opens and closes.
if self.property["open"] == true then play_sound("door_close"); play_animation(self, "close"); replace_navigation(self, WALK_AND_INTERACT, INTERACT_ONLY); set_entity_property(self, "open", false) else play_sound("door_open"); play_animation(self, "open"); replace_navigation(self, INTERACT_ONLY, WALK_AND_INTERACT); set_entity_property(self, "open", true) end
For the improved version using the Modify Navigation method, let's assume we are using a different type of door that swings open, as shown in the image below. In the script, the navigation between “door_tile” and “tile02” is set to the type of “Interact Only” when the door is open due to the way its model swings inward. This prevents the player from walking through the door when it's open.
if self.property["open"] == true then play_sound("door_close"); play_animation(self, "close"); modify_navigation("door_tile", "tile01", INTERACT_ONLY); modify_navigation("door_tile", "tile02", WALK_AND_INTERACT); set_entity_property(self, "open", false) else play_sound("door_open"); play_animation(self, "open"); modify_navigation("door_tile", "tile01", WALK_AND_INTERACT); modify_navigation("door_tile", "tile02", INTERACT_ONLY); set_entity_property(self, "open", true) end
Scripting objects like doors is a great way to learn more about the RPG in a Box scripting language. There are often multiple methods to accomplish the same functionality and there isn't necessarily a right or wrong approach. As with many other concepts, the best way to learn is to experiment with different setups and determine what works best for you and the particular game that you're creating. Have fun!