Tutorial 1–4 - BLKTower/TestWiki GitHub Wiki

In this tutorial, we will be learning the basics of creating triggers in Lua and refactoring our map so that the units are created by script rather than being directly placed in the Terrain Editor.

This tutorial will cover:

1. Getting Started With Lua

Our game engine uses Lua to build game logic that shape how games are actually played. At some point we will add a trigger GUI for writing game logic without writing script, but for now we use Lua. It may sound like scary coding, but in reality Lua is a widely-used lightweight scripting system focused on speed and ease-of-use. Lua is widely documented and googling "How do I do X in Lua" usually returns useful results.

To write Lua you'll need a text editor. Sure, Notepad or TextEdit will technically get the job done. What you really want is to download and use Visual Studio Code, an excellent, free, cross-platform code editor. When installing VS Code, be sure to check the "Add 'Open with Code' to Windows Explorer" option, as it will make your life easier in the future.

Once you've installed VS Code, we're going to add an extension that adds syntax highlighting (to make Lua easier to read). First click on the "Extensions" icon and use the search bar to search for "Lua".

1 code extension

Next, click the "install" button for the first option that appears.

2 lua extension

Next we're going to modify VS Code's file associations so it recognizes our trigger files as Lua script. You can likely skip this step if you have the DreamEditor extension added to VS Code as it should setup the file extensions automatically. The DreamEditor extension is automatically installed and updated whenever you install a new version of the editor. You can check if you already have installed in the "Extensions" icon in VS Code.

3 Extension

To manually set up your file associations, go to "File > Preferences > Settings". Then on the left go to "Text Editor > Files". Finally, under "Associations" click "Add Item". On the Item box write "*.lua.txt", and on Value write "lua", without quotation marks.

It should now look like this:

4 settings

Great! Now we're ready to get started adding some triggers to our map! You can close each of the open tabs in VS Code by click the "x" in the tab or with the CTRL+W shortcut.

2. Adding Triggers To Your Map

Triggers live inside the "Trigger.lua.txt" file inside the map folder. You can open this file directly by pressing this "Open Lua Script" Button on the left side in the Terrain or Data Window.

1-4-2_1a

Alternatively, you can open this file by selecting "File > Open" in VS Code or by dragging the .lua.txt file directly into your open VS Code window. By default, the Trigger.lua.txt file will look like this:

6 preset lua

For this tutorial, we'll remove this code (removing it won't cause any problems).

Write the following (actually write it out, it'll help you learn better than copy-pasting):

DCEI.LogMessage("Hello Lua!")

Save the trigger file when you finished and press Play in the editor to test your work.

At first it may seem like nothing is different. But if you open "Window > Play Settings Window", look for the Player Logs on the right side, and scroll to the bottom, you'll see that "Hello Lua!" has been printed. So what exactly happened there? We used the DCEI LogMessage function, which takes a string and prints it to the log window.

7 player logs

3. Creating Units In Triggers

Now let's do something a little more useful. We'll use the DCEI CreateUnit function to... create a unit! Back in VS Code, add a few new lines and write: DCEI.CreateUnit(1, 1, "Hero IceMage", 16, 16). If you used a different name for your hero, use that instead of "Hero IceMage".

We'll add a comment here by writing -- TRIGGERS. Our code will ignore this line. We'll talk more about comments in the next tutorial, so for now all you need to know is that comments can help us visually categorize our code.

8 create unit

SAVE again and hit play. You should see two heroes fighting enemies. Great! At this point you may be wondering what those parameters we used in CreateUnit() were. If we take a look at the CreateUnit() function in the API Reference we can find out:

CreateUnit(int teamId, int playerId, string unitTypeName, float x, float z, float dx, float dz)

What each of those things does:

  • Team Id (which team the unit is on. 1 is the local player's team)
  • Player Id (which player owns the unit. 1 is the local player)
  • Unit Type Name (which unit to create)
  • Map Coordinates (where to spawn the unit in X, Z)
  • Unit Facing (optional, what direction the unit is facing)

Now that we know how to create units in triggers, let's refactor the map so that the hero and enemies are created by triggers rather than being pre-placed on the terrain. Erase the units on the map by selecting them and pressing the Delete key and save. Hit Play again.

...And now there's no units? If you check the Player Logs Window (CTRL+SHIFT+L), you'll see the cause:

9 lua error

Our first lua error: "Hero IceMage is not registered". In order to create units, effects, or behaviors using triggers, they must be explicitly registered somewhere in your script so the engine knows to load that piece of data into memory. We didn't encounter this error before because the engine already knew about the hero since it was placed in the terrain editor.

To fix this, simply add DCEI.Unit() to your CreateUnit line. 10 declarations

SAVE again and if you hit Play, your hero unit should be created in the center of the map. Next, try creating the three enemy units (Standard MeleeUnit) in the map in triggers. Remember the team id and player id for enemies is -1, otherwise your hero won't attack the melee units.

Your triggers should look something like this:

image

PRO TIP: The editor supports hot reloading of triggers and data. If you save your triggers file and press the "Restart" button in-game, your changes will be applied without having to relaunch the game instance.

12 restart


4. Variables, Arrays, Loops

We can improve our Lua script by using variables instead of using the unit type name to improve readability and reduce the chance of errors.

To create a variable that stores the enemy unit type name, we'll write: local enemy_unit_name = "Standard MeleeUnit". Make sure to write this line above the lines where you actually create the enemy units. We can then replace all instances of "Standard MeleeUnit" in our script with our new variables enemy_unit_name.

I'm also adding another comment -- VARIABLES on the line above to organize where I track my variables.

13 refactor

We can store the x, y coordinates in an array variable.

-- VARIABLES
local enemy_points = {
    {20, 14},
    {21, 16},
    {20, 18}
}

We can reference array values in our script like so:

-- VARIABLES
local enemy_unit_name = DCEI.Unit("Standard MeleeUnit")
local enemy_points = {
    {20, 14},
    {21, 16},
    {20, 18}
}

-- TRIGGERS
DCEI.CreateUnit(-1, -1, enemy_unit_name, enemy_points[1][1], enemy_points[1][2])
DCEI.CreateUnit(-1, -1, enemy_unit_name, enemy_points[2][1], enemy_points[2][2])
DCEI.CreateUnit(-1, -1, enemy_unit_name, enemy_points[3][1], enemy_points[3][2])

Lastly we can clean up our script with a for loop to create our three enemy units with less code:

-- TRIGGERS
for i = 1, 3, 1 do
    DCEI.CreateUnit(-1, -1, enemy_unit_name, enemy_points[i][1], enemy_points[i][2])
end

We can use a variable in our for loop to increase readability.

-- TRIGGERS
for i = 1, 3, 1 do
    local point = enemy_points[i]
    DCEI.CreateUnit(-1, -1, enemy_unit_name, point[1], point[2])
end

It's also good practice to make a variable for "Hero IceMage" as well, so let's do that.

-- VARIABLES
local hero_unit_name = "Hero IceMage"

-- TRIGGERS
DCEI.CreateUnit(1, 1, hero_unit_name, 16, 16)

Now that you refactored your code, your final Trigger.lua.txt script should look like this:

14 Final Script

Look at how clean and readable that code is now!


Tutorial Map: Tutorial 1-4 Triggers

Next Up: Tutorial 1–5: Writing More Triggers In Lua

⚠️ **GitHub.com Fallback** ⚠️