Index | FAQ | Search | Memberlist | Usergroups | Profile | Log in to check your private messages | Log in | Register

I don't understand the whole server/client thing.

| Inside3d Forums Forum Index -> QuakeC Programming

View previous topic :: View next topic
Author | Message
--- | ---
Nash Joined: 19 Oct 2007 Posts: 95 Location: Kuala Lumpur, Malaysia |

Posted: Sun Nov 11, 2007 1:20 am Post subject: I don't understand the whole server/client thing. |

To be honest, I really don't get the concept at all. A lot of stuff I'm doing is basically "because everyone else is doing it that way". I don't fully understand the things I code in my QC. For example, all that WRITEBYTE stuff. What's that all about... ? Would the game not work if they weren't there?

Back to top |

daemon Joined: 07 Nov 2007 Posts: 62 |

Posted: Sun Nov 11, 2007 2:23 am Post subject: |

I don't exactly know what the WHOLE purpose of WRITEBYTE is, but I know it's one way of sending information to just one client. For example, a you can make a sound play for just one player, like a menu sound or something. There are lots of other purposes for it though, i just don't know what they are.
The main point for me to use CSQC is to be able to draw text onto the screen w/o having to send strings over the network every second or so. But there are lots of other goodies like being able to draw images to the screen w/o doing something hacky like attaching them to the player's view and disabling gunbob.
I haven't seen it done yet, but you could probably also make player movement clientside, and then instead of you seeing yourself lag before you move, only the other players would see you lagging, but no one would really be aware of it unless the lag got really bad and you started taking damage while it looks to you like you're not getting hit.
_________________
-daemon [ daemonforge.org ]

Back to top |

Sajt Joined: 16 Oct 2004 Posts: 1026 |

Posted: Sun Nov 11, 2007 2:35 am Post subject: |

You're lucky you're using Quake, you pretty much don't have to worry about server/client stuff! Quake is one of the easiest modding platforms because its networking so simple. (UnrealScript, on the other hand...) All the QC runs on the server. Every 'tick' (see sys_ticrate cvar) the server sends the states of relevant entities to each client (relevant meaning the entities that are in view). The state includes modelindex, frame, angles, origin, effects, etc. The clients are basically dumb and simply render these entities. Very simple!
The WRITEBYTE stuff is for one-off events, stuff that doesn't work in the 'entity' state system.

Code:
WriteByte (MSG_BROADCAST, SVC_TEMPENTITY); WriteByte (MSG_BROADCAST, TE_EXPLOSION); WriteCoord (MSG_BROADCAST, org_x); WriteCoord (MSG_BROADCAST, org_y); WriteCoord (MSG_BROADCAST, org_z);

