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

Praxiiz

Sorceror
Altering it in memory works great - but it does require that the client change map numbers to see the effects.

In this screenshot, I've altered the memory to set the wraparound (where the actual map ends and begins wrapping around) to 1500. I haven't altered the regular dimensions. I'm standing at 1490.map change.jpg
 

Praxiiz

Sorceror
In this screen shot I've set both the wrap-around and the map dimensions to 1500. I'm still standing at 1490.
map change 2.jpb.jpg

Can anyone elaborate on what the transition should be? Is the client expecting a transition done by the mapmaker in the first screenshot?
 

Praxiiz

Sorceror
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?
 

Praxiiz

Sorceror
I suppose the specifics of the transition can be done manually for now, even if map makers have to use trial and error. It looks like these issues have already been addressed in that Ryandor thread. The next thing I need to decide how to implement is some sort of feature negotiation between the server and ultima live. I can change maps out now, and change their sizes, but the client needs a way to know what the dimensions of a map will be. It will have to get that from the server some how.
 

Praxiiz

Sorceror
I believe map wrapping is handled server side. Actually it would have to be, as the server handles all the player movement.

That makes sense. Once I complete this phase of the project, shards can use larger maps and more of them. Now to figure out how to implement a feature negotiation and how to handle new map registration on the server side.
 

Praxiiz

Sorceror
When the server registers a map, it knows the size. The obstacle is giving that information to the client. The map change packet only gives a map number.
 

Praxiiz

Sorceror
I suppose I can use the packets I've been using before, just adding another command to their command section. The client ignores those packets anyway. When a player logs in, I can send them a packet that enumerates the maps and sizes. When a new map is registered, I'd have to send a new packet out to all the clients on the server. Can you think of any other times?
 

Tabain

Sorceror
As for your first screenshot if you didn't realize this yet.. If the wraparound point is next to ocean, the client automatically renders continuous ocean over the black dungeon area so you won't be able to see the actual line of the wraparound when you're traveling by boat. Since the client is expecting ocean, it creates that artifact instead.
 

Praxiiz

Sorceror
That makes sense. And it explains the artifacts when I walk away and come back to see a solid black strip.

So far I've gotten the memory address searching to work. I can reliably locate the base pointers to the memory mapped indexes, maps, and statics files. I'm about half way through the code used to swap them out. I'm refactoring some of the client end code as I go. I can also reliably find the map dimensions and wrap around points which means that shard owners won't have to stick to the standard dimensions on any of their maps.

I have included a class on the server end where each of the physical maps will need to be defined. This means that you will define your logical maps in MapDefinitions.cs as you normally would, but the physical characteristics of the map files will also need to be described in another file.

I've added in the communication from server to client so that clients will receive the file definitions when they log in, and some of the intercept code for the map change packet.

I would estimate that I'm 80% complete with this basic functionality. After I'm finished, you will be able to add more map files with custom dimensions.
 

Praxiiz

Sorceror
A 10,000 x 10,000 map with no statics will take up over 300 mb on disk.

10,000 x 10000 = 100000000 tiles
100000000 tiles / 64 = 1562500 blocks

1562500 blocks x 12 bytes = 18,750,000 bytes in the staidx#.mul file
1562500 blocks x 196 bytes = 306,250,000 bytes in the map#.mul file
0 bytes for the statics#.mul file

total bytes: 325,000,000

Considering Felucca - 7168 x 4096 = 29,360,128 tiles / 64 = 458,752 blocks
Every static takes 7 bytes. The statics file for fel is 22,321,495 bytes (v7.0.2.2).
There are 3,188,785 statics in Felucca (22,321,495 / 7).
This means that on average, Feluca has / 6.95 statics per block. (3,188,785 statics / 458,752 blocks)

If you decorate like the OSI guys, you can expect the statics file for a world of 10,000 x 10,000 to have 10,859,375 statics (1,562,500 blocks x 6.95 average statics per block), giving it a total size of 76,015,625.

In total, a decorated world of that size could take up over 400 mb.
 

Praxiiz

Sorceror
It also occurred to me today that if a shard didn't want to release its custom maps, then the map would be streamed to the player only as the player visited portions of the map. This means that a player would have to visit every block on a map to get the entire file. They could actually run lines every 5 blocks.

This concept could prevent shards from stealing each others maps. A shard owner couldn't simply download another shards custom maps and use them outright without visiting every portion of the map.

The cost of this would be incurred in bandwidth. But a typical player isn't going to cross more than a block or two per second at a full run. This means that if a map the size of Felucca was entirely land, it would take 458752 seconds (assuming 1 second per block), which would be 7645 minutes, or 127 hours.
Assuming a player ran the length of the map at full speed in lines every 5 blocks (the update range for the system), It would take 91,392 seconds. This is assuming one block per second (4096 vertical tiles / 40 tiles = 102 lines which are 7168 tiles long or 896 blocks long. 102 lines x 896 block lengths = 91,392 block lengths) 91,392 seconds = 1523 minutes = 25 hours to get the entire map
 

Pure Insanity

Sorceror
And even then, they would only be able to "map" the parts that they could reach. =P

So your system is basically gonna handle patching for maps, that's pretty sweet. There's really no need for us to put them in our own patches if we use this method, right?
 

Praxiiz

Sorceror
While switching memory pointers seems to be easy enough, memory mapping a 300mb file in the client memory space throws out of memory exceptions when mapping (This is due to the address space, not the actual available amount of memory on the system). This is most likely caused by a combination of the 2 GB limit on 32 bit processes (which can be lifted to 3 gb, but not something I'll require users to do), and the need for a contiguous block in the process space. Mapping smaller files doesn't seem to be a problem. It looks as though I'm going to have to put some kind of memory management class in client dll, and probably restrict the size of custom maps.

If the client executable were 64 bit this would most likely not be a problem.
 
Top