Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD Beta Forum Goto page 1, 2  Next
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Sep 02, 2008 7:48 pm   

How to best support multiple map windows
 
In zMUD, when you open multiple map windows, each window has it's own copy of the map database. For large map databases, this results in *huge* resource usage. I want to find a more efficient way to handle this in CMUD. I had thought that I could postpone this until Phase 2 of the new mapper, but I'm starting to think that doing this correctly will have a big impact on the fundamental design of the mapper, which is really what I'm working on in Phase 1. So I want to give this more thought.

What CMUD needs to do is make the map database and map "viewer" separate. And in the middle of this, I can introduce a new object called the "MapLocation". Each Session Window (a window with a network connection) has it's own MapLocation object. This object points to the actual map database (in memory). If two session windows share the same map database, then only a single copy of this database is loaded into memory. Each window has it's own MapLocation which each point to the same database in memory.

The map "viewer" window would point to the map database that it is rendering, along with a list of all MapLocation objects associated with that database. This single viewer window could display these multiple MapLocation objects as different icons with different colors, instead of just using the normal "blue dot" that we have in the current mapper.

The "viewport" (zone, x/y origin, zoom level, etc) information can be stored in the MapLocation object. When you select a session window, the map "viewer" would switch to show the viewport of the MapLocation in the selected session. So clicking between two different session windows on the same MUD would cause the map viewer to jump back and forth between the two character locations. Perhaps a pulldown menu in the mapper would also let you jump between multiple MapLocation objects within the mapper itself rather than needing to click on session windows.

In summary, the map viewer window would point to a *list* of multiple MapLocation objects. Each MapLocation object is associated with a single session window.

If you have multiple session windows connected to *different* MUDs, then you'd have multiple "viewer" windows, just like you have in zMUD. Each map viewer would be displaying a different map database for a different MUD. Each map database would be loaded into memory, just like with zMUD. So for multiple MUD playing, CMUD would work the same as zMUD. But for playing multiple characters on the *same* MUD, there would be huge memory savings and you'd only need a single map window instead of taking up screen space with multiple maps. The single map window would be able to show the locations of multiple characters.

In fact, I can imagine some sort of communication between multiple CMUD clients that might allow you to show the location of other friends (guild-mates) on the same MUD within your own map window. This could be very useful for groups who all use the same CMUD client to share their map location information. That would be a future feature (probably phase 3), but this architecture would support such a system.

The new Room Properties dialog would show a particular MapLocation object. It shows the current room name, description, and exits. A remaining question is whether we just want there to be a *single* Room Properties dialog (works like the "viewer" and shows the MapLocation object of the current session window. Clicking in a different session window changes the display of the single Room Properties), or whether there would be a Room properties dialog for *each* session window that always just shows the location of the character in that session and doesn't change if you click on a different session window.

Maybe there is a way to support both methods. The key is that the map "viewer" doesn't need to be open to display the Room Properties. The Room Properties just display the MapLocation object information.

The scripting within the session window also just uses the MapLocation object. Thus, the %roomXXX functions all work regardless of whether any "viewer" or "properties" window is open. The MapLocation is part of the session window and loads the map database that it needs on-demand.

So, except for deciding if there are multiple Room Property windows, or just one, I think this is a better and more modular architecture for the mapper that will better support multiple maps, and especially multiple characters on the same shared map.

Opinions and suggestions are welcome.
Reply with quote
Arminas
Wizard


Joined: 11 Jul 2002
Posts: 1265
Location: USA

PostPosted: Tue Sep 02, 2008 10:45 pm   
 
Apologies if you already said this and I just missed it.

I know several guilds on different MUDS that would benefit greatly from having Multiple map location objects.

For example you have some sort of remote control commands for pets or far-seeing.
So these objects wouldn't necessarily be for multiple characters and they would be all within the same session window.

An example on Avalon. A sorcerer has sent his little imp out into the world to hunt down some poor sucker.
The map displays a blue dot (or whatever) for the location of the sorcerer, and a red dot for his minion. If the sorcerer moves the blue dot follows him, and if the imp moves the red dot moves tracking it as well.
Now the sorcerer also has a bug-eyed demon that is tracking the movement of his prey so he has yet another dot, perhaps yellow, that moves when his target does.

The map is centered around the blue dot, and as it moves the sorcerer may or may not be able to actually see the red or yellow markers. If the sorcerer chooses however he could type an alias to have the map center on the movement of his demon or of his prey.

Anyway, you can see I hope from my example how it would be useful to have multiple markers that are children of the session window, and not just a single child marker.
_________________
Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Sep 02, 2008 11:52 pm   
 
Ahh, ok, interesting idea. So you'd like to be able to create multiple "locations" within even a single session window, each with a different color. Yeah, I can see how that would be useful.

I'm curious though. In your specific example, how would you envision being able to update the location of your pet. Does the MUD send you some sort of text that tells you where it is. Or how would you want to control it?
Reply with quote
Arminas
Wizard


Joined: 11 Jul 2002
Posts: 1265
Location: USA

PostPosted: Wed Sep 03, 2008 12:09 am   
 
The game in the case of the sorcerer he BECOMES the imp so it would be the same as if he were moving so he would need to run the alias to make it center on the red dot for movement.

Note that his body remains where-ever he was when he became the imp so he needs to know where he is, and he can be attacked and killed by other players while his mind is elsewhere... So he needs to be able to quickly jump back into his body and know where he is.

The alias would be something like

#alias becomeImp {#createIndecator imp red roomnumber;#te imp roomnumber;#centeron imp}

Other guilds like seers would get a line of text saying that they had moved their seeing stone to the north etc. So they would need to create triggers to #move the "locationindicater1 north" for example.

In the case of tracking his victim he gets text something akin to, "Mage Ramoth moves North to Center of Hellspont Square." From the tracking demon. Again he would need to have adequate scripting to #teleport "locationindecater2 roomnumber" then to #move it or whatever.
_________________
Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram
Reply with quote
Arminas
Wizard


