First, a little background... In my youth, my father got a job (he is a photographer) for a company called Infocom. He had to take pictures of the boxes in various things, like dunes and stuff. When he was done he gave me all of the boxesz he used. There were about 12 or so different games that actually had disks in the boxes. I was instantly hooked. I spent hours playing them and actually finished a few of them.

The other day I came across the source code to Zork and had to take a look. The source code I found was ported to C. The code was an absolute mess. I suppose that because of memory constraints they had to write the code in that fashion (I have never seen so many goto statements in my life.) I was disappointed to not see how those games worked their magic.

I have a personal project that I am working on and was wondering if someone could give me a little direction. I specifically wondered how the inventory system worked in a mud like QuickMUD. I am referring to the data structure itself, and how to allow for certain characteristics some objects might have.... for instance a chest that you could put other objects in, or a certain attribute like glowing, humming, and what not. Perhaps someone could point me to the files that have the source or someone could explain it in a simple way. I have thought about it but have not come up with something that is simple enough. Also I was wondering what the most widely used method of coding rooms was. I am interested in how others have done this. The simplest way to me it seems would be a 2d array . Of course I would prefer something that could change dynamically during run-time. There are many things that I haven't thought about yet, but I would rather not re-invent the wheel, so to speak.

Any help would be greatly appreciated.

HijacT

P.S. Has anyone seen Enchanter or Planetfall (from Infocom) ??? It has been over 2 decades and I seem to have lost the disks

Not to start a war or anything, but what's wrong with goto statements?

(In any case, remember that you aren't reading the native source. If you found what I think you did, you're reading a C translation of the FORTRAN translation of the original MDL code. Consider for a moment that MDL sports LISP as an ancestor, and ponder the backflips that must have been performed to get all the way to C.)

Not to start a war or anything, but what's wrong with goto statements?

IMO, there is little reason to use it in modern programming languages today. In my experience, most people that use it do so in such a way that they horribly mangle their code, which can make it very difficult to try and support or modify their work. OTOH, we frequently use "goto" in high level languages without realizing it through flow control statements (break, switch, etc...), and of course, in the underlying machine code.

At any rate, it's an age old battle in structured programming, starting with a paper written by Edsger Dijkstra:

He states that the goto statement "is too much an invitation to make a mess of one's program". However, much of what he wrote was more of a caution against using goto in place of some of the statements we take for granted today (if, loops, etc...).

There have been many followup discussions as to whether or not you can use goto statements and still maintain structured programming practices. Donald Knuth has a (unsurprisingly) lengthy paper on this subject:

Not to start a war or anything, but what's wrong with goto statements?

IMO... Edsger Dijkstra...Donald Knuth

Yes, yes... I know. Hence the "Not to start a war or anything..."

Though as you can imagine, I'm pro-goto (but not pro-foolishness; it's easy to get stupid with gotos, and most of the time they are used poorly). If the machine code can do it, I should be able to do it -- don't make me whip out my assembler!

For what it's worth, some of our test harness code (in C++) at my workplace has a couple of gotos in it. Several of us have looked at the functions that contain this and considered re-writing it so that they don't have these gotos any more.

All of us, independently, have come to the conclusion that any rewrite of these particular pieces of functionality to be without goto statements would be less easy to understand, and we've left them alone.

The moral: use the most appropriate tool for the job (although, while the most appropriate tool might be a goto, it's highly unlikely).

I don't feel strongly enough about it to engage in battle. The only steadfast opinion I do have is that it should be one of those concepts that gets taught last.

Kaz wrote:

All of us, independently, have come to the conclusion that any rewrite of these particular pieces of functionality to be without goto statements would be less easy to understand, and we've left them alone.

I've run into this before as well... typically I end up creating some sort of strange loop/break construct that emulates "goto" without actually using the keyword. The result is readable, but I typically have to leave myself a comment so I don't try to "fix" it later. It's a rare occurrence, but not completely imaginary.

Schmendrick wrote:

If the machine code can do it, I should be able to do it -- don't make me whip out my assembler!

I'm not an assembly coder, but it's probably not possible to write a functional assembly program without jumps. Which, of course, was your point. :)

Most game engines are far from the thing of beauty the end result might appear. Though some of the underlying structures and algorithms might be elegant, the entirety tends to be messy. I wouldn't place just Zork in this category (just 99% of the software industry).

As far as inventory systems, most Diku-derived MUDs use a linked list for inventory. Worn items are marked with a flag for their worn location within this inventory list (which is iterated through on a call to 'inventory'). If you wish to see for yourself, there are a million examples on other sites... though I'm not personally familiar with QuickMUD and what limitations might exist for its source code (closed, limited, open). The linked list works well because it gives resizeability and the structure/class chosen for each item allows the characteristics to be set.

I agree. A 2D array is probably acceptable only in the case that darn near EVERY space on the grid (of EVERY map) is occupied by a room. Because in a 2D array, you're allocating space in memory for XxY rooms, so every "empty" grid is wasted space.

Otherwise, use a system of links and indices. F'rexample, a small array (over, say, the enumerated type of {north,south,east,west,up,down} or whatever) filled with the indices of other rooms would be a part of every room's data type.

Room 43
north: 53
south: 33
east: 44
west: 42
up: 0
down: 0

Arrays also potentially pose an extra step for builders who want to add/remove things from their maps. Want to make that hallway one room longer or shorter? In an array system, you'd have to shift the rest of the map to fit (or add a dummy room, like a vestibule or something). In an indexed system, it's just a matter of making the room and reassigning its neighbors' links.

I agree. A 2D array is probably acceptable only in the case that darn near EVERY space on the grid (of EVERY map) is occupied by a room. Because in a 2D array, you're allocating space in memory for XxY rooms, so every "empty" grid is wasted space.

I don't think he meant the room structure to be based on a 2D array, but rather the inventory system. I'm not quite sure how he meant to do this with 2 dimensions, but my first idea to do so is one dimension handles each object and the second handles all the characteristics. This is rather wasteful and difficult to use, but not impossible.

As far as rooms based in arrays, I don't see a problem (though the single dimensional array where all rooms are indexed works more abstractly than the 2D array based on room ocation). I've seen some very efficient and effective implementations of this method as well (particularly in very-busy worlds) though it works terribly for nearly empty worlds/areas.

Hey thanks for the replies. I see what you mean about using a linked list for inventory. I found a structure in merc.h which sort of answered my question -- having another separate linked list within the object... I was thinking of it in a completely different way and failed to think of the obvious.

Another thing, I wasn't thinking of using a 2d array for rooms. There would be a lot of empty space. What I am wondering is how to do doors... for instance opening the east door in room 66 would open the west door in room 67. I would want to treat the door as one object instead of 2 instances which are equal in every way (material, locked, open, closed etc.)

If you really want to do that, have door objects that are independent of the rooms and are stored in a global list somewhere. Associate a pointer to a door object with the room exits. When someone opens a door, change the status of the associated object to "open". If you do this, you will probably need to attach a list (or anyway pair) of rooms-it-opens-onto to each door, so that you can issue the appropriate open/close messages.

The alternative that I have seen is to have door info attached the the exit, and have code that automatically finds the associated door in the other room (that is, the exit in another room that represents the other side of the same door), opens/closes it, and issues the messages.

I think the first method is probably not worth the extra complexity of wrangling the global list of door objects. The find-and-set-other-side-of-door code just isn't that much.

Make the exits an object - each room has n exit objects that each connect to an arbitrary number of rooms (perhaps connect a room to itself, or 3 rooms, no need to limit it to the obvious case of one room to another). When you open the exit, it is opened from every perspective (since other rooms are sharing that exit object).