Tutorials: wallsets and custom monsters, objects, etc
Moderator: Sophia
Forum rules
Please read the Forum rules and policies before posting.
Please read the Forum rules and policies before posting.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Question on alcoves please! I have created a new custom alcove, copying the base alcove obj. code , but objects placed "in" the alcove don't sit at the correct height. Is there a way to define the height an object is seen at when placed in an alcove? Many thanks!
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
Not directly. Objects in alcoves are always drawn at 15/16 the total height of the alcove, because that looked right for DM and I didn't ever delve into alcoves that looked substantially different.
- Gambit37
- Should eat more pies
- Posts: 13766
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
Wasn't there a demo of different sized alcoves in the test dungeon? Perhaps investigate that example and see if it can be adapted?
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
I wasn't inclined to fix this but the more I look at this code the more I hate it. Expect 0.84 soon.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Well, short term fix was I noticed I had a lot of transparency outside the actual alcove graphic in the bitmap, I cut this off and the 15/16 rule has put the objects back into position...! Thanks.
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
DSB 0.84 will add a y_subtract_denominator property, and the standard alcoves will have a value of 16. The height of the alcove will be divided by this number and then subtracted from the y position of any objects in the alcove. A value of 0 will subtract 0.
There are some limits to doing it this way, of course. A value of 1 subtracts the full height, a value of 2 is halfway down, a value of 3 is 2/3 of the way down, and so on, so this really only has any resolution at all for items at the bottom of the alcove. This is how it normally works so it should be fine for most cases. I'm not opposed to adding absolute pixel offsets but that is more work, so I don't really want to bother if nobody's actually going to use them.
There are some limits to doing it this way, of course. A value of 1 subtracts the full height, a value of 2 is halfway down, a value of 3 is 2/3 of the way down, and so on, so this really only has any resolution at all for items at the bottom of the alcove. This is how it normally works so it should be fine for most cases. I'm not opposed to adding absolute pixel offsets but that is more work, so I don't really want to bother if nobody's actually going to use them.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Thanks Sophia, this sounds good. My particular alcove graphic has a visible lip at the bottom edge, effectively like a very slightly protruding shelf with some thickness. So this makes the bottom of the alcove bitmap lower then the ‘surface’ of the alcove that the object is placed on. Your proposed amendment above would go a long way to fine tuning the object placement in respect of this. Thank you.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Quick question on this mechanic: Is it possible to drop more than one type of food or object?Sophia wrote: Wed Jan 22, 2025 9:15 pm Ah, I see now. The food_type property is the archetype that is actually dropped. It doesn't even have to actually be food, it can drop any object. You can use the properties min_food and max_food to specify the values; if you want "sometimes none" you can set min_food to 0.
When a monster dies, its on_die function is called, which is setup_food_drop in this case. This places the food into the monster's inventory. Then the engine deletes the monster instance and drops its inventory onto the floor, so the food is dropped.
- Gambit37
- Should eat more pies
- Posts: 13766
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
I've now unarchived my DSB project and have been going through it to understand what I have left to do. It's a lot! Anyway, I can now answer your question. Monsters that drop objects just need a couple of properties setup, eg, to drop multiple items use a table listing the items in drop_item_type:
To drop a single item, use the name of the item in quotes, eg, the golem has this:
Note that on_die=setup_item_drop overrides the food drop mechanic, so if you also want to drop food you can add it to the table, or write your own function to do cleverer things. Have a look in the monster.lua file in the base folder to see the various monster specific drop functions.
Code: Select all
obj.skeleton = {
[...]
on_die=setup_item_drop,
drop_item_type={ "falchion", "shield_wood" },
[...]
}
Code: Select all
drop_item_type="club_stone",
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Thanks Gambit, ah yes of course, the Skeleton! Silly me,I should have remembered and checked that before asking. All makes sense, thank you.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Thinking about this for a sec.... potential stupid idea alert: would it be possible to use a Monster for an "object", keep the monster totally static, unkillable, it does nothing other than be decoration, and then utilise it's abilty to have a FRONT, BACK, and SIDE graphic... so as to simulate the above, but with only one "object"? It's a bit hacky, but... just curious! I might try it..Sophia wrote: Sat Jan 18, 2025 11:26 pm Right, viewangle allows you to specify what directions an object is visible from, so by stacking up multiple instances in a square with different viewangle values, it will look like something that looks different depending on the direction.
The simplest way is to set the archetype's viewangle property to a direction: NORTH, SOUTH, EAST, or WEST. This will make any instances of the archetype visible from only that direction.
Alternatively, if you want an object to be visible from multiple directions, you can specify viewangle as a table of bools, in the order north, east, south, west. So, for example:This object is only visible if you are north or south; it is invisible from the east or west.Code: Select all
obj.myobj.viewangle = { true, false, true, false }

