Crossfire Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: A few thoughts on client/server



I'm going to comment upon stuff that was posted a week ago. Be warned.

+--- Carl Edman:
| If an animation actually means something, it has to be done on the
| server side.  When I said animations I was thinking exclusively of
| aesthetic repeating patterns (like waves, or fire, or darkblade).
| Those I believe are both much more frequent and happen much faster.
| All of that is handled with relative ease by the proposed protocol.
| The only case which is really worrisome are spikes because they both
| have meaning _and_ they are constantly and quickly repeating.  A
| couple of spikes could really load a slow connection.

One of the advantages of using symbolic names for all of the images
was that an entreprising client writer could draw his own superior
sets of images. He could even make a 3D version of Crossfire (like
Wolfenstein, not Doom).

Clearly, putting some animations here and some there in the model will
complicate matters. All we need is a syncing parameter so that the
client knows where to start in the sequence.

ITEM <tag> <x> <y> [<image> [<qty> [<frame> [<description>]]]
    Default value for <frame> is 1, of course.

++--- Tero Haatanen:
|| Note that alive object's animation can have a real meaning, like
|| different animation of wizard, when he concentrate to cast a spell

Okay, let's take that example:

    ITEM 1232 1 2 wizconcentrate
    ITEM 1232 1 2 wizard.111

_versus_

    ITEM 1232 1 2 wizconc.111
    <0.2 seconds passes>
    ITEM 1232 1 2 wizconc.111
    <0.2 seconds passes> [...]
    ITEM 1232 1 2 wizard.111               

Notes:
  1. <wizard.111> could be an animation in a future version of
     crossfire.
  2. I think it is best that an animations replay speed can not be
     changed via the protocol. Animations with same images but
     different speeds should have different names. I don't think this
     will be common, anyhow.
  3. The fancy 3D client would have to download the animation
     descriptions to get the number of frames and hence the timings.
  4. As for syncing - we don't get sub-frame resolution here. This can
     be a problem if we allow variable frame length in the animation,
     so we probably should use a constant frame rate within the
     animation description, too. This makes it easier to handle at a
     possible slight performance penalty (size of animation
     description). Of course, the client can collapse it into
     (duration,image) pairs if it wants to.


++--- Tero:
|| So server can implement feature that player don't see all items if
|| looking from too far.
||
+--- Carl:
| If that is what you want (and it certainly sounds like a good idea),  
| then just don't send ITEM commands for faraway small items.

You realize of course that this won't work unless you put a lot of
state in the server for each client, a lot more state than I have
called for :-)

Onto ASCII->binary->UDP: The way I see it, that's the route we should
take. It is trivial to convert Carl's ASCII protocol into a binary
protocol, and it will be almost as efficient as a protocol designed to
be binary.

The only exception I can think of is MAP/UNMAP which could (as
suggested by a gentleman whose name I've forgotten) be optimised into
transmitting an 11x11 array - with 16 luminance values that is 61
bytes. The argument about the VIEW not necessarily being in the centre
of the display is mute - the client will have to map co-ordinates in
any case.

We should make the protocol so that making a UDP version isn't more of
a hassle than necessary.

A protocol which doesn't care about lost packets would have to be
_very_ graphical in nature. It would be a win over X, for sure, but
not much else. So we'd need to ack, but not necessarily for every
packet. The other thing TCP gives us is packet ordering. We can design
the protocol so that it doesn't depend on it. A sort of mini-TCP:

  server -> client:
    <send lots of data>
    <tick is over>
    ACK? 3 packets

  client -> server:
    <receive data>
    ACK! 3 packets
    <starts drawing>
 _or_
  client -> server:
    <receive some data>
    NAK missing packet with sequence number 2
  server -> client:
    <resend packet 2>
    ACK? 3 packets

and so on...

(every packet has a byte-sized sequence number, which is reset each
tick)

Getting UDP right is very difficult, though -- just look at the FSP
failure! I'll definitely recommend that we write the ASCII layer
first, which will be plenty fast enough for LANs and WANs. If we do it
right, slipping in a new transport layer would be piece of cake.

One more thing: It would be a good thing if the server sent some kind
of command at the end of a tick for the convenience of the client. The
client must otherwise use a select() with a small timeout to guess
when it is opportune to update the screen (assuming the client wants
to handle screen refresh in an optimal manner).


Kjetil T.

PS. I have actually played Crossfire over a 2400 modem while
downloading a file in the background (using term :-) I think that with
LBX and a 9600 modem or above, performance would be acceptable.
(Looking forward to May 2!)