06 Jun, 2009, Chris Bailey wrote in the 21st comment:
Votes: 0
Well, I haven't made any kind of Wilderness system in C or C++ but I can give a run down of a system I've done before

Wilderness "areas" were saved in an external text file that stores a large 2d array representing the area. Each element of the array had a sector object and contained little information other than it's map symbol, height of that x,y coordinate.
Each player, item, monster etc all inherited from the same base object that had a location. The location was a particular "map" file and x,y coordinates. There was no need for an actual Z coordinate since the height of the object was the height of the sector, unless something modified it elsewhere, and then it would just increase the objects "height". I didn't keep implicit lists of where players or item's were. If a player wanted to pick something up, it would pull out all of the item's whose current map == the player's map, and whose coordinates matched the player's coordinates. Calculating distance between player's and item's was just as easy, a simple if player.is_in_range(object,10,line), item.is_in_range(player,4,cone). But that system didn't have any kind of non wilderness to speak of either. The entire world consisted of these maps and everything was to the same scale, across the entire world. Now all your brainers out there will probably tell me why that was such a horrible way of handling it :P
06 Jun, 2009, David Haley wrote in the 22nd comment:
Votes: 0
It should be fairly easy to give rooms expiration counters, right? Instead of wiping the room as soon as players leave (or it's empty), give empty rooms a 10 minute timer, and give rooms with "breadcrumbs" a 2-hour timer (or whatever), and after that delete the object as well (chalking it up to scavengers or something).
06 Jun, 2009, KaVir wrote in the 23rd comment:
Votes: 0
David Haley said:
It should be fairly easy to give rooms expiration counters, right? Instead of wiping the room as soon as players leave (or it's empty), give empty rooms a 10 minute timer, and give rooms with "breadcrumbs" a 2-hour timer (or whatever), and after that delete the object as well (chalking it up to scavengers or something).

You'll typically find that players move around quite fast - particularly in the sort of wilderness system where the objective is usually to travel from "point of interest A" to "point of interest B". Each player could potentially pass through hundreds, or even thousands, of rooms per hour (and while they're unlikely to leave a trail of breadcrumbs behind them, you may find the rooms become cluttered over time - particularly if corpses take a long time to decompose).

Empty rooms can be wiped instantly (although this only need occur if the player quits, leaves the wilderness, or enters a location already occupied by another creature - otherwise the same room is just reused each time you move). The problem is only with rooms that contain persistant objects.
06 Jun, 2009, Skol wrote in the 24th comment:
Votes: 0
KaVir, that was one issue I wasn't sure of with the created/freed rooms. People drop crap all over.

Another question is populating the wilderness, if the guy leaves the area and goes back to find that goblin he left all beat up etc.. Or do we do more 'random encounters' type, and if so does it check the players level or the wilderness'? imagine say a level 54 char running a level 3 around and blam, out pops a level 56 ogre, splat goes the lowbie heh. (Yeah, RoM's SOOO level based).

KaVir, how did you handle 'planes' between rooms? Aka like doors/walls/etc. In the above example it was just a symbol that it would hit showing it doesn't exit say east | being a barrier. But 'tween' the north/south exits would have to be it's own line as well.
06 Jun, 2009, KaVir wrote in the 25th comment:
Votes: 0
Skol said:
KaVir, that was one issue I wasn't sure of with the created/freed rooms. People drop crap all over.

The question is, how much of that crap do you want to keep? Back when I created my wilderness I was drawing heavy inspiration from the Mud-Dev discussions about persistant worlds. I decided I wanted items to stay forever unless explicitly destroyed - but after a few months of play, movement consisted of wading through rooms full of bones and rusty old weapons.

What I'd suggest is to set some sort of destruction datestamp based on the item type. Allow players to explicitly hide items if they want to (eg burying treasure to pick up later) and perhaps have certain items which never vanish, but for other items just assume they're eaten by wild animals, taken by bandits, or are otherwise lost over time.

Skol said:
Another question is populating the wilderness, if the guy leaves the area and goes back to find that goblin he left all beat up etc.. Or do we do more 'random encounters' type, and if so does it check the players level or the wilderness'? imagine say a level 54 char running a level 3 around and blam, out pops a level 56 ogre, splat goes the lowbie heh. (Yeah, RoM's SOOO level based).