Joined: 11 Jul 2002
Posts: 1265
Location: USA

PostPosted: Wed Sep 03, 2008 12:47 am   
 
After thinking about this a bit more. I think there should be at least two center on commands. One that basically makes the secondary marker BECOME your marker temporarily so that mapping etc would work as if the imp were in fact the sorcerer.

And one that simply centers on one of the other markers.

So the sorcerer would use #becomeMarker imp, and the seer would #centerOnMarker stone1.

Then if the seer moves his seeing stone north via #moveMarker stone1 north; the map would not treat it as if he had actually taken a step
and the map would not automatically recenter on the room to the north. Also if the seer were to go out the map would automatically recenter on HIS location.

The sorcerer would have to use #becomeMarker Self or some equivalent to jump back into his default marker.
_________________
Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Wed Sep 03, 2008 10:37 am   
 
Multiple map windows seem like a good idea, and multiple markers within a single window is something many of us have wanted for a very long time. I definitely want to be able to create multiple MapLocation objects within a single session, and would expect that player tells and other messages would be used to coordinate locations during some game events.

For handling multiple map windows I would suggest a setting that is created in the PE. The MapWindow setting would have fields of name (must be unique just like other windows), file (holds the absolute or relative path to database file), and visible (boolean value for whether the window should be displayed), location (roomkey value for the location of the default blue dot), docking position (while docking is actually controlled by the layout this field would be used to decide where to send a speedwalk). Since most users will only use a single window I would suggest the Map button in the toolbar checks for a map window setting and when none is found it creates one and fills in the fields. If one is found it makes the window visible and brings it up. This makes the creation of multiple map windows within a session an advanced item. Because deleting the setting while the window is displayed could be a problem you should protect against that, a simple first step that should be done is to set the hidden flag on the setting when it is created.

For the locations I would again suggest a setting. These however would need to be controlled by script. Syntax wise I might suggest something like:
#LOCATION name [foreColor] [backColor] [roomKey] [mapWindow]
Creates/updates a marker location setting
#LOCATION name
Sets the named location as the currently active location, this would carry accrosed sessions. The room properties window would be updated to display the current location. Since multiple windows can actually be used it it would mean that the room properties window can not be tied directly to a single database.
#LOCATION mapWindow
Sets the location to the default blue dot that is included from the mapper window. This one is using the name of the mapper window itself in order to decide which window we are working with.
#LOCATION
Lists all location settings. The list would include each windows built in location, and should flag which is marked as the current active location.

#WITH LocationName {
The room properties window would update to display based on that location setting and subsequent grouped commands would use that location as the current location. LocationName in this case could also be a mapperWindow name and would then operate based on that map's built in blue dot.
#MOVE s
#SHOW %roomname
} // restores to the previous Location setting at this point

#TELEPORT
With no arguements this should center the map on the current location, I think it does this already.

#SHOW %pref(MapFile)
Should provide the full path for the database of whatever map window the current active location is in.


On quite a few of those I said the Room Properties window should be updated when the active location is changed. I am actually imagining a drop down box in the room properties window that lets us set whether it is coordinated to a specific location setting, the active location, or just a user selected room.


This also bring to mind another wonderful thing to have. #WALK LocationMarker. Being able to use #WALK to automatically compute a path from the current active location to another of those markers would be excellent. Having the #WALK lock on to marker and adjust its path when the marker gets moved would be amazing.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Sep 03, 2008 7:33 pm   
 
Vijilante is on the same page that I am. In fact, your suggestions are very much like what I've already been thinking about. Your #WITH idea is interesting. I was thinking more like the #CLASS command where you set the "current location" and then set it back, but I can see that the syntax of #WITH might be better. The tricky part is that the current location used for the %roomXXX functions is a global variable within the window object, so if you had multiple threads and they each changed the current location, there could be some bad interactions.

As I mentioned in the other thread on the mapper scripting, I think the mapper "window" object is the top-level window/module in the specific *package* file for the map database. Each map database has a single map package that contains the scripts for that map database. So that's a one-to-one relationship. The "map object" acts as the top level window/module object, and the room "classes" exist within that window object.

One issue I still haven't solved yet is how to associate a particular session window with a particular map package/window. You might have multiple session windows that point to a single map window (with different location markers), or you might even have a single session window that switches between multiple map windows. I'd like a lot of flexibility with this. But when you walk through a MUD in a session window, CMUD needs to know which map(s) to update, especially when in Map mode to create new rooms on the map. And when you double-click on a room on a map, CMUD needs to know which session window to send the speedwalk commands to. Because I can see this as a many-to-many relationship, it gets tricky. Do you ever send the speedwalk directions to more than one session window? When you move in a session window, should it ever create a new room on more than one map window? Seems like it could get complicated.

It sounds like you are suggesting that each "location" object points to a specific map database window. So your character session window can select one of these locations, and that ends up assigning the session window to the map associated with the selected location object. That's a possibility. When walking through the MUD in your session window, it would create a new room in the map associated with the current location object. So it would never create a room in more than one map database at any time. When double-clicking on the map window, it would send the speedwalk directions to the session windows assigned to whatever location objects are in the current room in the map. And maybe you can set the properties of a location object to see if it is "live" or "following" and only send the speedwalk directions to the "live" location objects. Then it sends the directions to any session windows assigned to that location object.

I'll need to think some more to see if this takes care of everything. It's giving me a headache ;) But I think we are getting close to something good here.
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Wed Sep 03, 2008 9:23 pm   
 
I hadn't really thought about all the many-many relations possible earlier. Now that you have described a little more about the kind of flexibility you are imagining, and we have some rough terms let's take a look at those relationships.

