[DSB Tutorial 3] More on Triggers, and Writing Custom Lua

This forum is for the Lua scriptable clone of DM/CSB called Dungeon Strikes Back by Sophia. Use DSB to build your own highly customised games.

Moderator: Sophia

Forum rules
Please read the Forum rules and policies before posting.
Post Reply
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

[DSB Tutorial 3] More on Triggers, and Writing Custom Lua

Post by Sophia »

Counters!
In DSB (and in standard DM) a counter allows you to take action after something receives multiple activations. For example, opening a door after two different buttons have been pushed, closing a pit after a pad has been stepped on three times, and so on. In DSB, counters are found in "FloorFlats", under the "MECHANICS" class, called, appropriately enough, "counter."
Image

Place the counter in an out of the way place. The exact location doesn't matter. Most designers place counters and other such mechanics items inside of walls near the location that they're needed, but this isn't required.
Image

Right click the counter to edit it. It defaults to needing two activations to trigger it. You can change this if you want, but leave this alone for now. Each time a counter is activated, it will decrement, and it will send its own message when its value is 0. Therefore, it will take two Activate messages to get this counter to 0.
Image

Make two buttons, for example, "button_blue" found in the "BUTTON" class of "Wallitems". Also, give the counter something to trigger, like a "movablewall" (found in the "WALL" class of "FloorFlats") Right click the counter, and in its trigger editor, set the counter to Deactivate the movablewall. The room should end up looking something like this:
Image

Set each button to activate the counter.
Image

It's not necessary to change the buttons' OpBys, but set both of them to Disable Self so that each one can only be pushed once. If you allow the button to be pushed multiple times, then you can activate the counter by pushing one button twice, which isn't what you want.
Image

You can verify that the buttons are set up properly by choosing the Reverse Target Lines option in the View menu. This handy feature shows lines to what targets a given object, not its own targets, e.g., if you hover your mouse over the counter, it draws red lines back to the two buttons because each of the two buttons sends Activate messages to the counter.
Image

You might be tempted to save and test out the dungeon at this point, but it might be kind of inconvenient. Let's move the start point closer to the area we're working. Recall that to set the party's starting position, you can choose Set Party Start in the Edit menu, or press Y on the keyboard. Move the party start position here:
Image

The other problem is that, by default, levels below level 0 are totally dark. While you can cast light spells to remedy this, let's just bump up the level's illumination to make testing easy. Choose Level Info in the Edit menu, or press W on the keyboard. From here you can increase the light level.
Image

Now save and test it out!

Adding a Reset Button!
It works, but it only works once. Granted, that may be all that is needed. However, DSB allows you to reset counters and triggers, via the "Reset" message.

Add another button off to the other side.
Image

Target the counter and your other two buttons. Counters will reset to their default value in response to a Reset message. Buttons that have been disabled by "Disable Self" will become active again.
Image

It should end up looking like this. Note that Reset messages are colored olive.
Image

Save and try it out.

It works, but there's a small cosmetic problem: the buttons stay pushed in. Wouldn't it look better if the buttons popped out again when they were reset? Let's take care of that now.

Terminology!
Before we continue, let's introduce a bit of important terminology. Up until now, everything in the dungeon has just been referred to as an object. This is fine, but it's not very specific, as there are actually two distinct sorts of objects to pay attention to in DSB: archetypes and instances. An archetype represents the category of a dungeon object. For example, "screamer slice" is an archetype. An instance, on the other hand, is a specific item in the dungeon, i.e., one specific screamer slice that Halk the Barbarian is about to shove into his mouth. As such, there can be many instances of a given archetype, and each instance belongs to a given archetype.

Swapper!
When you push a blue button in DSB, the base code changes the button instance's archetype from "button_blue" to "button_blue_pushed", which causes its appearance to change to the pushed in button. So, to pop the button back out, all we have to do is change it back.

The qswapper (quick swapper) allows us to dynamically change the archetype of a given instance. It's found in "FloorFlats", class "MECHANICS". Add one of those now.
Image

