[crossfire] Re: Map Protocol Question

Andreas Kirschbaum kirschbaum at myrealbox.com
Sun Aug 21 15:43:03 CDT 2005


Mark Wedel wrote:
>
     
      Alex Schultz wrote:
     
     >
     
      > Wouldn't it work if you made the server behave properly, then let
     
     >
     
      > existing clients just send their mapredraw anyways? It might be a
     
     >
     
      > tad bit of extra wasted bandwidth, but it would make new servers
     
     >
     
      > behave properly to the protocol spec and old clients wouldn't be
     
     >
     
      > hurt, and just continue to waste bandwidth with the mapredraw to a
     
     >
     
      > similar to how they do already.
     
     >
     
     
     >
     
      The server is arguably behaving properly - as said, the design is that5H
     
     >
     
      the server basically just sends what changes. The event that causes
     
     >
     
      those changes isn't a concern to the server
     
     >
     
     
     >
     
      Originally, the client did not have any fog of war, so this was all
     
     >
     
      very simple - the server and client would remain in sync, as the
     
     >
     
      server would send updated info for all spaces that have changed.
     
     >
     
     
     >
     
      However, when fog of war was added, it was necessary for the client to
     
     >
     
      know when its fog of war data was no longer valid - hence the addition
     
     >
     
      of the newmap command. Originally, this was basically something to
     
     >
     
      just tell the client 'get rid of your fog data' - the server would
     
     >
     
      still do the 'right' thing and only update the spaces that changed,
     
     >
     
      and the client was still supposed to remember what data was visible.
     
     
I'd like to come back to this issue: I think the current implementation
of the newmap command does not work at all. (And cannot be made work
without changing semantics.)


Imagine the situation when a player leaves scorn through the east gate
into the gatehouse. Assume that the player is running, that is the
server automatically moves the player without receiving explicit move
commands from the client.

The following sequences of events and actions depicts two cases where
the map view of server and clients will differ eventually. The first
example is the "normal" case where the differing views auto-correct; the
second example results in a display error (which I actually can
reproduce here).

Of course, there is more than one possible event processing order for
client and server. But since the specific order I've chosen is actually
possible, I think the semantics of the newmap command are broken.

- client sends "run 3"

- server receives "run 3"
  server detects that player entered an exit, changes the player's map
  server sends "newmap"
  server sends "map_scroll +1/0"
  server sends "map1a <difference of Scorn to gatehouse>"

- client receives "newmap"
  client clears map information
  client sends "mapredraw"

- client receives "map_scroll +1/0"
  client basically ignores it because it has a cleared map state

- client receives "map1a <difference of Scorn to gatehouse>"
  Note: this information is not correct because it is a difference from
        Scorn, not a difference from an empty map. This is why some
        tiles show up as blank for a short time: all tiles that did not
        change are displayed blank (client already has cleared his map
        view).

- server receives "mapredraw"
  server clears map information
  server sends "map1a <difference of empty to gatehouse>"

- client receives "map1a <difference of empty to gatehouse>"
  Note: this information is not correct because it is a difference from
        empty, not a difference of the empty map updated by the previous
        map1 command.

Normally these differing map views are not (very) visible because the
"map1a <difference of empty...>" alone is the same information as both
map1a commands combined.


But there are cases where this equivalence does not hold. The following
example depicts such case. To simplify the events, the map1a commands
show only the updates of the player face.

- server sends "map1a <add player face at 4/4>"
- server sends "newmap"
- server sends "map_scroll +1/0"
- server sends "map1a <clear 3/4, add 4/4>"
- server sends "map_scroll +1/0"
- server receives "mapredraw" (due to client response to newmap command)
- server sends "map1a <add 4/4>"

Here the last line is wrong: the preceding mapredraw command makes the
server forget that 3/4 still contains a previously sent face. Therefore
the client now displays two player faces at 3/4 and 4/4. (The last map1a
command only updates the ground layer at 3/4, but not the layer with the
bogus face.)


Summarizing, I still think that the semantics of the newmap command
should be changed so that the server will clear the map information
whenever he sends that command: this change would solve the problems I
explained before because now all map state changes originate from the
server; the client just follows what the server says.


>
     
      Now, when maps are being changed, it probably is more efficient to
     
     >
     
      have a server->client command that basically says 'I'm clearing
     
     >
     
      everything' - that would be more efficient than the server sending the
     
     >
     
      coordinates and whatnot for a bunch of spaces that need to be cleared.
     
     >
     
     
     >
     
      The easiest way to handle this is to probably add something like a
     
     >
     
      newmap1 command. The client can negotiate its understanding of that
     
     >
     
      with the setup command like the other stuff. IF the client gets that
     
     >
     
      command, it acts liek it does now - clear out its fog data, and the
     
     >
     
      server knows that if it sends that command, it also clears out all its
     
     >
     
      data. So when the client gets it, it then knows it doesn't have to
     
     >
     
      send a mapredraw request to the server.
     
     
I fail to see why that newmap1 command is necessary since the protocol
specification says:

|
     
      newmapcmd (0/1)
     
     |
     
          This tells the server if the client understands the newmap
     
     |
     
          protocol command.  This is used by the client in the fog
     
     |
     
          of war mode to clear the old data when the player changes
     
     |
     
          maps.
     
     
I read this as "if the client does use fog of war mode, it should tell
so by negotiating the "newmap" command; a newmap command sent by the
server means that the player just had changed maps and that the client
should clear the map state".

Therefore I still think that the clients currently behave correctly, but
the server is wrong by not clearing the map state. That is, we could
just change the server behavior without breaking the specification or
existing clients.

    
    


More information about the crossfire mailing list