On ampWindows:
1. The concept I have for a mapWindow setting is that it contains the general controls for the window, and provides a scoping control like a module.
1a. Among the controls directly contained in it is the 'default' blue dot, the appearance items (currently in the .ini), the general configuration (also currently in the .ini), and some sort of shorthand definition for building the map mode triggers. All of those should be accessible by hitting a configuration button in the PE, or using the existing configure menu. The reason to include some shorthand is to help a user rebuild them by a wizard interface. This way if they muck them up they could just hit rebuild and it would spit out the original trigger set.
1b. As it also provides a global, external, local control for scripting there is a first layer of scoping to determine which windows are able to interact with it. We can set the package enabled in both direction to further determine the correct interractions in more complex settings.
1c. The inclusion of a parent window field can be used to control where it expects to send commands to. This is the same as the way in which the docking relation is now used. Considering all the headaches that have occurred with changing the docking type through the PE, I wish you would just get rid of that and rename the relative to field "parent window". While you fix this make it so we can set it back to null!
1d. If the mapWindow is available to multiple windows and has no defined parent then it has no idea where to send commands. Scripts would be executed based on the context that sourced the #MOVE, #OK, #MAKEROOM, etc; but double-clicking to speed walk would not work.
1e. A mapWindow would need to have its own idea of scope to determine which Location settings should be displayed. If the mapWindow isn't directly marked as a child of a given window setting then it would not be able to access Location settings within that window for display. It would display those that are within its scope and (when defined) its parent window's scope.
1f. I don't actually envision the mapWindow setting as requiring its own package. I see it as something that would be created in the main package for a new user, and when they were more advanced they might consider moving it to its own, or a shared package. Advanced users would already understand all the concepts for the interface as it basically combines module and window, and adds map specific items. It would operate by the same priciples as a module/window, and therefore be a nearly native addition to advanced users.

Now to Locations:
2. A 'Location' setting. These might be contained anywhere. There might be 17 purple dots running around on a map, and that might actually be what the user wants. I see these as something that might be in a window, module, or mapWindow setting. These might be disabled at any time, and the maps visual control needs to know that.
2a. A Location setting within a Window has the same self-only scoping as other settings within that window. To provide a Location on a map shared between sessions it should be placed in a global module that both the Window and mapWindow have access to. This sort of multiplaying should be considered as an advanced usage.
2b. A globally available Location might be seen by many mapWindows, this is why it needs to store a specific map it is associated with. This could either be done by the mapWindow name, or by the actual database filename. I would tend to prefer mapWindow name as that provides the ability to make specific markers appear only in some mapWindows.

Specific replies:
Quote:
Do you ever send the speedwalk directions to more than one session window?

Yes, when 2 sessions are operating from different locations. When those 2 sessions use the same mapWindow operating from different Locations, we would want each sessions to be able to use speedwalking. However, it can't be done through double-clicking without a way to lock the mapWindow display to a specific session. Perhaps a right-click speedwalk with location would be workable, but it again has the problem of which window to send it to. Context is used as part of the scoping routines, and because context is lost with this method it might not be possible to determine a window that could be called the owner for a given location. I think users making use of such multiplay would have to be willing to accept that #WALK must be used from the window.

When both sessions are joined up such that one character is following another, then no. Speedwalking would only occur with 1 of them, and having a 'parent window' field should cover this.

Quote:
When you move in a session window, should it ever create a new room on more than one map window?

Yes. All mapWindows that use the same database file should always be synchronized. If 15 sessions are using a single database and I have 15 characters all at different locations, with an automated mapping script driving each of them. I expect that the database and display will be updated cleanly whether I have just 1 mapWindow, or 27.

Quote:
The tricky part is that the current location used for the %roomXXX functions is a global variable within the window object, so if you had multiple threads and they each changed the current location, there could be some bad interactions.
Copy the global variable to the script execution stack when the script is first started. Then use a pointer to that spot in the stack until the thread ends, the script returns to the command line, etc. I think you mentioned already doing something similar with some other global variables, perhaps it was changing the special characters with %pref.

If anyone can think of a relationship that doesn't get covered by the scoping rules, the parent window field, and the caveat that there just is no way to display it (use #WALK); then please speak up.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Sep 03, 2008 10:20 pm   
 
OK, let me think about this a bit more and read your post a few more times (headache is getting worse ;) Something tells me that you are really onto something here, but I'm still missing the "ah-ha" moment that I need. There is something about treating the "location" object just like another setting type with the existing scoping rules that seems to make a lot of sense, and then the mapper just displays all locations that are within it's scope (and locations that are enabled).

The reason I thought about the mapper window being in it's own package is to keep the scripts for the map in a separate pkg file from your main session scripts. Then people can share mapper scripts separately. But I guess you are correct that there would be nothing stopping someone from putting the map window into it's own separate package if they wanted it separate. So keeping it with the main settings by default for novice users might not be a bad idea.

Quote:
Considering all the headaches that have occurred with changing the docking type through the PE...

Create a new topic in the beta forum if there are bugs/headaches with changing the relative window in the PE. It seems to work ok for me here.

Quote:
Copy the global variable to the script execution stack when the script is first started.

Well yes, that's what I was thinking of. But the current system has a global "current room" within the session window. All of the mapper commands/functions access this current room. So a thread would need to save the current value, then change the global variable to the new current room. But then some other thread that calls a %roomXXX function would be using the current room of the other thread and not the previous value.

What I'm going to need to do is get rid of the global variable and store it within the thread variables like I did with some other globals. So yes, I know how to do it, it's just going to be a pain. But I don't really see any way around it. Each thread will need to have it's own "current location" on the map for proper scripting.

Quote:
All mapWindows that use the same database file should always be synchronized.