Right click to edit the qswapper, and press the "Edit Swap Arch" button. This will allow you to change the archetype that the qswapper's target gets swapped to. It also allows you to specify whether the qswapper targets a specific target list, or the instance operating it. This is useful if you want to make a qswapper that works in response to a wallitem being clicked or the like. For now, though, we want a specific target list, so leave this setting alone.
Image

Target the two buttons on the west side of the room with the qswapper. Qswappers do not have a message type, as they don't actually send a message; they affect their targets directly.

Now, right click the reset button and add an Activate message sent to the qswapper, in addition to the Resets. Now, the buttons will not only be reset, they'll be popped back out, too.
Image

Writing Some Lua!
DSB can do quite a lot with just the basic mechanics available in ESB, and you can actually create a fairly good (if rather standard-looking) dungeon without delving into Lua at all. However, the vast majority of interesting and more advanced effects in a DSB dungeon are created by means of writing Lua code, and you'll need to write a bit of Lua to import custom graphics, too.

A Lua program can be edited by any text editor. Notepad will do! However, I'd recommend something designed for code editing, such as SciTE, vim, or the like. There is also an editor designed specifically for Lua called LuaEdit, but it is at times buggy, so your mileage may vary.

By default, DSB will attempt to parse a startup.lua located in the same folder as your dungeon. It will also look for a file named objects.lua which contains custom objects you might want to use in your dungeon.

Let's start by creating a startup.lua.
Image

The first thing we'll do is write a very simple function that will be called when you press the reset button. Write the following code in your startup.lua:

Code: Select all

function reset_notify()
    dsb_write(system_color, "YOU PUSHED THE RESET BUTTON.")
end
This is a very simple Lua function that will print "YOU PUSHED THE RESET BUTTON." to the game console in the standard system color, a bright cyan. Now we just have to add a way to invoke it.

Function Callers!
One useful way to invoke custom Lua code is through the function_caller object. Like most other mechanics-related archetypes, it's found in "FloorFlats" under class "MECHANICS". Add a function_caller, and right click it to edit it. There, click the "Edit Called Functions", and tell the function_caller to call our newly created function, reset_notify, when it is activated.
Image

Edit the reset button and add another Activate message, this one directed at the function_caller. Now, when you push it, it will send Reset messages to the other two buttons and the counter, an Activate to the qswapper to pop the buttons out, and an Activate to the function_caller, which will call reset_notify and print a message to the console.

More Sophisticated Actions!
Naturally, inside of this Lua function we can do a lot more sophisticated things than just print a message. Change the code to this:

Code: Select all

function reset_notify()
    dsb_write(system_color, "YOU PUSHED THE RESET BUTTON. WIN A PRIZE!")
    local lev, xc, yc, dir = dsb_party_coords()
    dsb_spawn("apple", lev, xc, yc, dir)
end
After printing the message, the next line creates four local variables, lev, xc, yc, and dir, and initializes them with the output of the function dsb_party_coords. In other words, it stores the party's level, x coordinate, y coordinate, and direction in these four variables. After that, an apple is spawned at those coordinates, i.e., right at the party's feet. This means that when this code is executed, the message will be printed, and then an apple will appear at the party's feet. Try it out!

You can take a look at the DSB Wiki for a lot of information on the various dsb_ functions you can use.

Creating Objects!
We've made this reset button pretty fancy. Let's give it a new look, as well. You can create your own graphics if you want, or just use the following four images, which are versions of the button that have been recolored orange.
button_orange_front.pcx
button_orange_side.pcx
button_orange_front_pushed.pcx
button_orange_side_pushed.pcx
Place these four files in your dungeon's directory along with your dungeon.lua and your startup.lua.

While it's possible to just dump all of your startup code in startup.lua, it's a better idea to organize your code across multiple files, like the base code does. So, let's create a file called graphics.lua where we load our custom graphics.

Make a new file called graphics.lua and put the following code in it:

Code: Select all

gfx.button_orange_front = dsb_get_bitmap("BUTTON_ORANGE_FRONT")
gfx.button_orange_side = dsb_get_bitmap("BUTTON_ORANGE_SIDE")
gfx.button_orange_pushed_front = dsb_get_bitmap("BUTTON_ORANGE_PUSHED_FRONT")
gfx.button_orange_pushed_side = dsb_get_bitmap("BUTTON_ORANGE_PUSHED_SIDE")
These four lines create four new entries in the gfx table, a global table where DSB stores all of its graphics.

