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

Re: A few thoughts on client/server



Now I have read so many articles about client/server that I throw
in some my own comments. I probably repeat something that is
already said, but take this as just my opinion.

The first point I want to make is that client it just user interface
for the game. This is of course obvious, but this is sometimes forgetten.
And that means that everything that player can do, can made also in 
client automatically. Like if player can look the ground and pickup 
all diamonds, client can be configured so that it sends needed pickup 
commands automatically. Client purpose is offer nice playing interface 
not force player do manually simple things like this. Pickup by value/
weight index can be either client (where it really belongs) or in server
 (to save a little bandwidth, not need send examine/pickup packets).

And everything that player has seen can be stored in clients memory.
But client shouldn't get _any_ updates about items behind players
vision. So if monster dies behind wall updates shouldn't be send
before that player can really see that there is now more any monster.

I personally prefer binary protocol because it easier parse and
it saves CPU-time and bandwidth.

XPM (I talk here XPMs, althought client use graphic format most
suided it needs, of course) caching in client side is not very
easy problem to solve. Two different server can use same name to 
refer two totally different pixmap. Maybe this problem disappears
if servers use same name to prefer _exactly_ same image. The number 
of image sets affects here, keeping two set of images is acceptable,
but ten is too much. Server should notify client in the beginning of
the session that when images was updated and send list of changed
images, so that client can delete old versions. In server side 
pixmaps are easy collect files according to date, it just take a 
little more building time for images.

The best solution would be a smart cache which reads new pixmaps
from every server and compares images existing ones and adds it to 
general cache if it not exist or server ones if it different than 
the general image or if it is same as a general images already then
simply use general image.

I think its better send number-name list begin of connection and
after that use only numbers to refer to images. This saves really 
bandwidth a long term. Let's make some calculations from the current 
version. The number of pixmap is 2200, average length of name 12.6,
so it takes about 32 Kbytes send a list. After that you can refer 
each image with two bytes, so you save about 10.6 bytes per image. 
And average size of map is 27x26 which makes 702 squares. So using
numbers to refer images saves you 7441 bytes per map (and this 
is only floors not objects or animations). So after 4.3 maps it
starts really save bandwitdh. And little longer pause in the 
beginning of play isn't so bad than slow play the whole time.

I think it better client tell to server if it use B/W bitmaps or
color ones. First those B/W versions are already drawn and they 
looks much better than if client tries convert color ones to B/W. 
And secondly 24 * 24 bits = 72 bytes, where color images are
72 * 8 =  576 bytes. The client knows only how to display data
so that it looks good after when server is told client what data 
really is (bitmap name doesn't tell anything it's just reference 
to actual graphics data).

Simple way to transfer images are transfer colors when server starts 
and images when they needed as 576 bytes binary data. Or if limiting 
to current colors you need 5 bits per pixel and it would make 360 
bytes data. Easy to use everywhere and don't need any special parsing.

About doing animation in client is partical solution only. Most alive 
objects moves around so animating those in client side don't help, 
since you have update them anyway. So objects which can be animated on
client side are backgrounds (currently 3) and normal objects (e.g. 
diamonds and so, currently about 50). If client animates these, 
it helps server side. Note that alive object's animation can have 
a real meaning, like different animation of wizard, when he concentrate 
to cast a spell, director turning around and so on. So maybe there 
should be two types animations on server side, first done by client 
and second done be server.

One point about Carl Edman's protocol is that it makes difference 
between backgrounds and objects and that doesn't make sense. Does
that mean that background objects don't have same properties that
other objects? And what are these terrrains? Floors? Floors and walls? 
If walls does it count weak walls? And so on. I think it's not worth it.
And there isn't anywhere seen requirements how long client have to
keep items in the memory. Does UNMAP mean that client can delete
this square totally and server sends it again or does client have
to keep all places in memory where player is visited or so only to
next CLEAR command? Note that client really shouldn't been aware 
which physical map player is, although it probably knows it. Think
something like current world maps, client don't need to know which
physical map is in question.

One thing which makes hard to send just updates in visible items is 
that server has to remember all things what it has been send to every
player in the game. With 10 players and big map this is quite much of
memory to keep tracked. I prefer Kjetil's idea that client tells how 
many stacked objects client wants and server send images without names.
Since how many times players click on walls to see their names? 
If player wants to look at a specific square it sends command to server
("look x y"). Server sends back a string (and maybe pixmaps) what player
see there. So server can implement feature that player don't see all items
if looking from too far. Player don't need names most objects anyway,
so don't wast time to sending them.

I think it's also good assume that player is always in the centre
of view (currently 11x11). Maps are designed that way, so no need
of changing that. This view can be probably get up to 15x15, but
bigger that change the game too much. All maps are designed only
for small views.

One solution to send updates for map is that when player first time
enters to the new map, whole 11x11 (or 13x13, 15x15) area is send player.
With binary packet it makes 11 * 11 * 2 = 242 bytes per/graphics level.
Next time when view is changed server checks if how much that byte array 
is changed. If it changed only little then update packet can be send.
If player moves, that array is shifted in same direction that player
moves. It would be very easy to server remember what is send to 
each player since you need keep only latest update, not whole map.
Update packet use 3 bytes per location per graphics level, so it don't
even use much bandwidth.

One thing about protocol, it really can't be a stateless in sense
that server must know what packets are accepted from client. I mean
that dead players can't move around and so. It can be a very simple
as discussed protocol has shown. I use those commands only as commands,
not how they are encoded and sended. 

 -Tero

--