runtime map modification

For some situations it might be a useful feature to be able to change the map layout while the players are playing. This will allow us to implement features which allow the players to affect the ingame world with their actions. Examples are:

  • Events which make bridges or walls appear or disappear (like switches or trigger areas)
  • Gates which open or close
  • Cities which lie in ruins after an invasion
  • Constructions created by players
  • Even maps which are entirely procedurally generated by the server are possible

The GPMSG_MAP_LAYOUT_PATCH message

This message is sent by the map server to inform the clients about the differences between the original map as it is in the map files and its current state. The packet can either include the changes in a rectangular section of the map or of the whole map (by defining a rectangle which spans the whole map).

It is sent:

  • when the client enters the map (this patch includes all changes)
  • when the map is changed while the client is already on it (this patch only includes the last change)

GPMSG_MAP_LAYOUT_PATCH byte layer, coordinates x_y, coordinates width_height, byte compression_method,{ int16 data }

  • layer: id of the map layer affected by the changes (when multiple map layers are changed a packet has to be sent for every layer)
  • x_y: upper left corner of the affected rectangle
  • width_height: size of the affected rectangle
  • compression_method: In most cases the map data will be easily compressable. This byte allows to define the compression method used. 0 means no compression. 1 could, for example, mean GZIP and 2 BZ2. One value should be a special compression algorithm for walkmaps (because they need less than 16 byte per tile and will be frequently affected by map-changing events). The server SHOULD use trial&error or heuristics to find the optimal compression algorithm.
  • data The actual map data. Might be compressed by an algorithm denoted by compression_method. After applying the algorithm it is a chain of width*height 16 bit integer values. ** 0-32768 The tile id as explained in the map file ** -1 Tile stays as it currently is ** -2 Tile is reverted to the original state in the map file

Handling changes in the walkmap

When the walkmap is changed some beings might end up stuck in an inaccessible area. The feature which invokes the map change is responsible for preventing or fixing this situation. Examples for handling this are:

  • simply not allowing the map change as long as a being is inside the blocked area (door)
  • hurt them and then move them out of the blocked zone (cave-in)
  • warp them to another map (pitfall)
  • accept trapping the beings as long as the situation is only temporary (ice trap)
  • always have some kind of "emergency exit" when there is the possibility that a character becomes unable to leave an area without the help of another character (complex switch puzzle).

Note regarding detecting such situations: Remember that we are developing a massive multiplayer online game. You never know how many (or few) characters are in one area.

Limitations

  • It is not possible to add new tilesets to the map. Only tiles from the tilesets already used by the map can be used.
  • The feature which invokes the map change has to be aware of the id number of each tile. A change in the map file which changes the tile IDs will break it.
  • This feature should generally be used sparingly because it can create a lot of traffic when there are a lot of clients on a map and there are frequent and comprehensive map changes.

When not to use map patching

  • Animation - use animated tiles instead
  • Critters or similar objects which move around randomly - use NPCs or particle effects instead

Comments

Bertram - 2010/02/01: Maps files could also have preset multi-state parts stored within their data. The server could then trigger the state of the wanted map part, which could still be the entire map. Then, the task to reload the map part would only go to the client. This state mechanism, if well thought, could also add/remove layers, and/or change its size. Last but no least: We still have to think about the multi-level map design and handling.

The GPMSG_MAP_PROPERTY_PATCH message

This message allows to change a map property like background music or ambient overlays. It is used in the same way as the layout patch message - when the client enters the map or when a change occurs.

GPMSG_MAP_PROPERTY_PATCH { string key, byte mode, string value }

The patch can include any number of key/mode/value combinations.

  • key is the affected property.
  • mode can be 0 to replace the old value with the new one, 1 to revert the value to the original state in the map file or 2 to remove it entirely.
  • value when the mode is 0 this is the new value of the property. When the mode is 1 or 2 the value field has no meaning. the server SHOULD thus send an empty string.

Comments

Bertram - 2010/03/31: Again, here, maybe we should go more likely for presets triggered by the server. Otherwise, the server will have to be aware of available ambient overlays, music files, etc...

I'd provide this, IMHO:

GPMSG_MAP_PROPERTY_CHANGE { string key, byte preset } Change a visible map property the client should take care of. * key is the affected property. ("overlay{0,1,...,n}", "music", "title", ...) * preset The map preset to be loaded by the client. A 0 value means that this property should be disabled, or emptied. In other cases, the value tells the client which preset is to be used for the corresponding key value. On client side, the preset values are map properties stored as: preset_<key>_<preset>="value" If the client doesn't have such preset, nothing happens.