You can specify a file path and extension if you want:

Code: Select all

gfx.button_orange_front = dsb_get_bitmap("BUTTON_ORANGE_FRONT", "button_orange_front.pcx")
Now we need to tell DSB to load this new file. By default, as mentioned before, it only loads startup.lua (as well as objects.lua, but only object archetypes should be defined in there) so we'll need to inform DSB that we have a new file it needs to load. This is done by means of a lua_manifest, which is a Lua table defined somewhere in startup.lua that lists all of the other files needed. For convenience, it's best to put the lua_manifest near the beginning or near the end.

Right now, it's just the one file, so the lua_manifest is very simple. Add the following to startup.lua:

Code: Select all

lua_manifest = {
	"graphics.lua"
}
Finally, we need to create an objects.lua to define our new orange button. Make a new file and call it objects.lua, and write the following code into it:

Code: Select all

obj.button_orange = clone_arch(obj.button_green, {
    front = gfx.button_orange_front,
    side = gfx.button_orange_side,
    click_to = "button_orange_pushed"
} )

obj.button_orange_pushed = clone_arch(obj.button_green_pushed, {
    front = gfx.button_orange_pushed_front,
    side = gfx.button_orange_pushed_side,
    click_to = "button_orange"
} )
It's possible to define object archetypes completely from scratch in DSB, but a more convenient way is often to use clone_arch, which makes an exact copy of a given archetype, and then takes a table that contains changes you want to make to that arch. Here, we've cloned the green button, and simply changed its bitmaps and the arch it changes to when clicked. Feel free to look through base/objects.lua to get a feel for the properties objects have, and which object archetypes would make the best base for cloning from. Future tutorials will also talk further about object properties, of course.

Now we can go back to ESB. First, we'll have to inform it of our changes. Choose Reload Archs from the Edit menu. Provided you entered all of the code properly, it should reload the Lua archetypes without a problem. Now our brand new button_orange object is available for use in ESB!

Right click the reset button and click "Change Object Archetype". You can then select your new button.
Image
Now save and try it out. Your reset button is now your new custom orange button!

Next time, we'll make some more different custom objects, including items with attack methods and monsters with unique behaviors.
User avatar
Gambit37
Should eat more pies
Posts: 13715
Joined: Wed May 31, 2000 1:57 pm
Location: Location, Location
Contact:

Re: [DSB Tutorial 3] More on Triggers, and Writing Custom Lu

Post by Gambit37 »

Aaahh..... lightbulb :-) Very cool, this is the tutorial I needed. Binding LUA functions to be invoked via dungeon mech was something I didn't understand how to do. It's all falling into place now.... thanks so much for doing these tuts, this is exactly what I need to get properly started with DSB :-)
User avatar
Bit
Arch Master
Posts: 1064
Joined: Mon Mar 03, 2008 10:53 am
Location: Nuts trees

Re: [DSB Tutorial 3] More on Triggers, and Writing Custom Lu

Post by Bit »

Possibilites are really really impressive - and the work behind it unimaginable!
User avatar
ian_scho
High Lord
Posts: 2806
Joined: Fri Apr 07, 2006 8:30 am
Location: Zaragoza, Spain

Re: [DSB Tutorial 3] More on Triggers, and Writing Custom Lu

Post by ian_scho »

Great work Sophia.
LuaEdit download
User avatar
zoom
Grand Master
Posts: 1819
Joined: Tue Sep 23, 2003 1:27 am
Location: far away but close enough

Re: [DSB Tutorial 3] More on Triggers, and Writing Custom Lu

Post by zoom »

IT is good that you can post -- eahmm -- meaningful comments, too ! ;)
User avatar
Kesa
Journeyman
Posts: 67
Joined: Fri Sep 10, 2010 11:44 pm

Re: [DSB Tutorial 3] More on Triggers, and Writing Custom Lu

Post by Kesa »

This tutorial helped me a lot when it came down to making function_call events, your the best Sophia ^.^ now all our games we make with dsb will be awesome!!!
Post Reply