That's one problem with level-specific spawns. Another is that players have no incentive to explore - they can just wander around the same part of the wilderness, day after day, knowing that they'll always get good exp. Thus I'd definitely recommend allocating different mobs to different parts of the wilderness.

Skol said:
KaVir, how did you handle 'planes' between rooms? Aka like doors/walls/etc. In the above example it was just a symbol that it would hit showing it doesn't exit say east | being a barrier. But 'tween' the north/south exits would have to be it's own line as well.

The data for each room was stored in a 32bit integer, and only 7 of those bits were needed for room type. The remaining bits were used for other things, including walls and doors for three directions (north, east and up). If I recall correctly it was 2 bits for each door (none, open, closed, locked) and 2 more for each wall (none, wood, stone or metal).
07 Jun, 2009, quixadhal wrote in the 26th comment:
Votes: 0
The other extreme would be….

Quote
> drop sword
You drop a rusty longsword on the ground.
You sense movement in the underbrush nearby.
> get sword
You take a rusty longsword.
> drop sword
You drop a rusty longsword on the ground.
You sense movement in the underbrush nearby.
> look
You are standing in a grassy field, littered with small bushes and the occasional tree.
There are mountains comfortably far off to the north, and the dark smudge of a forest
to the east. The grasslands continue to the south and west, as far as you can see.
> wait
You wait around a few moments, wondering what will happen!
> n
As you head north, you see a small flash of movement and suspect that anything you
might have left behind is now the proud possession of some small creature that makes
its home here.


I would find that should give your players enough warning to know that leaving breadcrumb trails isn't an option, and eliminate the need to worry about transitory changes. If you wanted to spawn real objects as part of the room design, that would be a case for a hand-crafted room that would override the auto-generated one.
07 Jun, 2009, Runter wrote in the 27th comment:
Votes: 0
KaVir said:
quixadhal said:
Personally, I think a better idea is to generate a virtual room for every player (or NPC) that is in the wilderness. If someone moves and their coordinates will then match an already existing room, move them into that room instead of generating a new one. If no players/npcs are left in such a room, recycle it or destroy it.