Here you are setting up to send a sequence of data to all the clients in an unreliable manner (since you're using MSG_BROADCAST). You're sending the 'tempentity' message, so for example this sends an 'explosion event' to all the clients. The client parses the message and makes a particle spray and plays r_exp3.wav.
The first argument to Write* functions is the message type. This has to be the same for all Write* calls in a sequence. The second argument to Write* functions is the data.
Message types:

- MSG_ALL sends to all clients in a reliable manner. Used for such things as chat messages.
- MSG_BROADCAST sends to all clients in an unreliable manner, meaning that the packet could get lost. This is more lightweight than reliable messages and is used for less important messages like sounds and tempentity effects.
- MSG_ONE sends to one client (as defined by the QC global msg_entity) in a reliable manner. This is used, for example, by sprint (SVC_PRINT) and centerprint (SVC_CENTERPRINT), which only print to a single client.

When the client reads data from a packet, it first reads a byte and sees which SVC_* constant it lines up with (see QuakeWiki for a list of all SVC_* constants). Then it parses more data, depending on which SVC_* was used.
For example, an SVC_SETVIEW byte is expected to be followed by an entity (WriteEntity). An SVC_TEMPENTITY is expected to be followed by a TE_* byte. An SVC_TEMPENTITY, followed by a TE_EXPLOSION, is expected to be followed by three coords (WriteCoord). And so on.
Note that on old engines, if you use up an entire packet (about 1400 bytes), either by having too many entities in view of a client, or by sending him too many WriteByte messages, you'll get 'packet overflow' and everything off the end of the packet will be ignored. You can notice this on old engines if you have too many gibs: you won't hear any more sounds, because the SVC_SOUND messages are after all the entities in the packet, and since there are too many entities the SVC_SOUNDs get lost.
Of course, newer engines like DarkPlaces are more intelligent: they give entities priority, and if an entity doesn't fit in a packet, it will give it extra priority to be sent next tick. So with a lot of entities, you get a bit of delay but they all still get sent. The priority system makes it more or less cycle through entities so they each get sent every couple of ticks, rather than only the first couple of entities on the list getting sent every tick.
Man I'm bad at explaining.
_________________
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.

Back to top |

daemon Joined: 07 Nov 2007 Posts: 62 |

Posted: Sun Nov 11, 2007 7:21 pm Post subject: |

Sajt wrote:
MSG_ONE sends to one client (as defined by the QC global msg_entity) in a reliable manner. This is used, for example, by sprint (SVC_PRINT) and centerprint (SVC_CENTERPRINT), which only print to a single client.

So when you use sprint() or centerprint() it automatically uses MSG_ONE? I assume so, just curious.
_________________
-daemon [ daemonforge.org ]

Back to top |

Spike Joined: 05 Nov 2004 Posts: 944 Location: UK |

Posted: Mon Nov 12, 2007 8:16 pm Post subject: |

daemon wrote:

Sajt wrote:
MSG_ONE sends to one client (as defined by the QC global msg_entity) in a reliable manner. This is used, for example, by sprint (SVC_PRINT) and centerprint (SVC_CENTERPRINT), which only print to a single client.

So when you use sprint() or centerprint() it automatically uses MSG_ONE? I assume so, just curious.

Nope, that's a simplification.
sprint and centerprint are _like_ MSG_ONE (sent to one client and reliable) but in reality the code in those builtins goes through directly without ever thinking about MSG_ONE. although as far as qc is concerned, there is no difference.
packet overflow happens after 1000 bytes in unmodified quake. 1400 in quakeworld (but quakeworld limits the number of ents anyway, so 1400 isn't really reachable).
To reiterate what sajt said:
In basic unmodified quake, the server is the entire game with the clients as nothing more than input gatherers and renderers. but they do need other information, like what to draw where, hence centerprints, sprints, and all the WriteByte calls.
To simplify the engine design, quake is both a client and a server, even when playing single player. Demos are simply a recording of the data sent from the server to the client.
MSG_BROADCAST is seen by all, and its unreliable (meaning its meant to be seen by all players, but it might never actually arrive, effectivly getting ignored). MSG_ONE is seen only by the player named in msg_entity. MSG_ALL is like MSG_BROADCAST, except that you know they'll actually get it.
Be careful when using WriteByte. Try and get the exact sequence correct, and avoid spamming too much in any one frame. Old servers (and a decent handful of new servers too, certainly in quakeworld) will barf if your writebyte data overflows a buffer, which will be seen on the client as illegible server messages. If you get one of these messages, then it was 90% chance of something to do with writebytes. Darkplaces provides many builtins which are not only slightly easier on the eye, but also ensure that the buffers are correctly flushed and will not overflow awkwardly.
CSQC complicates matters by putting seperate gamecode on the client, which can be interpreted however you want. with csqc, the state-based form of ssqc is highly weakened. It can still be written as state based, but the csqc is able to impose additional state that would not otherwise be there, but it requires additional mapping on the server, which can be hidden away in a seperate qc file somewhere. CSQC gives additional control, particuarly over the 2d parts of the screen, but it also allows prediction and things too.
daemon: regarding player movement in csqc, I did get this working at least with fte and qw protocols/physics. FTE at least is capable of doing it as perfectly as normal qw prediction, although I do admit that the qc code required to do so is larger than is really desirable, due to my own design decisions regarding how ssqc/csqc interact - read: requires ssqc changes too. But this is a seperate topic which I really ought to elaborate on some other time in a different topic.
_________________
What's a signature?

Back to top |

Display posts from previous:

| Inside3d Forums Forum Index -> QuakeC Programming | All times are GMT
Page 1 of 1

Jump to:

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Powered by phpBB © 2004 phpBB Group