- Gambit37
- Should eat more pies
- Posts: 13766
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
I have an immobile invisible monster that I use to create destructible obstacles, so I think your idea should work. You might get some issues with offsets though.
Another way would be to create the four objects in Lua, but only place one of them in ESB. Then write a small function that spawns the three other objects and attach that function to the on_spawn method of the first object.
Another way would be to create the four objects in Lua, but only place one of them in ESB. Then write a small function that spawns the three other objects and attach that function to the on_spawn method of the first object.
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
Take a look at create_linked_object and how it is used by pits to spawn their ceiling pits as an example. It could be used as-is or as a basis to write your own code.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Ok - so I thought I understood this at the time, but evidently I didn't! I was today trying to split out my various objects and graphics items into more discrete and manageable sub lua files. My Startup.lua reads like this, splitting the code into GFX files for the bitmaps, and OBJ files for the various object descriptions:Sophia wrote: Sat Jan 18, 2025 7:59 pm Splitting code off to more .lua files is what the lua_manifest is for. You can include files there and they will be loaded by DSB.
Code: Select all
lua_manifest = {
"DH_GFX_Dungeon.lua",
"DH_GFX_Monsters.lua",
"DH_GFX_Things.lua",
"DH_GFX_wallsets.lua",
"DH_OBJ_Floor Items.lua",
"DH_OBJ_Misc_UI.lua",
"DH_OBJ_Monsters.lua",
"DH_OBJ_TH_Armour.lua",
"DH_OBJ_TH_Food.lua",
"DH_OBJ_TH_Items.lua",
"DH_OBJ_TH_Weapons.lua",
"DH_OBJ_Wallitems.lua",
}
Now I'm not sure what I'm doing wrong. Could you possibly explain it to me in simple steps? (...and sorry for not understanding something probably super basic..)
Or is it simply that object definitions cannot appear in any file other than objects.lua?
Many thanks!

- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
Strictly speaking, object definitions can't appear in any file other than objects.lua, but there's a workaround. You can use dsb_import_arch. Just ignore the field where you're supposed to specify the arch's name and import whatever code you want.
Add lines like this to objects.lua:
EDIT: Fixed syntax.
Add lines like this to objects.lua:
Code: Select all
dsb_import_arch("DH_OBJ_Floor_Items.lua", "")
--etc.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Thank you so much, Sophia. I have added the objects.lua which now contains only the dsb_import_arch lines (one per OBJ lua), changed the manifest in startup to omit any of the OBJ references, but now I get an error message saying that a file is not found, but it doesn’t tell me which file, it just mentions the folder location that the dungeon (and all other lua files) is in. Feel like I’m missing something basic, but I don’t know what! Any ideas what this might be?
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Ah, I noticed in test dungeon it’s potentially more like this; lua file first, then optionally an object in that file:
I changed it round to this, I think they’re loading ok but I have a couple of (I think) unrelated errors I still need to fix (finding the right assets)
Code: Select all
dsb_import_arch("DH_OBJ_Floor_Items.lua", “”)
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
Ah, yes. I hadn't actually used that function in a couple years.
I'm glad you figured it out!
I've fixed my initial post above in case anyone stumbling across it gets confused.

