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

Re: A quick draft of a preliminary proposal for a possible version of the crossfire protocol



lemke@ncd.com writes:
>   Well, I've given the list of arguments why not N times on the list,
>   so   why not do it N+1 times ?  Forgive me if it is the short form.
> 

> i've seen them -- but my experience is that the binary solutions is
> better.  (which i also sent, and saw no response to).

Yes, I saw that article and found it interesting, but at the time I had  
already exceeded my personal crossfire-list posting quota.

>   * Less conflict between independent groups of extenders
> 

> no conflict at all if you specify the extension mechanism up front.
> look at X, and any of the related protocols.

X was developed and is maintained by a staffs of dozens of professional  
programmers at universities and OS developers who do nothing else but  
extend, optimize and fix bugs in it.  Unfortunately crossfire doesn't  
have that kind of programmer resources, so it needs to be a little bit  
friendly to the programmer.

>   * Doubtful if binary will use less bandwidth overall.  Certain that
>   it   won't in many cases.
> 

> name some.  a single byte opcode is smaller than a string.  2 bytes
> of length data is usually smaller than the ascii representation of
> the same. if the packets have a fixed format, there's no need for
> whitespace and other artificial delimiters.

On really slow connections (and those are what we are haggling about --  
an unloaded ethernet can handle anything we can dream no matter how  
badly designed) almost without exception use compression on the stream  
(like e.g. V.42bis).  In that case binary _and_ ascii will be  
compressed to a binary format.  I seriously doubt that after  
compression an originally binary format is still significantly smaller  
than an ASCII format.  Also, those compression algorithms were designed  
and tuned for ASCII text and may end up doing a better job on it that  
on binary.

>   * Byte order, data sizes and packing.  That can be solved on
>   systems   more easily than on others but is a perenial source of
>   bugs in binary   network protocols.
> 

> only poorly written ones.  all these problems have been solved,
> numerous times.  specify items in terms of bytes, don't use 'int'. 

> choose a byte order and stick with it, having one side swap where
> necessary.

I know, I know, I know.  You and I know the hoops we have to jump  
through and the operating systems we work under provide the libraries  
and tools to do that relatively painlessly.  Mac, DOS and Windows  
clients don't have that luxury and their programmer don't have that  
experience.  Considering how important these clients are going to be, I  
think it is important to make life easier for them if we can.

>   Ultimately it is true that it is possible to write a binary
>   standard   and enforce it and likely it will give a (slight)
>   performance increase   in a perfect program.  But then the same can
>   be said for writing   crossfire completely in machine language and
>   rewriting it for every   port. 

> 

> if your goal is to reduce bandwith, binary is faster.

Not necessarily.  See above.

> Its also faster to parse.

True, but not by as much as you may want to believe.  Remember that we  
are parsing machine generated statements of a fixed format and without  
ambiguity and not natural language (which is very slow to do well).   
Also I think we agreed that for virtually every client the limiting  
factor will be the network bandwidth/latency, not CPU.

> the major performance limitation of the game is
> communications -- that's where the effort is well-spent.

That's true.  But the commands worth optimizing are MAP, ITEM, and  
TRANSMIT (by reducing the number of unnecessary tranfers and  
interspersing them), not PLAY.  I'll offer you a bet of $1 that when  
the client is written in excess of 95% of server->client traffic will  
consist of these commands in virtually all situations.

> ascii may make the debugging simpler, but the players don't give a
> damn, they just want the best possible game. 


And for most users that is a game which is relatively bug free and in  
which bugs get fixed as soon as they are reported.

> make the choice that best solves the customer's problems, not the
> developer's.

Well, that may hold in the commercial world.  When a very small number  
of good programmers write something which very many users want and do  
it for free, the programmers do get to have some say about the product.  
:-)

>   >   > you'll want to have room for options here -- does the client
>   >   > support sound, what format does it want the images in (1 bit,
>   >   > color, etc).
>   >   

>   

>   >   The server does not care.  A client without sound, just never
>   >   REQUESTs   the sound files.  A client without graphics (i.e. a
>   >   curses or robot   client) just never REQUESTs the images. 

>   >   Clients with limited graphics   convert the received graphics
>   >   into whatever format displays best   natively.
>   >   

>   

>   > from what i saw, the server sent the 'play sound' messages no
>   > matter what.  sure the client doesn't have to fetch them, but why
>   > waste the packets if they're going to dropped?  a simple "here's
>   > what i do" startup packet saves a lot of bandwidth.
>   