I'm not sure this is quite right. I think each mapWindow can be currently tracking a different location object. So you might have 15 windows connected to the same database, but tracking 15 different locations. The database keeps them synchronized (if a new room is added to the database, it gets displayed on all 15 map windows), but the map location that the map window is centered on might be different. If Window A is tracking Location A (red) and Window B is tracking Location B (blue), then when Location A changes, Window A is re-centered on the new location (if auto-center is on), whereas Window B just changes where the red dot is displayed, but remains centered on the Location B blue dot.

A final complexity is the Room Properties window. Do I allow multiple room property windows like I would for the map viewer window? Everything is easier with just a single room property window. If I allow multiple windows, then I'm going to have to create some sort of RoomPropWindow object just like the MapWindow object, and that just seems like overkill and too much complexity.

But I can see people who are multiplaying who might want a separate room property window for each character to show the name/description/compass for each character. So maybe I allow multiple Room Properties windows and just allow you to assign which "location" you want it to track, or which MapWindow you want it to track. If you assign it to a specific location, then it will track that location regardless of what room you select on the map. If you assign it to a MapWindow, it will track the current location on that map window and would change if you clicked on a different room like it does now. This allows the Room properties to be used without the map window (by just tracking a specific location object).

I think you already mentioned this with your pull-down selection in the room properties. I'll just need to find a way to make it easy to change without necessarily taking up a lot of screen space. So maybe with some sort of right-click menu and then update the caption of the room properties with what location or map it is assigned to.

Then I'll just need to figure out where to store that information for each room properties window so that it gets saved/loaded with the window layout without needing to create a bunch of other new settings types.
Reply with quote
Arminas
Wizard


Joined: 11 Jul 2002
Posts: 1265
Location: USA

PostPosted: Wed Sep 03, 2008 10:36 pm   
 
I would think maybe a pull out panel on the side of the properties window that has a list of the current active location objects with the one that is being displayed highlighted.

I think that the location objects should belong to session windows with network connections. Each session starts out with a default location object that is automatically followed by the properties window.

Also If I DO happen to have multiple session windows that have a network connection open then if I click on one of them, then the default for that session is the one that the properties window displays information for.
_________________
Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Wed Sep 03, 2008 11:12 pm   
 
Windows that don't have a network connection could easily have a location object too. As Vijilante mentioned, once CMUD supports multiple location objects, I can see people using them for all sorts of stuff in scripts. So I'm not going to restrict it to just windows with network connections.

But yes, there would be a default location object that is created and used normally unless you create other locations yourself.

If you click on another window that has it's own location object, the properties window will normally switch to displaying the properties of that room as you said. Unless you lock the room properties to only track a specific location all the time, in which case it wouldn't change when you clicked on another window or map.

I'm not actually fond of pull-out panels in this case. Only the window docking system handles the "fly-out" panels and I don't want to add the complexity of the docking system to the properties panel since it's already a dockable panel for the existing dock manager. And a panel that you have to click to open (like the "nearby" panel in the mapper, for example), takes extra clicks compared to just having a right-click menu. I might also just implement a menu selection item in the status bar of the room properties, which is where I already display the "Save/Cancel" buttons when editing. I decided to use the status bar since I always need a status bar for displaying mouse-over help messages and adding stuff to it allowed me to remove any menu or toolbar from the window, which takes up valuable screen space.

So once of the items in the status bar might indicate which location you are tracking, and you just click on it to bring up a menu of all existing locations and windows. With just a simple list of items like this, you don't really need anything as fancy as a pull out panel. That's more useful for complex elements, such as the tree-view that is displayed in the nearby/zone pull-out in the existing mapper.
Reply with quote
Arminas
Wizard


Joined: 11 Jul 2002
Posts: 1265
Location: USA

PostPosted: Wed Sep 03, 2008 11:20 pm   
 
Fair enough, just trying to think of a place to put the list of existing objects. The status bar sounds better to me anyway.
_________________
Arminas, The Invisible horseman
Windows 7 Pro 32 bit
AMD 64 X2 2.51 Dual Core, 2 GB of Ram
Reply with quote
wrym
Magician


Joined: 06 Jul 2007
Posts: 349
Location: The big palace, My own lil world

PostPosted: Fri Sep 05, 2008 2:24 pm   
 
Read this post and something wasn't quite clicking, started thinking about it and think i may have a decent idea...

The mapper can be broken down into several parts,
1) Backend, reads database into memory, provides information as requested and updates as directed
2) map properties window, allows the viewing and editing of room(s)
3) map viewer window, a visual display of the map, with functionalty to edit/move/add rooms
4) map location object. Tracks players/pets/summons/friends on the mud

As I see it, all that the properties window and viewer should have 2 modes of operation, static and dynamic. The difference being weither or not the current selected map location object is followed. I would find this very helpfull. One mapwindow/properties for my current window, both dynamicaly following location object a (me), and a second set, following a pet or static and letting me edit information else where. For the properties window, a right click or a drop down from the status bar would work wonderfull for selecting which map location object to either zoom to, or dynamicaly follow.

The map location object i believe should be what calls scripts, and requires the scoping. IT is what is moving into rooms and may have multiple occourances. I don't think ALL map location object will want to run scripts, maybe a property to disable room scripts... when a friend moves a room, you dont' want that script to go off. I like vijilante's idea about using #with maplocationobjecta {.........}

When it comes to scoping %roomxxx() functions, perhaps if the roompropertie is a number use that number, then if it is a location object use that location's room, FINALY use the default/primary/scripting location object's room?
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Sep 08, 2008 7:06 pm   
 
Wrym: Your description is basically correct. Those are the "parts" that the new mapper is broken into...that's what I've been working on for the past week. But it's not actually the map location object that "calls" the scripts. It's really a parameter that is passed to the scripting system. The location object is basically the default room number when calling %roomXXX functions without a first argument.

But you raise a good point:
Quote:
when a friend moves a room, you dont' want that script to go off.