I've fixed my initial post above in case anyone stumbling across it gets confused.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Awesome, I have it all working smoothly now, it's much easier to manage all the different code.
I managed to make the static monster hack work also. Working out pretty well on initial test. Example use is a freestanding statue or gargoyle. Might try it also for damageable barrel or urn (stores objects, releases them when hit for damage). Will see if I can also use med and far graphics for the monster bitmaps, to see if I can tone it in a bit better at distance. Gambit, offsets seem to be ok.
Only issue is, an object placed on the same tile as the static monster cannot be picked up.... !
I managed to make the static monster hack work also. Working out pretty well on initial test. Example use is a freestanding statue or gargoyle. Might try it also for damageable barrel or urn (stores objects, releases them when hit for damage). Will see if I can also use med and far graphics for the monster bitmaps, to see if I can tone it in a bit better at distance. Gambit, offsets seem to be ok.
Only issue is, an object placed on the same tile as the static monster cannot be picked up.... !
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
You can set no_stopclicks to true in a monster's archetype to allow objects to be picked up from its tile.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Ahhh, useful, thanks. Is it possible to stop objects going into a tile entirely?
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
The simplest way to do that is to just put an invisible wall on the tile.
- Gambit37
- Should eat more pies
- Posts: 13766
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
Oh my goodness. First time I've heard of this. Gamechanger!Sophia wrote: Sun Feb 02, 2025 1:31 am You can set no_stopclicks to true in a monster's archetype to allow objects to be picked up from its tile.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Well. The plus side is I just discovered the 2x mode… can’t believe I wasn’t aware of this until just yesterday. The down side… I need to sharpen up my graphics skills a bit more now, and the micro adjustments via offsets and tweaks of graphics just got a bit harder….
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Am just considering how to organise the bitmaps:
Ie, is the word "path" after "local" simply a label?
Or, can I enter several paths?
... where each of the three bitmaps is in a different "pics" folder?
Thanks
Can this work by specifying local path, local path2, local path3, etc?Sophia wrote: Sat Jan 18, 2025 7:59 pm
A simple way is to concatenate a string like this:This makes things shorter and makes it easier to change paths.Code: Select all
local path = "folder/pics/" gfx.my_bmp = dsb_get_bitmap("MY_BITMAP", path .. "my_bitmap.png")
Code: Select all
local path = "folder/pics1/"
local path2 = "folder/pics2/"
local path3 = "folder/pics3/"
gfx.my_bmp = dsb_get_bitmap("MY_BITMAP", path .. "my_bitmap.png")
gfx.my_other_bmp = dsb_get_bitmap("MY_BITMAP", path2 .. "my_bitmap.png")
gfx.an_other_bmp = dsb_get_bitmap("MY_BITMAP", path3 .. "my_bitmap.png")
Or, can I enter several paths?
Code: Select all
local path = "folder/pics1/"
local path = "folder/pics2/"
local path = "folder/pics3/"
gfx.my_bmp = dsb_get_bitmap("MY_BITMAP", path .. "my_bitmap.png")
gfx.my_other_bmp = dsb_get_bitmap("MY_BITMAP", path .. "my_bitmap.png")
gfx.an_other_bmp = dsb_get_bitmap("MY_BITMAP", path .. "my_bitmap.png")
Thanks

- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
It's a single variable. Your second example will keep overwriting path. I'd recommend doing it like this:
If you actually wanted it to work like your second code, you could write a function for that, though.
Code: Select all
local paths = {
"folder/pics1/",
"folder/pics2/",
"folder/pics3/"
}
gfx.my_bmp = dsb_get_bitmap("MY_BITMAP", paths[1] .. "my_bitmap.png")
gfx.my_other_bmp = dsb_get_bitmap("MY_BITMAP", paths[2] .. "my_bitmap.png")
gfx.an_other_bmp = dsb_get_bitmap("MY_BITMAP", paths[3] .. "my_bitmap.png")
Code: Select all
local n = 0
local paths = {
"folder/pics1/",
"folder/pics2/",
"folder/pics3/"
}
local function autopath()
n = n + 1
return paths[n]
end
gfx.my_bmp = dsb_get_bitmap("MY_BITMAP", autopath() .. "my_bitmap.png")
gfx.my_other_bmp = dsb_get_bitmap("MY_BITMAP", autopath() .. "my_bitmap.png")
gfx.an_other_bmp = dsb_get_bitmap("MY_BITMAP", autopath() .. "my_bitmap.png")
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
Thank you so much. I see how it works now. Weighing this up against the other option using the graphics.cfg. Really appreciate your help in explaining all this.
- Gambit37
- Should eat more pies
- Posts: 13766
- Joined: Wed May 31, 2000 1:57 pm
- Location: Location, Location
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
My project has ended up a mixture of stuff in the graphics.cfg and then a ton of new stuff organised via chunked files called in the manifest. It's pretty messy and could do with an overhaul. With hindsight, I should have used the graphics.cfg for all the direct replacements, and then only added new files for new custom graphics that don't map to the existing images. Another way is to not use the graphics.cfg at all and instead specify everything in custom new override files (which is how I originally started) but that seems to increase loading time.
Right now I've got such a messy mixture that I can't remember where anything is, and this is one reason why I'm struggling to restart the project: do I spend time reorganising with the benefit of hindsight, or just leave it chaotic and finish everything that's missing and broken first? No right or wrong answer really, I guess we all just find ways that work for us...?
Right now I've got such a messy mixture that I can't remember where anything is, and this is one reason why I'm struggling to restart the project: do I spend time reorganising with the benefit of hindsight, or just leave it chaotic and finish everything that's missing and broken first? No right or wrong answer really, I guess we all just find ways that work for us...?
- Sophia
- Concise and Honest
- Posts: 4306
- Joined: Thu Sep 12, 2002 9:50 pm
- Location: Nowhere in particular
- Contact:
Re: Tutorials: wallsets and custom monsters, objects, etc
It does. If you put everything into new files, then it loads the DM image in base/, trashes the DM image, and then loads your custom image. This rather inefficient process is one big reason why being able to directly substitute images via graphics.cfg exists.Gambit37 wrote: Tue Feb 04, 2025 12:00 pm Another way is to not use the graphics.cfg at all and instead specify everything in custom new override files (which is how I originally started) but that seems to increase loading time.
- Ser Xav
- Lo Master
- Posts: 449
- Joined: Mon Jan 21, 2013 10:58 pm
- Location: I see walls stretching off into the darkness...
Re: Tutorials: wallsets and custom monsters, objects, etc
So I am attempting this method to see how it works out. I think I've set it all up succesfully. I have created the graphics.cfg which is sitting in same folder as the dungeon.lua. All the paths are correct, as is the graphics_path = { ... example couple of lines below (from a much bigger list):Sophia wrote: Sat Jan 18, 2025 7:59 pm
If you want to delve a little bit more into Lua code you can use the graphics_paths table, which is defined in graphics.cfg. DSB can't automatically scan or anything like that, but you can generate this table of key:value pairs corresponding long names with short names however you want to, so you can concatenate strings to automatically build paths or whatever else. For example, this code has the same effect:Code: Select all
-- In graphics.cfg graphics_paths = { MY_BITMAP = "folder/pics/my_bitmap.png" }
Using graphics_paths also allows you to replace existing bitmaps without reloading anything or changing any code, because you can just change the path to the bitmap.Code: Select all
-- In your normal code gfx.my_bmp = dsb_get_bitmap("MY_BITMAP")
Code: Select all
graphics_paths = {
DOOR_POWER_01 = "X:\00_DM_Project_2025\DSB_DarkHalls\DUNGEON\DH_GFX\01_DOORS\DOOR_POWER_01.PNG",
DOOR_WOODEN_03 = "X:\00_DM_Project_2025\DSB_DarkHalls\DUNGEON\DH_GFX\01_DOORS\DOOR_WOODEN_03.PNG",
SENTINEL_01 = "X:\00_DM_Project_2025\DSB_DarkHalls\DUNGEON\DH_GFX\05_MONSTERS\SENTINEL_01.PNG",
Code: Select all
dsb_import_arch("DH_OBJ_Monsters.lua", "")
dsb_import_arch("DH_OBJ_TH_Items.lua", "")
etc
etc
Code: Select all
lua_manifest = {
"DH_GFX_Monsters.lua",
"DH_GFX_Things.lua",
etc
etc
}
Also, I don't know if the problem is with the file, or with the process. In graphics.cfg, the filepath is in the middle of a much bigger list alphabetically, in the DH_GFX_monsters.lua it's listed first. I've --commented out the object and gfx references with it in all files, to try to omit it from the loading process, but oddly it reports the same error regardless.
I know I always say I think I'm probably doing something obvious wrong (I'll get some t-shirts printed), but... I don't know what the error is. Am I doing the path incorrectly?
Any ideas?