>   How often is a sound played on average ?  Once a minute on average
>   ?    For 10-15 bytes for the command (as very few events only
>   consist out of   a sound, the play command will almost always be
>   part of a larger TCP   packet which would be sent anyway) it is
>   just not worth it.  I'm trying   very hard to keep all these kinds
>   of little server hacks which require   the server to take
>   particular care of each client for very very   marginal performance
>   improvements out of the protocol definition.
> 

> you said latency was important to you -- reducing round trips is the
> best way.  why is there a hack?  the code that plays the sound simply
> checks a client's attributes before sending it the sound.

I just think that is a complication which buys you almost nothing.   
I'll bet you another $1 than we the server is running and you add an  
option which disables play commands on clients which don't have sound,  
you'll reduce total server network traffic by less than 0.2%. 


>   > you also want to avoid round-trip whenvever possible.  a server
>   > that tells a client about an image for the first time should send
>   > the image then, not wait for the client to ask for it.
>   

>   The server doesn't (and shouldn't have) the foggiest idea if a
>   client   (a) even needs images (robots and curses interfaces don't)
>   or (b)   already has the image from an earlier session or another
>   source or (c)   needs the image again during the same session or
>   (d) ...
> 

> which is the whole point of having the client tell the server this up
> front.  if the client doesn't even have a display (i believe you had
> an earlier example of a client that was text-only), why should it be
> sent all the map commands?  why does it ever need images?

Even a client which doesn't display (like a robot) still wants to know  
what the terrain looks like.  A robot may not care what a firewall  
looks like, but it doesn't want to walk into one.  Also a curses  
clients, may not want the bitmaps, but it still needs to know the map  
so that it can draw the appropriate ASCII characters.

> making these choices up front is trivial, and saves lots of effort.

Well, if I wrote it, I wouldn't bother about enabling/disabling the  
PLAY command.   But I'm sure when the server is up, the maintainers  
will be happy to accept your patch.

>   Please lets try not to blow up the source for the client or the
>   server   by introducing vast numbers of mutual client/server
>   dependencies.
>   

> obviously we have different ideas of what should be in control.
> 

> to me, the server is in full control -- how can it be otherwise when
> it has to talk to multiple clients?  it must track where everything
> is at all times -- otherwise you get two people killing the same
> monster, or picking up the same item, etc.  the server should know as
> much as possible about the client, so it only sends the client the
> protocol the client cares about.  all the client does is provide the
> interface between the user and the game -- it displays what's
> happening and relays the user's actions to the server.  the client
> can do trivial stuff, like not allowing the user to walk into a wall,
> but anything that can change the world state needs to be handled in a
> central location.

Of course the server has to be in total and exclusive control over  
everything which actually happens in the simulated world.  I'd even go  
as far as to say the client should not prevent players from walking  
into walls -- who says that there wont be a spell which allows players  
to walk through walls some day ?  (also, how should the client know  
what a wall is -- a list of names ?).  But by the same token the  
_client_ is in absolute control of how, when and in what form it  
displays the world to the user and the server shouldn't care about  
that.

You can think of it like this:  Whenever the player character moves a  
limb or in any other way affects the actual simulated world, the client  
has to make that request to the server (and may not assume that the  
server will fulfill it).  Whenever the player character has some  
sensory perception of some form, the server has to tell client (and can  
then forget about it). 


For example, the player wants to pick up a sword.  So it communicates  
that desire in some way to the client.  Then the client has to tell the  
server that the player wants to do that (in the current protocol: MOVE  
<sword tag number> IN <player tag number>).  That is all.  The client  
does not change its own view to display that the sword actually is in  
the possession of the player.  Whenever the server gets around to  
processing the MOVE command, it checks whether it is valid (i.e. if  
somebody else has already picked up the sword in the mean time) and if  
so executes it.  That means that the view of the world has changed, so  
the server has to tell all players within the LOS that they've seen the  
sword become a possession of the moving player (in the current  
protocol: ITEM <sword tag number> IN <player tag number>  
<sword-image-name> Sword).  Then when the client receives that message  
will transmit it to the user in some form.  Typically that'd be  
something like adding the sword image to the inventory window.

I hope that was understandable -- it think it is very important to get  
the abstraction right.

> (i don't believe pickup (at least as i think of it) can be handled
> locally -- the server has to know that the object has been claimed by
> the user, so another user (or monster) can't pick it up.)

The point about PICKUP was a misunderstanding.  Currently there is a  
command called 'pickup' in crossfire which puts the player into a mode  
in which he picks up all items he runs over.  The argument was about  
whether the server would have to know about the pickup mode, or the  
client could just automatically send 'MOVE <item> IN <player>' to the  
server for all items in every square the player runs into.  


	Carl Edman