That's correct. I can see that when a location object is tied to a different window (like a pet window), then maybe you'd want the room script to fire when the pet moved. So I think each location object will need a property to decide whether or not it runs the room scripts when it changes locations.

I've been thinking about the location object a bit more and how to better integrate it into the scripting system. In the other thread on scripting Vijilante talks about a good model for handling the room scripts, and talks about a possible syntax for #location objects. But I was thinking more about this and how CMUD might distinguish between a "location" object and just the ID name of a room. For example, when you normally do this:

#SHOW %roomdesc("MyRoom")

you are displaying the description of the room with the ID name of "MyRoom". So there needs to be a way to tell the difference between an ID name and a Location name.

So I was wondering about using a syntax similar to local variables where :name would refer to a location object. So you could do:

#SHOW %roomdesc(":location")

to display the description of the room currently at the specified location object. It might even be possible to treat :name in a lot of ways like CMUD treats $local references. For example, you might be able to assign them like variables:

:mylocation = 123

sets the "mylocation" location to room 123. Or

:mylocation = "myroom"

sets the "mylocation" location to the room with the IDName of "myroom".

With this kind of syntax, the CMUD parser could be expanded to recognize optional location objects within various commands. For example, the #MOVE command normally moves your "current" location in a specified direction. But CMUD would be able to add an optional location object so that you could do something like:

#MOVE :mylocation north

to move a specified location object in a given direction.

I need to think more about the parser implications of this. It might be tricky to handle location names that have a space in them, although ":my long location name" with the double quotes around it might be good enough.

I don't think it conflicts with the window-name syntax, since that syntax is either windowname: or :windowname: with a colon always at the end instead of just at the beginning.

Anyway, even though this overlaps with the other topic on scripting the new mapper, I'd be interested in continued options and discussions. This is the stuff I'm in the middle of implementing this week.
Reply with quote
Tech
GURU


Joined: 18 Oct 2000
Posts: 2733
Location: Atlanta, USA

PostPosted: Mon Sep 08, 2008 9:35 pm   
 
Finally got a chance to read this through and i think Vij and Zugg have something good going here. All of what I was going to suggest when the topic first came has been covered.

Wrym I'm not sure I quite get your static and dynamic modes of operation. Are you saying the 'dynamic' mode would be the normal usage as today (with autocenter) on a particular location object, and static just focus on a specific room? Would there really be a need to call this out? And if so wouldn't it be just as easy to just bring up the room properties on a map window that didn't have a default location object that was moving?

[Edit] Zugg I like the idea of having a shortcut syntax for location objects but I'm a little concerned about the parsing implications of using ':' for map location, but if you're Ok with it, then I guess I am too.
_________________
Asati di tempari!
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Mon Sep 08, 2008 10:51 pm   
 
I'm still stuck on parts of this, so I think I need to start setting some restrictions. I was trying to be too general-purpose and was running into recursive class problems.

Let me know if you think these restrictions are reasonable:

1) The map *database* needs to own the list of location objects within that database. This is because a location object is actually just a room "Key" value, which is a pointer to a room record in a particular map database. So a location object cannot be shared across multiple map databases. I think this one is pretty obvious.

2) A map "viewer" window is associated with a single map "database". You cannot display multiple map database files within a single map viewer window. Again, I think this is pretty obvious. However, multiple "viewer" windows *can* point to the same database (allowing each viewer to be showing a different zone and/or location)

3) Each map "viewer" has a single "current location object". This is the object (like the normal Blue Dot) that the map viewer is tracking and keeping centered (if auto-center is turned on).

4) Each MUD session window has a single "current location object". This is the location used by default with the %roomXXX functions if another room ID or name is not specified. This is the location used by commands like #MOVE, #WALK, #TELEPORT, etc unless some other location is specified (or unless it is within a #WITHLOC command).

OK, so I think those are all reasonable assumptions and restrictions. So now here is the part that I'm still having a bit of trouble with: how do I "connect" a particular map viewer with a particular MUD session window?

For example, I want to have a *single* map viewer window and when I click on the "CharacterA" session window, I want the map to show and center on the CharacterA location (which is the current location of the CharacterA session window). But if I click on the "CharacterB" session window, I want the map to change to show and center on the CharacterB location. In other words, two session windows are sharing the same map viewer. Same if the room properties dialog is being displayed and shared between the two session windows.

So how does CMUD know which map viewer is assigned to a specific MUD session window, allowing for multiple session windows to be assigned to the same map viewer? Seems like the map viewer needs to have a pointer to the "current session window" that is using the mapper. But when you click on a session window, it needs to know if that session window is allowed to use that particular viewer window. Because some other session windows might have their own viewer window.

You see the problem? A MUD session window cannot "own" a map viewer, because we want a single viewer to be useable by multiple session windows on the same MUD. But the viewer window cannot "own" a MUD session either. So we end up with a list of MUD session windows and a list of map viewer windows and no easy way to associate them with each other.

It seems like a map viewer window needs to have a list of MUD session windows that can use it. If you click on a MUD session that is in this list, then the viewer window updates to show the current location of that MUD session. I can implement that, but then I'm not sure how to give the player control over what session windows are in the list for each map viewer window, without making this really complicated for players. I'd like to hide as many of these details as possible so that it's just easy to use.

Maybe I need to add some menu commands like "Attach to map..." that would display a menu list of current map viewer windows, along with an option to create a new viewer window. And then a "Detach from map" that lets you detach a session window from a map window. And maybe have similar commands in the map viewer where you can "Attach to session window...", and "Detach from session". Session windows with the same stored %pref(MapFile) database name would share a single map viewer by default unless you selected the "Attach to new map viewer" option.
Reply with quote
shalimar
GURU


Joined: 04 Aug 2002
Posts: 4662
Location: Pensacola, FL, USA

PostPosted: Tue Sep 09, 2008 12:54 am   
 
