19 Jun, 2014, jakesmokes wrote in the 1st comment:
While working on my object design, a thought occurred to me about doors. If a door (or a window, or other portal) is to be treated like an object, then it would, I am thinking, need to exist in two locations at once. Which, I suppose, is possible given that an object can, in theory, be in two inventory lists at once. Has anyone run into any issues dealing with this type of thing? I think the case that I am thinking about (serious edge case) would be the one where a player tries to dismantle a door by removing the hinges. So you would need a way to parameterize the containment such that the hinges were only accessible on one side of the door.
It seems like, for this type of situation, one would need to make parts of the object that are one only one side be objects as well and then contained in only one of the two locations that the parent is located in. Probably not a high priority problem, but an interesting one. If a door closes and locks behind you.. it could be useful.
But, in general, is that how people handle doors? Two locations at once? So, if the door is opened then the exits for two locations need to be changed to deal with that..
Why not use two different objects that point to one another…? Essentially makes all of the fringe cases trivially easy to implement for.
Edit: to answer your question, in my game, each 'door' points to an instance of EXIT_DATA; each exit data contains in a union a to_room and a from_room integer designation. This is the way that Dikurivatives handle it.
Some LPMUD mudlibs handles a door as a single object, not stored in either room. The room code has a pre-exit function, which is called after the user attempts to move, but before they actually leave the room they're in. The pre-exit code usually checks to see if the exit has a door, if the door is open, locked, etc… and if the door needs to be opened, it does a call_out() into the target room to inform them of the door opening. Then the actual movement happens.
Generally, the door code has some properties for each side that it's linked to, so you can have a door that looks clean and well polished on one side, but rough and unkempt on the other.
And you also have the case of a (dummy) door that doesn't (yet) go anywhere - to block off something that hasn't been constructed yet but that the players will use as your MUD expands. As it doesn't go anywhere - you'd better make sure THAT door can't be opened! (I remember the classic FPS DOOM and its hack where you could get behind walls that only had a texture on the other side and then take a short cut through the void around the edge of the world…)
Dikuderivatives also allow opposite sides of a door to respond to different words which can be a hassle for newbies who only learn one of the names - and come upon the shut door from the other side. :evil:
The way I've done it amounts to two objects (one in each room), mind you that they're Exit objects in a list of Exit(s) and that they're references and are likely to be technically pointing at the same object (the actual Exit/Door object) given how Java and it's references work.
It does create some problems, though, enough that I probably ought to reconsider that particular approach. In particular when I "load" the exits for rooms into their respective lists of exits I have to be sure to grab both rooms and add that exit (the Door) to their respective lists for any Door(s), which is an exit subclass/type. Not to mention that because it's the same exit if I didn't make accommodations it would have the same name on both sides instead of some kind of enter/leave style. It's important here to know that I've followed (largely) the MU* convention of named exits where you have to type it's name to use it (as opposed to n/s/e/w directionals). I also have weird name notation to include the exit name for both ends and have to include the name as an "alias" and some other stuff in order for the exit handler to be able to figure out the door I'm referring to from just the part that's supposed to be the exit name on that side (given that the object's name includes both exit names and some separator characters). It works okay, but it's kinda of icky from the code end. I also have to be sure that there is only exit in the mapping for ids (I use that so everything has it's own unique "database" id) so that I don't duplicate the exit when I save all the objects.
To be fair, the way my code works is a little funky. Each room has a couple list of references to objects that are 'in' it (separated by class), except players (who are 'in' a room by virtue of their location field containing the room's "database" id), but including exits. I think that it might be a objectively better approach to apply the same notion about the players to most, if not all objects. It's probably less memory intensive too, but maybe more cpu intensive in theory, given that each time you want to look at the objects in a room, you have to actually figure out which ones those are.
** the code does allow for one way exits and you could have one exit in/for each room (one from R1->R2 and one from R2->R1), but there's no state data or anything so that can't easily or adequately represent a real door which might be locked or broken or made of differing materials (if one implemented materials and whatnot. Also, an Exit could ostensibly be anything from a hole in the floor to a cave entrance to just a virtual barrier representing movement across an open area.