RunUO Community

This is a sample guest message. Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Ultima Live - In Game Map Editing Framework

Jeff

Lord
I'm also noticing that when I use a boat to travel over the normal transition, it jumps from 5105 to 15. Is this done server side?
Code:
    public abstract class BaseBoat : BaseMulti
    {
        private static Rectangle2D[] m_BritWrap = new Rectangle2D[]{ new Rectangle2D( 16, 16, 5120 - 32, 4096 - 32 ), new Rectangle2D( 5136, 2320, 992, 1760 ) };
        private static Rectangle2D[] m_IlshWrap = new Rectangle2D[]{ new Rectangle2D( 16, 16, 2304 - 32, 1600 - 32 ) };
        private static Rectangle2D[] m_TokunoWrap = new Rectangle2D[] { new Rectangle2D( 16, 16, 1448 - 32, 1448 - 32 ) };

Wrapping is an unknown concept to the client. Everything is done on the server.
 

Praxiiz

Sorceror
Thank you for the information Jeff. This makes a lot of sense. It looks like customizing map dimensions is going to require some extra modifications server side. I was hoping to avoid modifying distro files, but it looks like I won't have any other choice if I want to support custom map dimensions.
 

Pure Insanity

Sorceror
Couldn't this system could open up the possibility of making "instanced" dungeons or areas?

Jakob did made an attempt at instances before http://www.runuo.com/community/threads/instances-experiment.57254/

There is also another system that works a bit better for instancing. You can do instances without the need of modding a client, could be done many ways. Easy way would be to register a new map clone, and then just do a good job at keeping track of who is there, ect, ect.

So how much longer Praxiiz? Not trying to rush you, just pretty excited to play with it. =D
 

Pure Insanity

Sorceror
I've been meaning to post this and let you know about this. Just now remembered though.

Every time I use [circularindent the target thing is always messed up. Seems to change if I change the radius too.
9-28-2011 5-24-51 PM.png

Some times it'll have the ankhs and a wooden wall. Not sure how you did this...haven't really looked into it yet. Just figured I'd point it out.
 

Praxiiz

Sorceror
I need to redo the multi target implementation to use the packet that was shown earlier in this thread. Once that is done, you shouldn't notice any more abnormalities while using that target.
I have most of the functionality built to support additional maps, but I need to work out some issues with the Memory Mapped files on the client end.
 

Praxiiz

Sorceror
I made some good progress tonight. I setup a map on index 32 on my local server. I gave it dimensions of 10000 x 10000. I was able to [set map 32 and the client changed maps to my new blank map, including wrap-arounds and map dimensions.

To overcome the memory fragmentation issue, I simply made sure that I am mapping the largest of the files first. This is a band aid solution however, because it really doesn't address the real issue. The real issue is that I need a consistent way of dealing with fragmentation in the client's virtual address space. The easiest way to address this issue is to use smaller maps, and just unmap them when the player leaves that map. I'd like to find a more elegant solution though, and so I will continue to investigate this.

To finish the basic functionality, I still need to put together some packets that will be used to switch maps quickly. I need a mechanism to switch from map 32 for example back to Felucca. Since I'm remapping Felucca and putting map 32 in its place, I need to temporarily move the client to a different map, swap Felucca back to its original place, and then switch the client to Felucca.

This small victory taught me a few things though. Using VMMAP I was able to look at the fragmentation of the clients address space. Typically running under razor I'm seeing 1 gb of file mappings, and another 300 mb of other stuff. (Dlls, shared memory, the client text area, etc). This only leaves a total of 700 mb for more allocations, and its fragmented. The biggest block was 400 or so mb, which is the biggest size a map file could be made.

If anyone has any experience with with space issues in the virtual address space of a process, I'd love to hear any suggestions.
 

Pure Insanity

Sorceror
Sounds like you're making pretty good progress, as for map sizes...I believe they can be ANY size as long as they remain 8x8. I suggest sticking to the 8x8 rule too, as too many things server side rely on this...like harvesting veins and other stuff.
 

Praxiiz

Sorceror
They need to be in even block sizes, that is right. The 10000x10000 size was just an experiment to make sure the client would switch properly and to test the part of the code that handled the switch and the packet responses. Normally each dimension would need to be divisible by eight.

While theoretically the maps can be any size, practically they cannot. The client just doesn't have enough unfragmented address space. If it were a 64 bit executable, this wouldn't be a problem. But since its a 32 bit executable, we're limited to 2gb of addressable space. The largest contiguous block that I could find after the client loaded under razor was 400 mb. While that would support a large map, you then have to consider the statics file (statics#.mul), and statics index file(staidx#.mul).

The larger the map file, the more risk of the client being unable to load the file. Now if a map file was kept below the normal sizes (Trammel and Felucca), then Felucca could simply be unmapped before the switch and the chances are that the new mapping would sit in the same address space as Felucca.

Right now my code doesn't do any unmapping of files. I am going to have to add that functionality for this system to be practical.
 

Pure Insanity

Sorceror
I don't see any reason for needing huge map files when you could create new ones on the fly like this, as it helps you pass a limitation that has been imposed on UO for a long time now that has drove some people crazy. The ability to add new maps while keeping the old ones, or just adding a ton of new maps is simply awesome. Ultimately, if someone wanted the appearance of a large map, they could do some trickery and "wrap" one map to another map.
 

Praxiiz

Sorceror
It just occurred to me how to avoid this whole problem, and make the statics mapping better. When the client loads, one of the first things it does is to map all the mul files. Now when I originally made the framework, the big issue with statics was the fact that whenever a static was added, the file size grew. This made the mapping invalid, and the client couldn't "see" the new section of the file because the client's view of it was made before that portion of the file existed. To overcome that problem, I would simply make the view 1.5 times the size of the file, and copy the file into memory. The major problem with this is that copying the file takes time, and if you play for a long amount of time, or if there are enough changes to the statics file while you're playing, there is a potential for the client to overrun its view anyway. Its unlikely, but there is a possibility.

I think there is a way to solve this problem, and the problem with the contiguous address space in the client. When the client first loads and tries to map all of its mul files, I will map three large views of memory, say 400 MB, 300 MB, and 200MB (900 MB in three views). Whenever there's an attempt to map any of the statics#.mul, staidx#.mul, or map#.mul, I'll simply redirect them to one of the large map views. This will force the client to use the same address space for all its maps. Whenever the client switches maps, I'll simply remap the corresponding view to the correct map file. The difference in the sizes will next be mapped so that the two new views will be the same size as the original large view. Because I won't be mapping the original maps initially, it will save some of the address space to use with the large views.

I will experiment with this next and see if there are any unanticipated problems.
 

Praxiiz

Sorceror
I've been refactoring the client side injected DLLs. It needed a structural rework to be maintainable going forward. I've also been researching methods of preventing the address space from becoming fragmented. My work time on the project has slowed, but I believe I will be able to find a good solution soon.
 

KHzspeed

Sorceror
I'm having a bit of trouble getting this system to load on SVN 663 ML.
properly followed the instructions for Playermobile.cs Edits.
the server is halting on this error:

ClientFileExport.cs:
CS0117: line 17: 'Server.commands.properties' dose not contain a definition for 'Register'

UltimaLive.cs:
CS0117: line 22: 'Server.commands.properties' dose not contain a definition for 'Register'

any help?
 

Praxiiz

Sorceror
In each of those respective files, remove the

Properties.Register();

lines. I'll update the package downloads once I get this next release done.
 

Praxiiz

Sorceror
I made some good progress today. I've been using a 10000x10000 map (which is divisible by 8 in both dimensions). That size will be the maximum map size for this system. I have allowed for 200 megs of statics for a map that large in the address space. (That's twice the density of the OSI Felucca map)

I think the map swapping system is reliable now, although it needs some more testing. Right now I'm reserving three big chunks of space when the client loads and releasing them only when maps are swapped. I then reserve any difference in memory immediately after (if I reserve 300 megs and the mapped file only uses 200, I reserve 100 megs right after). The operations are close to consecutive, but it's not foolproof. There's always the chance that the thread's quantum time could run out right after I release the memory and another thread in the client could break up the memory blocks, which would in turn break the system (there wouldn't be a big enough chunk to allocate a new map). I don't think its likely to happen, but it needs to be tested and proven.

I have some work to do server side, and then I will likely post a release with minimal functionality. Maps will have to be defined ahead of time. The functionality to add new maps while the server is running won't be implemented in this next release, but I'll be looking into it in further releases. Ideally I'd like to be able to define and start decorating new maps while the server is running.
 

tass23

Page
Praxiiz, I have to say you're doing an awesome job here with this. It's things like this that make this community so great. So before it gets lost in the smoke when you publish a release, thanks for all your hard work!
 
Top