That's the approach I used for my old mud, and it worked well. The only problem I found was dealing with objects left in the rooms - you'll probably want to cache them somehow, so that you can deal with players dropping loads of objects all over the place (eg leaving a trail of breadcrumbs) and also with players moving back and forth (i.e., you don't want to repeatedly load and unload a pile of objects every few seconds as a player runs back and forth between two rooms).


Yeah, very good idea actually.
07 Jun, 2009, Runter wrote in the 28th comment:
Votes: 0
As far as the dropping 'bread-crumbs' goes–I think setting up an event to destroy the obj (corpse, etc) at some later time is easy.
Most people use some type of event system now I think, and they're readily available in the repositories.
This would easily solve the problem with nondiscrimination between objects– persistent and otherwise– Since only objects created by specific means would be targeted.
07 Jun, 2009, David Haley wrote in the 29th comment:
Votes: 0
I'm still not sure why timeouts aren't appropriate. Sure, people move fast. So make the timeout small enough to do whatever it is you need to do with rooms with objects in them. I'm not sure I'm seeing what the big problem is here.
07 Jun, 2009, KaVir wrote in the 30th comment:
Votes: 0
Runter said:
As far as the dropping 'bread-crumbs' goes–I think setting up an event to destroy the obj (corpse, etc) at some later time is easy.

You could do that, yes - have the event system reload the room and its contents into memory (if it's not already there) and destroy whichever item/s have expired. However the suitability would depend on your implementation. For example, if corpses and body parts take a week to decompose, and players kill an average of 500 mobs per day, with 150 active players (not necessarily online at the same time, but who play each day) you'd have over half a million pending events before the first corpse decomposed.

My approach was to save an expiry datestamp on each object, and whenever the room was loaded check to see which items had expired, and destroy them on the spot (without notification to the player entering the room). If disk space had become a problem, I could have set up a shell script to go through and purge expired items.

The problem I had was with items that didn't expire - corpses becoming skeletons, severed limbs becoming bones, etc, and an event system wouldn't have changed that. What I should really have done was given even bones an expiry (or at the very least, compressed them into a single 'pile of bones' object). But that was my first mud, and I tried out a lot of concepts without really thinking through the consequences.

David Haley said:
I'm still not sure why timeouts aren't appropriate. Sure, people move fast. So make the timeout small enough to do whatever it is you need to do with rooms with objects in them. I'm not sure I'm seeing what the big problem is here.

It's not a "big problem", but if the timeout is large enough to be of any use it could result in a very large number of rooms being created, most of which won't be visited again before the timer expires. Rather than basing the expiration on time, I'd prefer having a fixed maxium number of virtual rooms, and clear out the oldest (least recent to have been visited) once I'd run out of empty rooms.
07 Jun, 2009, Runter wrote in the 31st comment:
Votes: 0
KaVir said:
You could do that, yes - have the event system reload the room and its contents into memory (if it's not already there) and destroy whichever item/s have expired. However the suitability would depend on your implementation. For example, if corpses and body parts take a week to decompose, and players kill an average of 500 mobs per day, with 150 active players (not necessarily online at the same time, but who play each day) you'd have over half a million pending events before the first corpse decomposed.

My approach was to save an expiry datestamp on each object, and whenever the room was loaded check to see which items had expired, and destroy them on the spot (without notification to the player entering the room). If disk space had become a problem, I could have set up a shell script to go through and purge expired items.


Fair enough. I've never really considered keeping objects in rooms for that long before a decay. I actually only keep objects in normal rooms for a few minutes before a decay process begins. For some people they would want it some time longer. I suppose it all depends on the implementation. In any case, it still would be less memory in use even with a minor majority of your total wilderness populated with items. And far less than if someone build a wilderness within the constructs of most stock codebases.
07 Jun, 2009, KaVir wrote in the 32nd comment:
Votes: 0
Runter said:
Fair enough. I've never really considered keeping objects in rooms for that long before a decay. I actually only keep objects in normal rooms for a few minutes before a decay process begins. For some people they would want it some time longer. I suppose it all depends on the implementation.

Well as I said, it was inspired by Mud-Dev discussions of persistant worlds - the idea being that you might (for example) accidentally recover a tarnished old gold ring while fishing…a ring which another player had lost while swimming across that same river several months earlier. There's a certain coolness factor in sticking your enemy's severed head on a pike deep in the forest, then coming back weeks later to discover it's still there - except that it's now a skull stuck on a rusty pike.

Runter said:
In any case, it still would be less memory in use even with a minor majority of your total wilderness populated with items. And far less than if someone build a wilderness within the constructs of most stock codebases.

Well if you're keeping all the rooms in memory (ouch), then the objects within them would already decompose with the stock functionality. In my case, the wilderness had over a billion rooms, so it was never going to be practical to work within the confines of the stock world system - I couldn't keep all rooms in memory, and therefore I couldn't keep the contents of all rooms in memory. RAM was pretty tight, so even your event system would have been an overhead I couldn't have afforded.
07 Jun, 2009, Runter wrote in the 33rd comment:
Votes: 0
I am curious as to which language your current project is using, KaVir?
07 Jun, 2009, David Haley wrote in the 34th comment:
Votes: 0
KaVir said:
but if the timeout is large enough to be of any use it could result in a very large number of rooms being created, most of which won't be visited again before the timer expires.

Isn't this somewhat self-contradictory? (The second part seems to suggest that the timeout is too large.) It sounds like you attribute very small probabilities to players going back to where they were before, so a small timer should be sufficient. It sounds like you have an implicit object destruction timer anyhow (your silent expiry). Is your expiry timer long enough that leaving things in memory is prohibitive?

A fixed-size MRU queue approach seems reasonable too, although it seems like the fixed size might have to scale with the number of players.
07 Jun, 2009, KaVir wrote in the 35th comment:
Votes: 0
Runter said:
I am curious as to which language your current project is using, KaVir?

Primarily C++, but that's not the mud I'm talking about in this thread. The approach I'm discussing here is something I implemented 12 years ago on a Diku/Merc MUD (in C).

David Haley said:
Isn't this somewhat self-contradictory? (The second part seems to suggest that the timeout is too large.) It sounds like you attribute very small probabilities to players going back to where they were before, so a small timer should be sufficient.

Your original proposal (in post #22) was that the timeouts would also destroy the contents of the room. What I'm saying is that making the timeout long enough to give objects any decent amount of persistance could result in a very large number of rooms being created.

David Haley said:
It sounds like you have an implicit object destruction timer anyhow (your silent expiry). Is your expiry timer long enough that leaving things in memory is prohibitive?

As I mentioned previously, many objects never expired (although corpses would rot, there would still be a skeleton left behind).

David Haley said:
A fixed-size MRU queue approach seems reasonable too, although it seems like the fixed size might have to scale with the number of players.

I found an LRU caching algorithm to be far better suited, as players are much more likely to return to recently visited rooms than long-ago visited rooms.
07 Jun, 2009, David Haley wrote in the 36th comment:
Votes: 0
KaVir said:
David Haley said:
It sounds like you have an implicit object destruction timer anyhow (your silent expiry). Is your expiry timer long enough that leaving things in memory is prohibitive?

As I mentioned previously, many objects never expired (although corpses would rot, there would still be a skeleton left behind).

I guess I'm still not seeing the big deal here, but ok.

KaVir said:
David Haley said:
A fixed-size MRU queue approach seems reasonable too, although it seems like the fixed size might have to scale with the number of players.

I found an LRU caching algorithm to be far better suited, as players are much more likely to return to recently visited rooms than long-ago visited rooms.

I was agreeing with you, you know… we just said the exact same thing. :rolleyes:
07 Jun, 2009, KaVir wrote in the 37th comment:
Votes: 0
David Haley said:
I guess I'm still not seeing the big deal here, but ok.

The problem is really just that if players are consistently producing objects (such as corpses) faster than those objects are being destroyed, the number of objects in the game will steadily increase over time - so you need some way to keep the number in check.

Depending on your implementation and available resources you could certainly keep everything in RAM, but for most people RAM is a more precious resource than HD space, so if the number gets excessively high it makes sense to use some sort of caching.

David Haley said:
KaVir said:
David Haley said:
A fixed-size MRU queue approach seems reasonable too, although it seems like the fixed size might have to scale with the number of players.

I found an LRU caching algorithm to be far better suited, as players are much more likely to return to recently visited rooms than long-ago visited rooms.

I was agreeing with you, you know… we just said the exact same thing. :rolleyes:

You proposed using a Most Recently Used (MRU) caching algorithm (discards the most recently used item first), while I mentioned that I found a Least Recently Used (LRU) caching algorithm (discards the least recently used item first) to be better suited.
07 Jun, 2009, David Haley wrote in the 38th comment:
Votes: 0
KaVir said:
You proposed using a Most Recently Used (MRU) caching algorithm (discards the most recently used item first)

I said queue, actually, which kindasorta makes a big difference. The most recently used things go in front of the queue, and therefore reshuffle the FIFO order – in this way, when popping things off of the end, the least recently used things get popped first. Seriously… give me at least a little credit, especially if I insist that I wasn't disagreeing. I'm not entirely stupid. :rolleyes:
07 Jun, 2009, Scandum wrote in the 39th comment:
Votes: 0
Runter said:
I'm not sure if (most?) mud clients are compliant with that. Do you know, David?

You can use \e
You can use \e [ [i]n[/i] ; [i]m[/i] r to set the scrolling region between top row n and bottom row m. For example \e[10;23r.

A couple of mud clients support vt100 drawing, but as far as I know zmud, soterm, and tintin++ are the only ones with vt100 scrollback support.
08 Jun, 2009, KaVir wrote in the 40th comment:
Votes: 0
David Haley said:
I said queue, actually, which kindasorta makes a big difference. The most recently used things go in front of the queue, and therefore reshuffle the FIFO order – in this way, when popping things off of the end, the least recently used things get popped first.

Apologies then - I've only heard of the MRU and LRU acronyms used for algorithms for discarding items, and thought you were proposing the opposite of what I'd implemented. I didn't want to ignore your comment though, in case there was some reason behind it that I hadn't considered.
20.0/181