Questions about DSB/ESB
Moderator: Sophia
Forum rules
Please read the Forum rules and policies before posting.
Please read the Forum rules and policies before posting.
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
Once a table has been defined for export, DSB will save the entire table.
DSB will also save all exvar values with the dungeon. Exvars also set the messages and targets of buttons and triggers, so, if they were not saved, the entire dungeon would basically cease to function. So, if something isn't getting saved properly, I think the problem is in your code somewhere.
As for "important_exvars", that's used by ESB, not DSB, in order to define the ordering of the list of exvars in the editor. It places "important" ones at the top, in the order defined, and then puts any others in alphabetical order beneath those.
DSB will also save all exvar values with the dungeon. Exvars also set the messages and targets of buttons and triggers, so, if they were not saved, the entire dungeon would basically cease to function. So, if something isn't getting saved properly, I think the problem is in your code somewhere.
As for "important_exvars", that's used by ESB, not DSB, in order to define the ordering of the list of exvars in the editor. It places "important" ones at the top, in the order defined, and then puts any others in alphabetical order beneath those.
- Lord_BoNes
- Jack of all trades
- Posts: 1064
- Joined: Mon Dec 01, 2008 12:36 pm
- Location: Ararat, Australia.
Re: Questions about DSB/ESB
It seems that you're correct here. The problem was a coding issueSophia wrote:So, if something isn't getting saved properly, I think the problem is in your code somewhere.
1 death is a tragedy,
10,000,000 deaths is a statistic.
- Joseph Stalin
Check out my Return to Chaos dungeon launcher
And my Dungeon Master Clone
- ebeneezergude
- Expert
- Posts: 345
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Questions about DSB/ESB
Oh, sorry, didn't see the "moneybox". A DM2 mechanic?Lord_BoNes wrote:@Ebeneezergude: Isn't that the job of the "moneybox"? You can store craploads of coins/gems in the thing, and it keeps on storing more
Which is basically what Sophia said: making the "stack" a container and doing various tricks...
- Lord_BoNes
- Jack of all trades
- Posts: 1064
- Joined: Mon Dec 01, 2008 12:36 pm
- Location: Ararat, Australia.
Re: Questions about DSB/ESB
It's not a "DM2 Mechanic" so to speak... it's part of the test dungeon and it requires it's own custom Lua code to work the way it does. As far as DSB is concerned, it's just a bottomless chest that holds coins/gems. Check out the test_dungeon/moneybox.lua to see the code I'm talking about.
1 death is a tragedy,
10,000,000 deaths is a statistic.
- Joseph Stalin
Check out my Return to Chaos dungeon launcher
And my Dungeon Master Clone
- Lord_BoNes
- Jack of all trades
- Posts: 1064
- Joined: Mon Dec 01, 2008 12:36 pm
- Location: Ararat, Australia.
Re: Questions about DSB/ESB
Another question: Is there a way to determine keyboard events (key presses/releases) in DSB? If not, could a pair of new events be introduced sys_key_press and sys_key_release?
EDIT: I'm also looking to intercept keyboard events while in a "fullscreen renderer" (like the dungeon entrance, for instance). Would that be possible?
EDIT: I'm also looking to intercept keyboard events while in a "fullscreen renderer" (like the dungeon entrance, for instance). Would that be possible?
1 death is a tragedy,
10,000,000 deaths is a statistic.
- Joseph Stalin
Check out my Return to Chaos dungeon launcher
And my Dungeon Master Clone
- Chaos-Shaman
- High Lord
- Posts: 2642
- Joined: Wed May 03, 2006 7:26 pm
- Location: The Gates of Hell
Re: Questions about DSB/ESB
i should have saw it... yuuup, there's no stopping it now
keep your gor coin handy
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
I have a really basic question that I'm kinda stumped by: what's the "right" way to find the ID of a specific unique arch that might be placed anywhere in the entire dungeon? I can do all the cell loops and checks, but my main stumbling block is: how do I find out the total number of levels in the dungeon?
EDIT: I totally forgot about dsb_insts() and got hung up on counting the levels first to loop through them.
Although, the question still stands, if I did want to find out the total number of levels, is there a way to do it?
EDIT: I totally forgot about dsb_insts() and got hung up on counting the levels first to loop through them.
Although, the question still stands, if I did want to find out the total number of levels, is there a way to do it?
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
Actually, no!
There hasn't been a need for it until now. I guess there still isn't, actually.
There hasn't been a need for it until now. I guess there still isn't, actually.
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
No problem, I figured I could just store the highest level number reached when iterating over all the insts: works great.
Another question: are there any performance or stability issues I should be aware of when using functions that call themselves? For example, I wanted to get the random RA door animation back from original DM, so I cloned 4 doors, each with a static bitmap in a different direction, then added this simple function.
It works fine, but I wondered if this is the right approach and if it's OK to do this sort of thing?
Another question: are there any performance or stability issues I should be aware of when using functions that call themselves? For example, I wanted to get the random RA door animation back from original DM, so I cloned 4 doors, each with a static bitmap in a different direction, then added this simple function.
It works fine, but I wondered if this is the right approach and if it's OK to do this sort of thing?
Code: Select all
function mhf_animate_door_ra(self, id)
local timer = dsb_rand(1,4)
local door = dsb_rand(1,4)
dsb_delay_func(timer, function()
dsb_qswap(id, "door_ra" .. door)
mhf_animate_door_ra(self, id)
end)
end
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
That's clever, but it's unfortunately not going to work. You aren't running into any recursion issues and there is nothing inherently wrong with setting that up that way, but the problem is that DSB doesn't bother to try to serialize lambda functions, so it's not going to survive a save and load.
You'd need to use messages, probably. This could also be something that you might want a master "ra door controller" object in the dungeon that handles all of the swaps rather than a bunch of messages flying around each door autonomously.
Or I could just make animations support a randomized frame delay...
You'd need to use messages, probably. This could also be something that you might want a master "ra door controller" object in the dungeon that handles all of the swaps rather than a bunch of messages flying around each door autonomously.
Or I could just make animations support a randomized frame delay...
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
Cool, thanks for the insight. I thought there might be something weird I wasn't aware of. While the function worked OK, it felt wrong!
I'll investigate how to do the master RA Door controller you suggested. Is that something I'd need a trigger controller in the dungeon for, or would it be better to do it all in Lua?
I'll investigate how to do the master RA Door controller you suggested. Is that something I'd need a trigger controller in the dungeon for, or would it be better to do it all in Lua?
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
You could build it entirely with dungeon mechanics for that authentic DM feel, but you'd end up with the sort of crazy mess of mechanics and actuators that made me add Lua scripting as such an integral part of the game in the first place.
My suggestion is to make a ra_door_controller arch and place one (and only one) inst of that somewhere in the dungeon. Send it a next tick message from somewhere else to get things going, and then give it a msg_handler for that message that uses dsb_insts to grab a list of all of the ra doors in the dungeon (it need only do this once and store them away, unless you think you're going to be dynamically creating and destroying doors!) and randomize them, then it can send itself a next tick message in a tick or two and do it all again.
I can help you with the actual code if needed but this should hopefully be enough to get you started.
My suggestion is to make a ra_door_controller arch and place one (and only one) inst of that somewhere in the dungeon. Send it a next tick message from somewhere else to get things going, and then give it a msg_handler for that message that uses dsb_insts to grab a list of all of the ra doors in the dungeon (it need only do this once and store them away, unless you think you're going to be dynamically creating and destroying doors!) and randomize them, then it can send itself a next tick message in a tick or two and do it all again.
I can help you with the actual code if needed but this should hopefully be enough to get you started.
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
Great, thanks, I'll investigate and see if I can get it working with messages.
Another question: How would I increase the default quiver area from 4 items to 6? Or add an extra slot to the pouch?
Another question: How would I increase the default quiver area from 4 items to 6? Or add an extra slot to the pouch?
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
You'd need to edit the inventory_info table in base/inventory_info.lua and define some new slots. The current quiver slots are sequential but there is no rule they have to be, so I'd recommend just putting your new slots in at the end. You can start at MAX_INV_SLOTS. (Don't redefine this variable though, even if you're adding more slots; it's somewhat poorly named)
In DSB 0.69, it won't search your new slots for ammo, but I was already planning on changing that for 0.70, so I'll just give you the DSB 0.70 code right now. You don't need to add this to your dungeon because it'll be part of the base code in the next DSB, so for now just replace search_quiv_for_ammo in base/methods.lua with the following code:
After making that change, you'll be able to add quiver_locations to your inventory_info and DSB will search for ammo in the new locations. For example, if you added INV_QUIV5 and INV_QUIV6 slots, you just need to add this line:
In DSB 0.69, it won't search your new slots for ammo, but I was already planning on changing that for 0.70, so I'll just give you the DSB 0.70 code right now. You don't need to add this to your dungeon because it'll be part of the base code in the next DSB, so for now just replace search_quiv_for_ammo in base/methods.lua with the following code:
Code: Select all
function search_quiv_for_ammo(who, need_type)
local qloclist = inventory_info.quiver_locations
local ploclist = inventory_info.pouch_locations
-- fall back to the hardcoded list
if (not qloclist) then qloclist = { INV_QUIVER, INV_QUIV2, INV_QUIV3, INV_QUIV4 } end
if (not ploclist) then ploclst = { INV_POUCH, INV_POUCH2 } end
local qammo
qammo = search_llist_for_ammo(who, need_type, qloclist, false)
if (not qammo) then
qammo = search_llist_for_ammo(who, need_type, ploclist, false)
if (not qammo) then
qammo = search_llist_for_ammo(who, need_type, qloclist, true)
end
end
return qammo
end
Code: Select all
inventory_info.quiver_locations = { INV_QUIVER, INV_QUIV2, INV_QUIV3, INV_QUIV4, INV_QUIV5, INV_QUIV6 }
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
I have the RA door thing half working: I can get all the doors to show a different image after a randomised delay, but they all share the same delay so are in sync with each other, which isn't what I want. It does still work after a save/load though, which is great
I'm not sure how to send each door a different delay, so that each door is independently qswapped from all the others at a different time?
EDIT: Hmm, I'm looking at two RA doors next to each other and they are in fact animating out-of-sync with each other. Which is what I want, but I don't understand how that's happening, lol!
These are the various bits of code I have so far, firstly I defined a global to store the ID of the RA door controller:
Then the controller arch definition:
Then the message handler:
Then my setup function (which runs as part of the game startup) looks for the controller and any RA doors, and stores the RA door IDs in the controller:
Finally the function called by the message handler to do the qswapping:
I'm not sure how to send each door a different delay, so that each door is independently qswapped from all the others at a different time?
EDIT: Hmm, I'm looking at two RA doors next to each other and they are in fact animating out-of-sync with each other. Which is what I want, but I don't understand how that's happening, lol!
These are the various bits of code I have so far, firstly I defined a global to store the ID of the RA door controller:
Code: Select all
radoor_controller = 0
Code: Select all
obj.radoor_controller = {
type="FLOORFLAT",
class="MECHANICS",
msg_handler=mhf_radoor_msg_handler
}
Code: Select all
mhf_radoor_msg_handler = {
[M_NEXTTICK] = "mhf_swap_radoors",
[M_ACTIVATE] = "mhf_swap_radoors",
[M_TOGGLE] = "mhf_swap_radoors"
}
Code: Select all
function mhf_setup_radoor_controller()
local radoor_ids = {}
-- Look for RA doors and a RA door controller in the dungeon:
for id in dsb_insts() do
local arch = dsb_find_arch(id)
if (arch == obj.radoor_controller) then
radoor_controller = id
elseif (arch == obj.door_ra) then
table.insert(radoor_ids, id)
end
end
-- If we have a controller and some RA doors, then store the
-- RA door ids in an exvar on the controller, and send an
-- initial message to the controller to get it started:
if (radoor_controller and (table.getn(radoor_ids) > 0)) then
use_exvar(radoor_controller)
exvar[radoor_controller].door_ids = radoor_ids
dsb_msg(1, radoor_controller, M_NEXTTICK, 0)
end
end
Code: Select all
function mhf_swap_radoors()
-- Loop through all the RA doors we stored earlier,
-- and qswap each door for a random "flip" direction:
local door_ids = exvar[radoor_controller].door_ids
for id = 1, table.getn(door_ids) do
local door = dsb_rand(1,4)
dsb_qswap(door_ids[id], "door_ra" .. door)
end
-- Repeat this function with a random delay:
local timer = dsb_rand(1,6)
dsb_msg(timer, radoor_controller, M_NEXTTICK, 0)
end
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
The radoor_controller global isn't needed, actually. Every message handler function is actually passed three parameters: id which is the id of the inst that got the message, data which is the data parameter, and sender which is the id of the inst that sent the message. So this code is equivalent (and more robust):
The code swaps all doors at the same random interval, so all swaps are synchronized. The reason any given two doors might appear to be out of sync is that your code makes no guarantee that the image swapped to is different from the door's current image. So 25% of the time, there will be no visible swap. You can actually take advantage of this in order to decrease the amount of apparent synchronization.
This reduces the swap interval by half but also adds a 50% chance the door won't be swapped at all. I've also made sure the swap is to a different arch. You can play with these numbers to get the kind of effect you want, I think.
EDIT: Fixed the code.
Code: Select all
function mhf_swap_radoors(id, data, sender)
if (not exvar[id]) then return end
local door_ids = exvar[id].door_ids
-- etc etc
end
Code: Select all
for i = 1, table.getn(door_ids) do
if (dsb_rand(1, 2) == 1) then
local door_arch = dsb_find_arch(door_ids[i])
local doorname = nil
while (not doorname or obj[doorname] == door_arch) do
doorname = "door_ra" .. dsb_rand(1,4)
end
dsb_qswap(door_ids[i], doorname)
end
end
-- Repeat this function with a random delay:
local timer = dsb_rand(1,3)
dsb_msg(timer, id, M_NEXTTICK, 0)
EDIT: Fixed the code.
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
Cool, thank you for the revisions, these work great
Regarding setting the ID of an INST to a global variable:
I have a unique arch object that I'm using to store gameplay data. I have a dsb_insts() loop in my startup that looks for that arch/inst, and assign its ID to a global variable store_data. I can then refer to this in many other functions when I want to store long-term variables, by using exvar[store_data].variable etc. (I ended up preferring this over exporting variables: for some reason an object in the dungeon that stores all my data seems to make more sense to me conceptually, and seems easier to manage.)
Anyway, the approach seems to work fine, but I'm aware it's possibly fragile and "not the DSB way".
So what would be a more robust solution? Do I need to use dsb_insts() to look for my arch/inst every time I want to refer to it in another function? This seemed like a performance issue to me which is why I was avoiding it, but is that the best way? Or is there another best-practice method I should be using?
Regarding setting the ID of an INST to a global variable:
I have a unique arch object that I'm using to store gameplay data. I have a dsb_insts() loop in my startup that looks for that arch/inst, and assign its ID to a global variable store_data. I can then refer to this in many other functions when I want to store long-term variables, by using exvar[store_data].variable etc. (I ended up preferring this over exporting variables: for some reason an object in the dungeon that stores all my data seems to make more sense to me conceptually, and seems easier to manage.)
Anyway, the approach seems to work fine, but I'm aware it's possibly fragile and "not the DSB way".
So what would be a more robust solution? Do I need to use dsb_insts() to look for my arch/inst every time I want to refer to it in another function? This seemed like a performance issue to me which is why I was avoiding it, but is that the best way? Or is there another best-practice method I should be using?
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
The "best" solution is probably to store the data in an exported table. That is:
If you don't want to do that for whatever reason, then your approach works fine.
Code: Select all
dsb_export("data_table")
data_table = {
some_number = 1,
some_string = "hello",
-- etc.
}
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
Cool, thanks, yeah for some reason I couldn't get my head around exports in the context of program flow and resuming save games. I've never been able to get that stop/start sound channel thing to work as a result. (Could really do with a stop_all_sounds() function to be honest!).
Anyway, next questions.
(1) What, if anything, can be customised about the width/height of the console? (And what is the default expected size?)
(2) Would it be possible to add support for custom sized party order icons? I'd like to use the ones from DM2, but they're bigger than those in DM.
Anyway, next questions.
(1) What, if anything, can be customised about the width/height of the console? (And what is the default expected size?)
(2) Would it be possible to add support for custom sized party order icons? I'd like to use the ones from DM2, but they're bigger than those in DM.
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
Quick question about #1 above: There's a note in the wiki about dsb_textformat() controlling the y offsets for the console.
I've been using this function to create wrapping text in other contexts. Can I also use it somehow to auto-wrap text in the console created by dsb_write()?
Or does the output of DSB write always need to be manually created? (IE, I need to use some kind of line-splitting function, as currently used in scrolls?)
I've been using this function to create wrapping text in other contexts. Can I also use it somehow to auto-wrap text in the console created by dsb_write()?
Or does the output of DSB write always need to be manually created? (IE, I need to use some kind of line-splitting function, as currently used in scrolls?)
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
Although a "console" is the modern term for what you would call the lines of text at the bottom of DSB's screen, it's actually pretty threadbare. It's just text dumped to a certain location on the screen. There is currently no support for word wrapping of anything of that sort.
The easiest approach would probably be to write a wrapper function that may make multiple calls to dsb_write if you pass it a long line of text. If this is sufficient, I can probably come up with something without too much trouble.
The easiest approach would probably be to write a wrapper function that may make multiple calls to dsb_write if you pass it a long line of text. If this is sufficient, I can probably come up with something without too much trouble.
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
Thank you, but not to worry, I found an example of what I needed on StackOverflow
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
Is there a way to change the duration of text displayed by dsb_attack_text()?
Or how would I write my own function to display something in that feedback area, for a specified amount of time?
Or how would I write my own function to display something in that feedback area, for a specified amount of time?
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
Right now, the only way you can change what is shown is by writing your own sys_render_attack_result but then of course you have to override that whole function and you're responsible for everything. If you wouldn't mind going into more detail about what you want then I could perhaps work in a simpler way.
Right now the time that the text is shown is hardcoded, but I could pretty easily add a second parameter to the function to allow you to change that.
Right now the time that the text is shown is hardcoded, but I could pretty easily add a second parameter to the function to allow you to change that.
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
I'm happy to override the whole function and have done so for this interface I'm working on. However, I had an idea about providing graphical feedback for other actions in this area, so instead of just specifying "damage burst" or "text", I'd like to render some other stuff instead. I don't want to give too much away here, but if you need more details, let me know and I'll send you a private message.
A duration parameter would definitely be useful, too It's currently slightly too fast for what I have in mind.
A duration parameter would definitely be useful, too It's currently slightly too fast for what I have in mind.
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
If you're writing your own custom renderer anyway, it seems like the easiest workaround (and keeps me from having to write any new code) would be to check if certain special text strings are passed and, if so, render special things. For example, you could write a custom sys_render_attack_result that draws Mophus's portrait if it gets passed "_DSBMOPHUS", which you could then pass via dsb_attack_text. This is the easiest way, but doesn't work if you need to pass any parameters of data, though.
- Gambit37
- Should eat more pies
- Posts: 13715
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Questions about DSB/ESB
OK, here's a probably very basic question: how can I make a destructible floorupright? For example, a blocking mound of rubble that can be attacked with a weapon and reduced to stones/boulders. I'm kinda embarrassed I can't work this out as I'm sure it should be pretty easy...?
- Sophia
- Concise and Honest
- Posts: 4240
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Questions about DSB/ESB
It's actually not that straightforward because the base code doesn't support weapon attacks against anything other than monsters and doors. The simplest fix might be to just put an invisible door on the square and have it respond to an M_BASH message by doing whatever it is you want. The data parameter of M_BASH is 0 if the door is just getting hit (in DM it goes thud) or 1 if the door should actually get destroyed.