Go by a variable (%focus?) defined by which session owns the window that last had focus?
It would retain its value until another owned window gains focus (to allow for the map having focus)
_________________
Discord: Shalimarwildcat
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Sep 09, 2008 4:05 am   
 
I am great with the restrictions 2-4.

Restriction 1 seems like a problem to me. To my view the map database is the collection of rooms, exits, and information directly tied to them. The database doesn't care about how it is displayed, and a location object is clearly a diplay object. It says, "draw a dot of this color over that room." I don't think we want the database to own the object, but we do want it to be clearly associated to a database. That association could either be done by asscoating to a specific map window (ie I want to display the location of a group of people in 1 window but not another), or directly to the database. I personally think that associating to the window, or list of windows is a better method.

Another reason to not have locations in the map database is that they will often be used with tracking other players. Basically the moment you go offline all of those entries become invalid. I am almost tempted to request they get a default field, use default check box, and the same automactic #NOSAVE treatment as variables.

Now to handle associating a map to a session. I had suggested provided a parent window field that would fix a given map window to a specific session window at load. As that field might be empty, or in the case you are suggesting where 2 sessions completely share the window I would say the procedure would look something like this.

Loading up:
1. Packages all load.
2. Map window opens.
3. Map window executes the equivalent of #LOCATION to get a list of all location objects within its scope.
4. Map window picks throuh all those to determine which apply and draws them.
5. Map window then checks its enabled packages for windows.
6. Map window polls those windows to see if they can see the map window and whether they are set to have a connection.
7. Map window checks its parent field if it is set and that window is in its list then the list is reduced to just that window.
8. Map window then just listens for redraw messages from the final list. Which should update by loading, unloading, and disabling of packages.
9. Perhaps the user can lock the map window to regular window temporarily, or lock it to a location object; either way the mapwindow already has a good list for these things and they just need to be kept up to date.

Continuous play:
1. Session window isn't actually doing anything with the map window. That is probably the key
2. Session window is executing scripts which cause locations to update. Locations have a definite assciation with a specific map window or database. When they are changed they now have a context as well.
3. The updated location sends the new information to its associated map windows and tells them in what context the update occured. When the location object is connected only to a database then it sends out the update referencing the database and passing the context. Each map window responding to the message can now check its redraw lists to determine whether it should update.

I don't see any recursions yet.

Now we get to the troublesome problem of 2 sessions sharing the same map. In all the stuff above updates should occur correctly, but the real question is how to meet your requirement 3. Having the map window be able to use the focused session's current location seems a reasonable enough method.

We already see from step 3 of Loading that the map window might need to be able to execute scripts within its own context, and that is a scary thought. At the very least it does need to be searchable by the existing context routines, and would also have to know what window context to use to #RAISE onRoomEnter. You can see in my Continuous Play step 3 that the context information is passed to the map window. That is the information it would use to determine where to #RAISE; and also decide whether to recenter, update a dot, or just ignore it.

The dot might be ignored because the location object is not inscope for the currently associate session window. For example I have 2 characters running about. One charms a monster, adds a dot to its map for it and runs it over to the vicinity of the other character. In this particular mud my 2 characters are mortal enemies, and to better roleplay it I wouldn't have them telling each other thier plans for killing the other. That charmed monster is an ambush waiting to happen, and I would want only 1 of my character to know its spot.

I think nealry all these statements for the map windows can be applied quite directly to the room properties window. The key as I see it is to pass the context for the update to the map window, and let it decide based on its setting what redraws are required. If I have 2 sessions and 2 maps I definitely don't want both maps to change when I click between sessions, but those 2 maps may be using the same database and most of the same locations. I may want 1 to shift with my focus in a given session window, and the other to be locked onto a specific location. I might even open a 3rd and want it to not follow any locations, work based on focus; and that would be the one I would use to scan where I want to speed walk to. The mapper needs to have that kind of flexibility in order to completely blow people away.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Sep 09, 2008 4:45 pm   
 
I think I mis-spoke in my assumption/restriction #1. I didn't mean to talk about where the location objects would be *stored*. They are going to be stored as new types of settings objects within the character session package, just like other aliases, variables, etc. In fact, they work much like variables as indicated with my post above where you can access their values via :location syntax.

What I meant is that a location is intimately tied to a specific map database because a location is just a room number. For example, your :current location might be room 123. Now, if you load a completely different map database for your session, room "123" no longer means anything. That room number might not even exist in a different map database. So logically, all locations are specific to a particular map database, even if they are not stored in the map database itself.

I think we are both on the same track here, but I just wanted to clarify that.

Back to the map/session association. Everything you mentioned is mostly correct and is what I was originally thinking until I actually tried to implement it. The problem comes from this statement:
Code:
1. Session window isn't actually doing anything with the map window. That is probably the key
2. Session window is executing scripts which cause locations to update.

That is true for commands like #WALK, #MOVE, etc. But what about commands like #NODIR that effect the current speedwalk "queue" in the map. Right now the "queue" is part of the map viewer. As is the map configuration that allows the creation of new rooms and the parsing of the text received from the MUD to determine what room to walk into. In other words, when you type "north", that command is queued by the map viewer (and visible in the lower-right corner) and causes an #OK trigger for the room to the north to be created. When the #OK command is executed by the session that fires the trigger, then the map moves the location to that room.

So part of this involves the location object, but part of it involves the current speedwalk queue for the map viewer.

As I type this it occurs to me that I probably need to pull the map configuration data into yet another code module to separate it from the database and the map viewer. That map configuration information shouldn't be associated with a specific window, but should be associated with the database (even if it is stored separately). Two map viewers displaying different levels of the same map database should share the same map configuration and not have separate configuration.

But where is the speedwalk queue? Is it associated with the map viewer, the location object, or the database? Seems like it should probably be associated with the location object so that multiple location objects can be in the middle of their own speedwalk queues.

