Message
| After playing with a Lua interface to SMAUG, I have developed a "scripted" reset system.
This is intended to gradually change the way resets are handled, from "reset" entries in the area file, to doing scripted resets.
The current system is rather inflexible, every x minutes certain rooms will get certain mobs, with certain equipment. There is no provision for randomness. Thus it is all rather predictable.
The scripted resets are implemented by:
- Having a single Lua script state for the entire MUD (this is new, compared to my earlier posts, where there was one script state per player).
- Modifying reset_area to first see if the Lua script will handle resetting a particular area, and if so, let it do it, and ignore the resets in the area file. This minor change looks like this:
void reset_area( AREA_DATA * area )
{
ROOM_INDEX_DATA *room;
if( !area->first_room )
return;
/* see if Lua script will handle it */
if (call_mud_lua ("reset_area", area->filename))
return;
for( room = area->first_room; room; room = room->next_aroom )
reset_room( room );
}
As each area is handled on a case-by-case basis, you can gradually add in scripted resets, an area at a time.
Advantages of scripted resets
Scripting resets adds heaps of flexibility. Here are some ideas:
- Randomize the rooms mobs appear in
Rather than always having a mob appear in the same room, you could make the reset choose a room from a list (eg. neighbouring rooms). This way players can't predict exactly where everything will be after a reset.
- Randomize mob types
You could choose to repop a mob from a list (eg. a warrior one time, a mage the next), so that the areas look more natural.
- Randomize mob numbers
Instead of always repopping (say) 2 mobs in a room, you might vary from 1 to 3, so that the exact contents of a room are less predictable.
- Make loot tables
There are times when you need to generate lots of mobs with similar loot (for example, the cage mobs in the Darkhaven Academy). Rather than tediously listing the same thing for every mob, they can share a common loot table.
- Randomize loot
Instead of always having exactly the same loot on each mob, you could choose loot from lists of things of roughly similar value (eg. one time the mob has a sword, the next time, a mace).
- Randomly have better items
You might make it so that 10% of the time, a mob has an extra item worth more, or more useful (eg. some extra food, or drink, or a potion).
- Randomly have much better items
You might make it so that 1% of the time, a mob has an extra item worth much more, such as a nice sword. This element of surprise would make killing mobs more fun.
- Randomly have rare items
You might make it so that 0.1% of the time, a mob has an extra item worth a great deal. The chance of getting this might be low, but the lucky player that finds it can sell it or use it to his advantage.
- Randomly make objects, like chests
You might arrange that every 10 resets or so, a chest is spawned that has a nice item in it.
- Randomly spawn rare mobs
Every few hours you might spawn an unusual (rare) mob. This might benefit the player in some way, eg.
- Have better loot if you kill it
- Offer an unusual quest (task)
- Be a shopkeeper selling rare things
The reset code could then despawn it 15 minutes later.
- Clean up rubbish
As well as adding stuff, the resets might notice that a room has 20 junk swords in it, and remove most or all of them, preferably if no player is in the room to notice their sudden disappearance.
- Generate messages
The reset code could occassionally broadcast a message to a room or the area. This message might just be local flavour, or notify players that a rare item or mob has been spawned.
As an example of the sort of thing you can do with scripted resets, I have converted the Darkhaven Academy resets into a script. The entire reset script looks like this:
function reset_new_academy ()
-- put the fountains in
multiple_objects (10401, -- fountain
{ 10300, 10305, 10319, 10325, 10326, 10327, 10328,
10329, 10330, 10364, 10366, 10374, 10382, 10386,
10401,
} )
-- close various exits
mud.set_exit_state (10300, "s", "c") -- close door -- Darkhaven Academy
mud.set_exit_state (10309, "n", "c") -- close door -- Wandering Darkhaven Academy
mud.set_exit_state (10310, "s", "c") -- close door -- An Enclosed Room
mud.set_exit_state (10312, "w", "c") -- close door -- Lost in Darkhaven Academy
mud.set_exit_state (10313, "e", "c") -- close door -- A Secret Alcove
mud.set_exit_state (10361, "u", "c") -- close door -- A Final Test
mud.set_exit_state (10362, "d", "c") -- close door -- In the middle of the eastern wall
mud.set_exit_state (10382, "n", "c") -- close door -- North-West Corner
mud.set_exit_state (10386, "d", "c") -- close door -- South-West Corner
mud.set_exit_state (10392, "u", "c") -- close door -- In a Humid Cavern
-- main helper mobs
minv (10399, 10300) -- Tsythia Mistress Headmistress
minv (10340, 10303) -- Domick Dom teacher
minv (10333, 10305) -- healer spectre cage
minv (10394, 10306) -- Abbigayle language teacher
minv (10342, 10319) -- Toric lord healer
minv (10346, 10355) -- Silvina receptionist woman
minv (10343, 10357, 1, 1, -- Zurg sage storekeeper
{}, -- nothing equipped
-- shop inventory
{ 10316, -- torch
10317, -- dried rabbit meat
10314, -- dragonskin skin water
}
)
-- initial mob we are sent to kill
minv (10345, 10308, 1, 1, { neck1 = 10345 } ) -- chadoyn cage, equip: Chadoyn bindings
-- assorted statues for each class
minv (10352, 10318) -- statue warrior cage
minv (10354, 10320) -- statue druid cage
minv (10353, 10321) -- statue vampire cage
minv (10351, 10322) -- statue thief cage
minv (10349, 10323) -- statue mage cage
minv (10350, 10324) -- statue cleric cage
minv (10355, 10391) -- statue ranger cage
minv (10400, 10400) -- statue Augurer cage
-- healers for each class
minv (10334, 10325) -- healer spectre cage --> Chamber of Trials for Warriors Room
minv (10335, 10326) -- healer spectre cage --> Chamber of Trials for Druids Room
minv (10336, 10327) -- healer spectre cage --> Chamber of Trials for Vampires Room
minv (10337, 10328) -- healer spectre cage --> Chamber of Trials for Thieves Room
minv (10338, 10329) -- healer spectre cage --> Chamber of Trials for Mages Room
minv (10339, 10330) -- healer spectre cage --> Chamber of Trials for Clerics Room
minv (10333, 10305) -- healer spectre cage --> Chamber of Trials for Rangers
minv (10401, 10401) -- healer spectre cage --> Chamber of Trials for Augurers Room
-- standard cage mob equipment
local west_equip = { neck1 = 10306, -- collar metal academy
hands = 10319 } -- gloves kid academy
local north_equip = { waist = 10302, -- belt leather academy
legs = 10303 } -- leggings mail academy
local south_equip = { head = 10304, -- helmet iron academy
about = 10305 } -- cape brocade academy
local east_equip = { wrist1 = 10300, -- bracelet charm academy
feet = 10301 } -- combat boots academy
-- Clerics cage mobs (2 per room)
minv (10326, 10331, 2, 2, west_equip) -- minotaur cage (west)
minv (10305, 10332, 2, 2, north_equip) -- naga cage (north)
minv (10312, 10333, 2, 2, south_equip) -- gnoll cage (south)
minv (10319, 10334, 2, 2, east_equip) -- kobold cage (east)
-- Mages cage mobs (2 per room)
minv (10327, 10337, 2, 2, west_equip) -- minotaur cage (west)
minv (10306, 10335, 2, 2, north_equip) -- naga cage (north)
minv (10313, 10336, 2, 2, south_equip) -- gnoll cage (south)
minv (10320, 10338, 2, 2, east_equip) -- kobold cage (east)
-- Warriors cage mobs (2 per room)
minv (10328, 10341, 2, 2, west_equip) -- minotaur cage (west)
minv (10307, 10339, 2, 2, north_equip) -- naga cage (north)
minv (10314, 10340, 2, 2, south_equip) -- gnoll cage (south)
minv (10321, 10342, 2, 2, east_equip) -- kobold cage (east)
-- Druids cage mobs (2 per room)
minv (10329, 10345, 2, 2, west_equip) -- minotaur cage (west)
minv (10308, 10343, 2, 2, north_equip) -- naga cage (north)
minv (10315, 10344, 2, 2, south_equip) -- gnoll cage (south)
minv (10322, 10346, 2, 2, east_equip) -- kobold cage (east)
-- Vampires cage mobs (2 per room)
minv (10330, 10349, 2, 2, west_equip) -- minotaur cage (west)
minv (10309, 10347, 2, 2, north_equip) -- naga cage (north)
minv (10316, 10348, 2, 2, south_equip) -- gnoll cage (south)
minv (10323, 10350, 2, 2, east_equip) -- kobold cage (east)
-- Thieves cage mobs (2 per room)
minv (10331, 10353, 2, 2, west_equip) -- minotaur cage (west)
minv (10310, 10351, 2, 2, north_equip) -- naga cage (north)
minv (10317, 10352, 2, 2, south_equip) -- gnoll cage (south)
minv (10324, 10354, 2, 2, east_equip) -- kobold cage (east)
-- Rangers cage mobs (2 per room)
minv (10332, 10390, 2, 2, west_equip) -- minotaur cage (west)
minv (10311, 10389, 2, 2, north_equip) -- naga cage (north)
minv (10318, 10387, 2, 2, south_equip) -- gnoll cage (south)
minv (10325, 10388, 2, 2, east_equip) -- kobold cage (east)
-- Augurers cage mobs (2 per room)
minv (10405, 10405, 2, 2, west_equip) -- minotaur cage (west)
minv (10402, 10402, 2, 2, north_equip) -- naga cage (north)
minv (10404, 10404, 2, 2, south_equip) -- gnoll cage (south)
minv (10403, 10403, 2, 2, east_equip) -- kobold cage (east)
-- Arena mobs - we invoke 1 or 2 at a time, up to a maximum of 4 alive
multiple_mobs (10301, { 10365, 10367, 10368, 10375 }, 1, 4) -- slug arena
multiple_mobs (10303, { 10363, 10370, 10377, 10381 }, 1, 4) -- crawler arena
multiple_mobs (10300, { 10365, 10373, 10374, 10379 }, 1, 4) -- wolf arena
multiple_mobs (10302, { 10370, 10372 }, 2, 4) -- naga arena
multiple_mobs (10396, { 10395, 10396 }, 2, 4) -- naga spirit arena
minv (10397, 10397, 1, 1, { wield = 10318 } ) -- queen naga asp --> wielding 'snakebite'
-- Lower tunnels
minv (10415, 10407) -- rat grey arena --> A dark tunnel below the Battlegrounds
minv (10409, 10408) -- ant fire arena
minv (10418, 10409) -- mole arena
minv (10417, 10411) -- rat grey arena
minv (10411, 10412) -- centipede arena
minv (10406, 10413) -- fire ant arena --> A hollow cavern deep underground
minv (10416, 10414) -- rat grey arena
minv (10412, 10415) -- centipede arena
minv (10407, 10418) -- ant fire arena
minv (10413, 10421) -- centipede arena
minv (10420, 10422) -- mole arena
minv (10410, 10423) -- centipede arena
minv (10408, 10424) -- ant fire arena
minv (10414, 10425) -- rat grey arena
minv (10419, 10426) -- mole arena
minv (10421, 10427) -- mole arena
-- New player advancers
minv (10497, 10499) -- hvak1 advancer --> Chamber of the Watch Room
minv (10498, 10499) -- hvak2 advancer
end -- reset_new_academy
The first thing I noticed was that resets were adding fountains all over the place, so a small helper function let me spawn multiple fountains in a single function call.
Then we close various doors.
After that the friendly mobs are spawned. The shopkeeper has clearly labelled inventory.
Another helper function "minv" was written which puts a mob in a room, spawning x at a time, up to a maximum of y mobs in the area. (eg. add 2 naga at once, to a total of 4).
If the mob has equipped items, or inventory, these can be specified as part of the minv function. You can also do bags with things in them, including other bags.
The "cage mob" equipment was repeatedly being specified in the original resets, so I made a table of equipment, and used it for each different class of cage mob. This lets you modify the cage equipment much more easily, if you want to.
Moving down to the arena, I noticed that the same mob was being spawned in multiple places, so I made a "multiple_mobs" function, that loops around, placing the mobs in the desired places.
You can see from the code above that the resets are much more readable than before. So far I haven't addressed the other ideas (like random mobs, or random equipment) but that would be easily added in. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|