|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Sep 02, 2008 5:42 pm
Scripting in the new mapper |
After more thinking this past weekend, I am doing some more architecture changes to the new mapper. When I was changing the code to allow the Room Properties window to be open even when the mapper window was closed, I started running into problems. In the old design, the mapper window was the one that actually opened the map database and manipulated it. But now I wanted the Room Properties to open the map database even if the main mapper window wasn't open.
This led me to thinking that I also want all of the %roomXXX functions and various other mapper commands and functions to still work when the mapper window was closed. For example, if just the Room Properties is open, then you should still be able to use #TELEPORT to change the room name/description and compass values shown in the room properties.
So I'm going to try and split the mapper *database* stuff from the actual windows themselves. In other words, the map database would exist within your session window as it's own object. The first time you use a mapper command or function, it will load the map database into memory automatically, just like it does the first time you open the mapper window.
But having the database separate from the mapper window or the room properties window would make this all more modular and would allow your map scripts to work even if the map wasn't being displayed.
This has also gotten me re-thinking the discussion in the http://forums.zuggsoft.com/forums/viewtopic.php?p=132895#132895 thread where I walked about making the mapper into it's own package. I'm not sure this works very well when allowing multiple map windows within a session. In this new design, each window in the session could have it's own map database object. That allows me to have multiple map windows (or room properties windows) that point to different session windows, rather than having a single map window that owns the map database connection. So the map database is really associated with a specific session *window* and is not in it's own separate package.
I'm just thinking out-loud right now, but I need to take some time to think about this a bit more. I don't want to come back in Phase 2 and need to re-design this all over again. Since the SQLite database conversion has already required a re-design of the mapper, I think this is the time to get this all structured the way it needs to be for future improvements too.
I know that the mapper *configuration* needs to be kept modular so that people can upload their configuration to the Package Library. But where do the Room Scripts and Zone Scripts belong? They are part of the map data itself, and not part of the "configuration". But are they specific to a particular session?
One way to think about this is to imagine a map shared by multiple characters on the same MUD. Obviously each character on the same MUD should share the same map "data" (room names, descriptions, exits, etc). But are the Room Scripts specific to each character, or are they generic for everyone using the same map? I can see arguments on both sides. But most of my mapper Room Scripts are pretty generic (like sending "show wares" when you enter a store, etc). So I guess I need some feedback from people who are using more complex mapper scripts, or maybe from people who would *like* to use more complex map scripts. Should these scripts be stored with the character session, or with the map data, or both somehow? And if "both", how to distinguish character-specific scripts from generic room scripts? |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Tue Sep 02, 2008 8:26 pm |
I believe room, zone, and map script should be stored with the map. They are part of the map data as they are a direct interaction based on the map. Handling a character specific thing is very easily done by having an alias, or better yet a function. The call to the alias/function is in the room script and is somewhat generic. The existence of that alias/function within the scope of the particular session becomes the controlling factor for how it behaves with that character.
|
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Tue Sep 02, 2008 9:10 pm |
Personally I would like to see room- and other map-related scripts stored with the map. Because they are map-related. I'm still not quite familiar with CMUD scoping rules at module level, but at least I would like that map scripts will "see" all the same settings that main window sees. If no, then I'll use events.
To be honest, the more I think about raising events in a room script, the more I realize that large part of the map scripts can be transferred to the character session, even generic scripts. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Sep 02, 2008 11:50 pm |
I think I also agree with this. Which is why I posted...
So here is the problem. Currently (and in zMUD), when you move into a room, the "context" is set to the System/_TempRoom class and the room script for the room is executed. When you leave the room, the contents of the System/_TempRoom class are removed.
Because it creates/destroys the scripts every time you move into the room, it is slow. And it is also the cause of the crashes that sometimes occur when the #OK trigger is deleted.
So first I'd like to find a way so that the mapper isn't always creating/destroying scripts. I'd like it to compile a script and cache the compiled code, just like other scripts, and then just enable/disable as necessary.
Also, it would be nice to edit Room Scripts in the normal Settings Editor. For example, we know that there are many properties of some settings (like buttons) that cannot be specified with a #BUTTON command. So rather than a Room Script containing a script like:
Code: |
#ALIAS whatever {do stuff}
#BUTTON ...
#TRIGGER ... |
it would be nice if you had the normal settings editor "tree view" and could select the alias, button, trigger, etc and edit it. Or use the New/xxx menu to create a new setting within the room, etc.
Those are the challenges that I'm struggling to deal with. I want to improve the performance of room scripts, but also leverage the existing setting editor to create/edit/delete room scripts (and zone scripts, and room "kind" scripts, etc).
Right now the settings editor only edits the settings that are stored in package files. This is why I thought about creating a package file for the mapper itself. But this means storing the scripts in a separate package file, and not with the map data directly. |
|
|
|
shalimar GURU
Joined: 04 Aug 2002 Posts: 4692 Location: Pensacola, FL, USA
|
Posted: Wed Sep 03, 2008 1:02 am |
make a new default package type then, Mudname.cMap
folks will want to be able to transfer just the map without necessarily getting all the room scrips and what not, just the room layouts and exits and what have you
the specific room scripts could be stored then with the main session, or in a separate package still. defined in a new modular setting type called #ROOM |
|
_________________ Discord: Shalimarwildcat |
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Wed Sep 03, 2008 11:15 am |
As I mentioned in the other thead about multiple map windows a setting that associates to the window seems like the right way to do these things.
This would then allow the creation of classes as a child of the mapWindow setting with names like MapMode, FollowMode, Room1234, ZoneAbc, etc. These classes are turned on and off as appropiate. The mapWindow setting itself would need to have some controls related to display as well as the module scoping controls. That makes moving into a room just matter of doing #T+ Zone;#T+ Room%roomkey, and letting the scoping take care of what becomes available where.
Following becomes almost a simple trigger #TRIGGER {%%roomname(%%destroom)}, that again is turned on and off as directions are queued. It would be slightly more complex since %destroom points at the final destination during a speedwalk, and there are also many other options to consider such as room description matching, but that is the basic gist of how to do it.
Mapping similarly is #T+'ed when a direction is queued and turned back off when things are done.
For display purposes, I would say put a button where the current script entry boxes are, and get rid of the script boxes. The button displays "Create scripts" when a class does not already exist, and clicking on it would create the class and open the PE to that location. When the right class exists the button should display "View scripts", and would open the PE to that class. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Wed Sep 03, 2008 2:14 pm |
Also, I think portal information should be character specific and not map file specific. This especially could come in handy when sharing map files. Right now I have to delete all 70+ stored portals before I distribute my map file to others then use an alias to add them back in. This would also come in handy when using one file with multiple characters on the same mud. This is not allowed on my mud but imagine if your portals are level based and each character can use a different set. Or like in Aardwolf where each portal is something actually held/owned by the character. Each character would need his own seperate list.
|
|
|
|
cazador Apprentice
Joined: 08 Dec 2005 Posts: 108
|
Posted: Wed Sep 03, 2008 3:35 pm |
Toxic wrote: |
Also, I think portal information should be character specific and not map file specific. This especially could come in handy when sharing map files. Right now I have to delete all 70+ stored portals before I distribute my map file to others then use an alias to add them back in. This would also come in handy when using one file with multiple characters on the same mud. This is not allowed on my mud but imagine if your portals are level based and each character can use a different set. Or like in Aardwolf where each portal is something actually held/owned by the character. Each character would need his own seperate list. |
I would suggest a little different approach. I have played many muds where portals are available for everone, even in Aard there are several like that. So my suggestion is to break portals into two locations one for global portals and one for character portals. |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Wed Sep 03, 2008 3:38 pm |
the ones available for everyone (at least in aard) arent portals in the mapper sense of the word. They are more like custom exits. Anyways Im sure Zugg will understand what I'm getting at.
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Sep 03, 2008 6:51 pm |
Yep, I understand the character-based portals that Toxic is talking about. They require you to hold a certain object in your hand and then ports you to a certain location. The current portal system in zMUD/CMUD doesn't handle it very well and doesn't really work with speedwalking automatically. I was able to create some aliases and then enter those aliases into the portal list, but it's a bit kludgy, and as Toxic mentioned, it doesn't led itself to sharing the map files with someone that doesn't have all of the portal objects.
I'll give that some thought for later in the mapper development.
Vijilante has got the idea pretty well thought out for the scripting. It's the way I was thinking about it when I posted in the original thread about the new mapper. But part of me still wonders if there is a better way to handle the room scripts. The difference between room scripts and normal classes is that only a single room is active at any given time. Yes, I can #T- the previous room and #T+ the new room. But I wonder about the efficiency of having all of those disabled rooms laying around.
One big difference between a Room and a normal Class is that the Room needs to have a "default script" that runs when it is enabled. For example, I have many rooms where the room script is just a simple command sent to the MUD when I enter the room. Such as "show wares" for entering a store, or "train" when entering a training room. So a Room needs to be able to have it's own script that it executes, while still being a "container" for other scripts.
When converting an existing map file, the current room script text becomes the "default script" for the room object in the mapper package. When this default script is executed, the context for creating new aliases, variables, etc will be the room class itself. So any script that currently uses an #ALIAS command to create an alias that works within the room will still work after the conversion...the default room script will execute and create the new alias within the room class folder. Once the alias is created, you can edit the default script to remove the #alias command, but even if you left it in, it would just modify the existing alias the next time it ran, so it would still work and would just give a lower performance than if you removed the #alias command from the script. I think this gives pretty good compatibility with existing maps.
Having each map database with it's own map package file also provides an obvious place for CMUD to create any temporary #OK triggers, instead of using the "System" class folder in the main character settings. And as Vijilante mentioned, several special class folders could be automatically enabled/disabled depending upon the mapper mode. This design keeps the map scripts separate from the character files. And even though they are stored separately from the actual map database, it gives people the flexibility to share their base map data without sharing the scripts. So it seems like a good solution. |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Wed Sep 03, 2008 7:04 pm |
Right the easy way to handle it is to use an alias that you enter into the portal field in the mapper and then use #TELE to transfer you inside the script. It also makes it easy to use the control the level based portals based on your current level as well as readding them all back to the mapper at any given time, but if it was more functional it would be nice thats for sure.
|
|
|
|
Arde Enchanter
Joined: 09 Sep 2007 Posts: 605
|
Posted: Wed Sep 03, 2008 8:30 pm |
Zugg wrote: |
Yes, I can #T- the previous room and #T+ the new room. But I wonder about the efficiency of having all of those disabled rooms laying around. |
You may think about alternative algorithms and then compare their estimated efficiency to pick up the best. Hm... One of alternatives, for example, could be an array or a list of sorted (for using of quick find) room vnums (integers) for the rooms that have some script. Then, instead of doing #T+/#T- for each room traveled you just check is their vnum cached in that array. If it is, then you fetch script from the map package. |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Sep 03, 2008 9:57 pm |
It's more complicated than that. Imagine that a room has a variable and an alias in it's script. Somehow this alias and variable need to be accessible within the normal internal settings database when the room is active, and not accessible when the room is inactive. Otherwise, this variable and alias needs to be handled just like any other variable or alias. CMUD already has an internal cache of settings, and somehow the settings for the room need to be added to this internal cache so that they will work.
I think I'm just going to do the #T+/#T- to start with and then see if there are any performance problems. I can't think of any other method that works easily with the current settings structure in CMUD. Making the mapper a package with it's own file and making rooms work as classes allows it to fit nicely within how CMUD already works and would result in the minimum number of other changes. Scoping rules would all work automatically, etc. And since the scripts in the mapper package would be normal scripts, there could be all sorts of other advanced usage that some people might come up with. The only difference between it and a normal package is that the various Room objects would be automatically enabled/disabled as you want around the map.
So I'm going to start with that. The only thing in the back of my mind was some performance issues that Vijilante reported a while back when enabling/disabling settings with a very large number of classes. But I'm not even sure if those performance issues still even remain or not. |
|
|
|
Toxic Adept
Joined: 27 May 2008 Posts: 299
|
Posted: Wed Sep 03, 2008 10:02 pm |
So is this going to work the same way with zone scripts? or is that going to be possible?
|
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Wed Sep 03, 2008 10:21 pm |
Yes, Zone scripts would be handled with ZoneXXX "classes" that are enabled/disabled when you enter/exit the zone. So just like with rooms.
|
|
|
|
Vijilante SubAdmin
Joined: 18 Nov 2001 Posts: 5182
|
Posted: Thu Sep 04, 2008 10:21 am |
I thought a little bit about the import to convert the scripts into the new format. One idea I came up with looks something like this:
#CLASS Room1234
$Commands=%replace(%exec(%roomcom(1234)),"|",";")
#EVENT onRoomEnter {$Commands}
#CLASS 0
This would roughly create all the settings, and put any commands that are sent immediately into the event. Obviously the replace isn't quite good enough. The only thing is to make sure that the correct room is enabled before the event is raised by the mapper.
In terms of performance, I think there are only about 5 rooms out of 5000 that I had to put a room script in in my map. Looking through the map used by one of Achaea's top explorers there are about 30 rooms out of 15000 with a script, and only one of those scripts defines some settings. The only place I could imagine a performance issue occuring is with raising the event, and I can't really see it being an issue with so few classes added. |
|
_________________ The only good questions are the ones we have never answered before.
Search the Forums |
|
|
|
mr_kent Enchanter
Joined: 10 Oct 2000 Posts: 698
|
Posted: Fri Sep 05, 2008 10:24 am |
Vijilante wrote: |
In terms of performance, I think there are only about 5 rooms out of 5000 that I had to put a room script in in my map. Looking through the map used by one of Achaea's top explorers there are about 30 rooms out of 15000 with a script, and only one of those scripts defines some settings. The only place I could imagine a performance issue occuring is with raising the event, and I can't really see it being an issue with so few classes added. |
Boat travel and herb collecting on lp-muds have led me to use many room scripts. Most of this could be moved into a package and then I could just set variables and call aliases from the room scripts but I have many more rooms than 5 or thirty with unique code.
Not meant to prove disprove any statement or belief. Just wanted to mention it. And now I'm wondering if it is only because of the wacky things in lp-muds that makes the difference. Or maybe I just abuse the room scripting ability. |
|
|
|
Tech GURU
Joined: 18 Oct 2000 Posts: 2733 Location: Atlanta, USA
|
Posted: Sat Sep 06, 2008 1:34 pm |
One thing Zugg hinted at, but I didn't explicitly see called is scripting for a particular room type. For example I may want all my shop specific scripts automatically running when I enter a shop room type. Of course I could detect and enable these types of scripts from my packages or add the room script to each room of that type, but I think scripting to a room type would be much easier.
While we're at it, I would like to onRoomEnter and possibly onRoomWalk tell you the type of room entered as part of the event. Although I supposed I can always trap the generic event, inspect the %roomxxx properties and raise my own room type specific events if need be. |
|
_________________ Asati di tempari! |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Mon Sep 08, 2008 6:55 pm |
Yes, room types will have their own script "classes" too. But not in the very next version. But once I have something like RoomXXX classes, then it will be easy to add something similar for room types that get automatically enabled/disabled.
|
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Sat Oct 18, 2008 2:48 am |
I'm a bit late to the party on this one, so I expect Zugg already decided, but anyway...
Zugg wrote: |
I think I'm just going to do the #T+/#T- to start with and then see if there are any performance problems. I can't think of any other method that works easily with the current settings structure in CMUD. Making the mapper a package with it's own file and making rooms work as classes allows it to fit nicely within how CMUD already works and would result in the minimum number of other changes. ...
So I'm going to start with that. The only thing in the back of my mind was some performance issues that Vijilante reported a while back when enabling/disabling settings with a very large number of classes. But I'm not even sure if those performance issues still even remain or not. |
Yeah, I remember reading something about CMUD being a lot slower with say 200 settings all disabled than 0 settings. So keeping all these settings hanging around, even disabled, is going to slow it down. Especially if we are including the #OK triggers, because then we are talking about thousands of settings! On the other hand, if the #OK triggers are not saved to the SQLite pkg file but only make it into the in-memory cache, then it should be fine - in which case they are going to need to be created and destroyed dynamically since they weren't last after closing CMUD.
The advantage of the #T+/#T- though is that it is easy to edit a room script for a room that you are not currently in! This was pretty difficult in the old mapper for 2 reasons:
1. Any movement would cause the room you had open to change.
2. Many other commands sent to the MUD would apparently cause the room you had open to change (maybe due to some scripts I have running to clear rubbish off my mapqueue).
I'm in favour of having a separate package (implies #T+/#T- scripts) or database (implies dynamic creation and deletion of scripts) for map scripts though. Clearly the room data and room script, zone data and zone script, etc. need to have links so they refer back to each other and deleting the data deletes the scripts too.
As for room types and room flags (and even room costs, maybe room contents), they can be raised by events that are active in your global map script: it would be good if these are accessible in a way that doesn't involve an extra database lookup (since that room is active anyway). |
|
|
|
Zugg MASTER
Joined: 25 Sep 2000 Posts: 23379 Location: Colorado, USA
|
Posted: Tue Oct 28, 2008 10:55 pm |
There is only ever one #OK trigger at any time. So that's not a problem. The problem is that right now CMUD is creating/deleting this #OK trigger, instead of just having a fixed trigger that is enabled/disabled (with a changing pattern). Changing this will make the mapper faster and fix the crashes when speedwalking across zone boundaries that sometimes happens right now (the #OK trigger gets deleted while it's still running).
Anyway, the architecture is mostly already decided at this point. The map viewer window will have a "window" setting, similar to the MUD output window. The room properties window will also have a "window" setting. Within the map viewer window you will have "Room" objects that are similar to class folders that contain your scripts for the map window.
By default this map window is stored within your normal session package. Of course, you can always move it to a separate package if you want. You handle that just like moving any other window to another package. |
|
|
|
Seb Wizard
Joined: 14 Aug 2004 Posts: 1269
|
Posted: Wed Oct 29, 2008 2:00 pm |
Zugg wrote: |
There is only ever one #OK trigger at any time. So that's not a problem. The problem is that right now CMUD is creating/deleting this #OK trigger, instead of just having a fixed trigger that is enabled/disabled (with a changing pattern). Changing this will make the mapper faster and fix the crashes when speedwalking across zone boundaries that sometimes happens right now (the #OK trigger gets deleted while it's still running).
Anyway, the architecture is mostly already decided at this point. The map viewer window will have a "window" setting, similar to the MUD output window. The room properties window will also have a "window" setting. Within the map viewer window you will have "Room" objects that are similar to class folders that contain your scripts for the map window.
By default this map window is stored within your normal session package. Of course, you can always move it to a separate package if you want. You handle that just like moving any other window to another package. |
This all sounds very good, and I think the changing pattern on the #OK trigger will really speed things up (especially if it's not saved to the external DB), particularly when the Package Editor and Map are both open and on at the same time. |
|
|
|
|
|