If the queues are part of the location objects, then I think you might be correct that all scripting commands and functions are ultimately tied to the location object and executed in their context.
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Sep 09, 2008 7:51 pm   
 
OK, I think I have it figured out now. The key is to put the #map commands and %roomXXX functions into the Location object itself. These are properties and methods of the Location object. The #MOVE command tells the location object to move. The %roomXXX functions set/retrieve properties of the Location object. Each Location object has it's own movement queue so that each one can be in the middle of speedwalking. Each Location object has a reference to the map configuration object to use for movement. It's the Location object that has the "track vs map mode" setting to determine if a new room is created in the map database when the location moves. It's the Location object that determines if room scripts should be run, etc.

Each Session window has a single "current location" object. This is set via the #LOCATION command (or via the #WITHLOC command). The Session window doesn't actually have any connection to the map viewer or room properties window at all.

When a Session window sets it's current location, the location object adds the session window to it's internal list of "attached sessions". Multiple session windows can set the same location object, in which case the location object has a list of multiple session windows. When a session window changes to a different location object (via #LOCATION), then it removes itself from the current location object and adds itself to the session list of the new location object.

Each map Viewer window has a list of location objects to be displayed on the map, along with a "current tracking location" object. If this is empty, then the map isn't tracking any specific location. Otherwise, when the tracked location changes, the map is re-centered on the tracked location.

Each Location object also has a list of all map viewer windows that are actively tracking the location, or just viewing the location. This allows the location object to notify the appropriate windows when the location changes.

When you double-click on a map to speedwalk, the speedwalk command is sent to the current tracking location object. It's the Location object that sends the various direction commands to the session windows. The location object loops through it's list of session windows, and sends the direction commands to any session window that has an active network connection (with some smarts to prevent duplicate direction commands from being sent to multiple windows that are sharing the same network connection).

When a session window uses the #WALK command, this is sent to the session's current location object. The speedwalk path is computed directly from the database (no map viewer is needed). Like above, the commands are sent to any session windows that are attached to the location object which have unique network connections. The #OK trigger is sent to the session window that issued the #WALK command, and #OK causes the location object to update it's location, which then notifies any Viewer or Properties windows in it's list of the change.

The key concept here is that the Location object is really in the center of everything. The session window only interacts with the Location object. The Viewer and Properties windows only interact with the location objects. There is no direct connection between the Viewer window and the Session window. They only connect indirectly via the location objects.

Some test cases:
Single session with single map viewer and properties
This is the default case that probably 90% of CMUD users have. In this case, the current location object in the session window is also the current tracking location in the viewer window and in the properties window. Double-clicking on the map sends the speedwalk directions from the tracking location to the list of sessions stored in that location (which is just the single session window). That window has a network connection, so it properly sends directions and responds to #OK commands to update the location, which then causes the map viewer and properties to be updated. It all works exactly like it did before with no changes. No fuss, no mess.

Two session windows sharing the same map viewer and properties
Each session window has it's own current location object (CurrentA and CurrentB). The map viewer is set to "dynamic track" mode, which will update it's tracking location based upon the last session window that gets focused. If you click on the SessionA, then the CurrentA location looks at it's internal list of map viewers and if any map viewer is set to dynamic, it updates the tracking location of that window to the CurrentA location. If you click on SessionB, then the CurrentB location object looks in it's internal list of map viewers and sets any dynamic viewer's tracking location to CurrentB.

Double-clicking a room on the map sends the speedwalk directions to whatever the current tracking location is. Each location sends the directions to it's specific session window, which then causes the map to update. If you click on the other session while the first session is in the middle of speedwalking, then it's still fine. The original tracking location object is handling it's own speedwalk queue and as #OK triggers fire in the original session, the location gets updated, which then updates the location of the marker on the map (but doesn't cause the map to re-center because the map is now attached to the location object of the session that you just clicked on). In other words, the original speedwalk continues as normal in the background even the map is now centered on a different location object.

When either session window issues a #WALK command, the command goes to the current location object for the session, which then handles the speedwalk, regardless of whether it is being actively tracked in the single viewer window or not. Issuing a #WALK command doesn't change anything for dynamic map viewers...only changing the session focus will change dynamic map viewers or properties windows.

Room Properties tied to Map window instead of session
In this case, we want the Room Properties window to be attached to the map window and change as different rooms in the map viewer are clicked on. To support this, we give each Viewer window an additional location which is the "currently selected location". This location is updated whenever you click on a room in the viewer window. Each viewer window has it's own selected location object that is different from any locations defined in any sessions. In the Room Properties window you select which Location object you want to follow (via the menu in the status bar). If you select a particular map viewer's selected location object, then the properties window gets updated when this selected location changes.

So, in all of these examples, everything flows through the Location objects. Each session can have it's list of location objects, or location objects can be in global modules to be shared between sessions (assuming the sessions are using the same map database). Each viewer window has it's own selected location object, and a reference to which location object is currently being tracked. Each viewer and properties window has a "dynamic" option that allows it to respond to focus changes.

All scripting works regardless of whether there is any viewer or property window open. You can use the #WALK command without any map window open (as long as a map database has been loaded for that session, via a new command called #OPENMAP, or if the %pref(MapFile) already has a stored value).

I think this covers it. Have I missed anything?
Reply with quote
Vijilante
SubAdmin


Joined: 18 Nov 2001
Posts: 5182

PostPosted: Tue Sep 09, 2008 10:33 pm   
 
It sounds like you nailed it and then some. Now I can't wait to play with it.
_________________
The only good questions are the ones we have never answered before.
Search the Forums
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Sep 09, 2008 10:59 pm   
 
Quote:
Now I can't wait to play with it.

Well, the mapper is now "all over the floor in pieces". This new architecture is a *huge* change to the mapper. It's not like a rewrite...all of the existing code should be completely re-useable. But getting all of the pieces put into their proper place (database, location object, viewer, properties, config, etc) requires a ton of editing and refactoring of the existing code (we are talking about something like 50,000 lines of code here). It's going to be days/weeks before I'm even able to get it all to compile again. And since the rest of CMUD didn't use a mapper in modules like this, this might be the "break" between the old v2.x and the new v3.x where I won't be able to produce any more v2.x bug fix versions. Depends upon how extensively the mapper changes effect the rest of the CMUD code and whether it's easy to handle the changes with conditional compilation statements.

It's a bit distressing when I get to this point of a project. Normally I like to make limited changes and then rebuild CMUD each night. But just the editing is going to take a least the rest of this week, and maybe into next week. And it's going to take even longer to debug and test it all.

When I'm done, I should have a *very nice* mapper architecture for the future. In the past everything has just been all thrown in the map viewer window class, and splitting out all of this code into it's proper locations should make it much easier to maintain.

Anyway, I appreciate everyone's patience with this. It will be worth it in the end. Just don't get worried if you don't see me posting very much over the next few days unless I run into more problems or headaches. And thanks for the help and suggestions...it's been very useful to "think out loud" about these changes.
Reply with quote
Seb
Wizard


Joined: 14 Aug 2004
Posts: 1269

PostPosted: Sat Oct 18, 2008 3:09 pm   
 
Sounds great Zugg! Just one suggestion:

It would be good to be able to have several possible locations for a single marker (what you are now calling Location objects) (probably each possible location of the Location object would have an identical looking marker), e.g. for when you are not sure of the exact location of that person or object but want to highlight possible locations on the map. Then if you want to speedwalk to that location (and the current Location object is not there), it would calculate which is the nearest (I realise that this calculation could be intensive if there are many possibilities) and speedwalk to that. (Then via script, one could unset this as a possible location if the person was not there, or unset all the others if they were.) This idea would also be important when you are not sure of *your* location on the map. Let's say #FIND comes up with 5 possibilities. They should each be added to the current Location object and as you move, any possibility that rules itself out because the next room doesn't match should be eliminated so you will eventually get back to a certain (as in sure) location. I know this aspect will certainly complicate the procedure when you move your character, but it also useful if, say, you are in a maze that has random exits. If a room is flagged as RANDOM, moving any direction from the room would check to see which of the rooms is all directions might be a match, and add all of them to your current *possible* location. As you keep moving the number of possibilities may go up or down depending on how many RANDOM rooms you move through and how identical they are (including exits). Of course the number of possible next rooms when you issue a movement command can get exponentially big in a very nasty maze and this would slow down the map, but that is the price you pay. (This is a feature that one of the mappers made for my MUD has.)

Zugg wrote:
When a session window uses the #WALK command, this is sent to the session's current location object. The speedwalk path is computed directly from the database (no map viewer is needed). Like above, the commands are sent to any session windows that are attached to the location object which have unique network connections. The #OK trigger is sent to the session window that issued the #WALK command, and #OK causes the location object to update it's location, which then notifies any Viewer or Properties windows in it's list of the change.

Also, if the commands to sent to more than one session window, shouldn't the #OK triggers also be sent to the same session windows?
Reply with quote
Zugg
MASTER


Joined: 25 Sep 2000
Posts: 23379
Location: Colorado, USA

PostPosted: Tue Oct 28, 2008 11:04 pm   
 
Sorry, but absolutely not. A "location object" has a *single* integer value that represents the room ID. If you want multiple rooms to be marked, then you need to create multiple location objects. Basically, a "location object" is a "cursor" pointing into the mapper Room table. There is absolutely no way to have it maintain multiple locations for a single marker...it breaks the entire architecture.

For example, here is a simple case. When you enter a direction to move on the MUD, like "north", CMUD moves the current "location" marker to the room to the north of the current room. If the marker represented multiple locations on the map, this would be impossible.

There are other ways to handle your case of #FIND having multiple possibilities. The best way being to loop through the room possibilities and create a location marker for each one. For example, maintain the names of the multiple markers in a string list. Use the same color for each marker, but a unique name (like MarkerNNN where NNN is the number index into the string list of #FIND results).

Mapping mazes is very low on my priority list. Mainly because most MUDs go to a *lot* of trouble to make them nearly impossible to map. And the more work I put into trying to map them, the more work the MUD puts into making them impossible to map. For example, on Aardwolf, "maze" areas are randomly generated periodically so that the map that worked yesterday won't work today. No way to map that, so it's a waste of my limited time to worry about it.

Quote:
Also, if the commands to sent to more than one session window, shouldn't the #OK triggers also be sent to the same session windows?

No. If you have multiple connections sharing the same location object, then you need to send the movement command to *each* connection, but you only want a single #OK trigger to cause the location object to be updated. It's only when each connection has it's own location object that each window needs to have it's own #OK trigger.

And honestly, I wouldn't worry about this detail much since I can't even really think of a case where you would want multiple connections to different MUDs to share the same location object. The code handles it because of how it's written, but I just don't see it being a realistic possibility.
Reply with quote
intoK
Apprentice


Joined: 18 Feb 2007
Posts: 190

PostPosted: Tue Oct 28, 2008 11:47 pm   
 
Zugg wrote:

Mapping mazes is very low on my priority list. Mainly because most MUDs go to a *lot* of trouble to make them nearly impossible to map. And the more work I put into trying to map them, the more work the MUD puts into making them impossible to map. For example, on Aardwolf, "maze" areas are randomly generated periodically so that the map that worked yesterday won't work today. No way to map that, so it's a waste of my limited time to worry about it.


totally agree, hardcoding any sort of engine inside the mapper would be of limited usefulness and possibly impacted on general performance (%walk calls etc). but a there are things that can be done to support user-side engines, like ability to have user flag for exits which i mentioned (feature requested actually) in the other thread.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD Beta Forum All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net