SENDEVENT - EVERYTHING ONE NEEDS TO KNOW! ========================================= By Marco Hladik Last updated: 10th of August 2018 sendevent() is the function you call from the CSQC to communicate, reliably, to the SSQC on the server. USAGE ===== The first parameter of sendevent() specifies the function to call in SSQC: sendevent( "Myfunction", "" ); However, it will not look for "void() Myfunction" on the SSQC, there is a prefix reserved for all sendevent calls. That one is `CSEv". So in reality, the above command will execute this on the SSQC: void CSEv_Myfunction ( void ) { } Now, what about that second parameter? .. , "" ); Well, sendevent has the ability to send data. 6 arguments can be passed, max. That second parameter string specifies the type of data you want to send. For example, you want to ask the server to set the health of a player to a specific value: CSQC: sendevent( "SetPlayerHealth", "f", 124 ); SSQC: void CSEv_SetPlayerHealth_f ( float h ) { ... } As you can see, the `f` indicates the type float. `s` would indicate a string. `v` would indicate a vector. `i` would indicate an integer. 'e' would indicate an entity (more about that in the last chapter). The second parameter specifying the arguments will append to the name of the function you're trying to call. It sadly does not yet support structs. CSQC: sendevent( "SetColorAndName", "fffs", 255, 0, 128, "Tommy" ); SSQC: void CSEv_SetColorAndName_fffs ( float r, float g, float b, string name ) { ... } ..is what a longer sendevent with multiple arguments would look like. 6 arguments are the maximum. This is because QuakeC supports 8 arguments max per function call. If you, however, only want to send floats and require more than 6 arguments, you can store them inside vectors: CSQC: vector v1 = [ myfloat1, myfloat2, myfloat3 ]; vector v2 = [ myfloat4, myfloat5, myfloat6 ]; vector v3 = [ myfloat7, myfloat8, myfloat9 ]; vector v4 = [ myfloat10, myfloat11, myfloat12 ]; vector v5 = [ myfloat13, myfloat14, myfloat15 ]; vector v6 = [ myfloat16, myfloat17, myfloat18 ]; sendevent( "Bah", "vvvvvv", v1, v2, v3, v4, v5, v6 ); SSQC: void CSEv_Bah_vvvvvv ( vector v1, vector v2, vector v3, vector v4, vector v5, vector v6 ) { myfloat1 = v1[0]; myfloat2 = v1[1]; myfloat3 = v1[2]; myfloat4 = v2[0]; ... } NOTE ABOUT SENDEVENT AND ENTITIES ================================= If you pass an entity via sendevent, it'll in reality send only the entnum. The entnum is the essentially the entity-id. If the entity does not exist via the SSQC (like, it has been removed since or is a client-side only entity) then the entity parameter on the SSQC function call will return `world` aka 0/__NULL__. For protective reasons, entities that are removed have their entnums reserved for a specific amount of time before being able to be used again. Player entities, for example, will allow their entnums to be recycled after 2 seconds. Any other entity its entnum will be reusable after only half a second. This should avoid most entnum conflicts. Basically, during this time, the CSEV_* will not return `world`. HOWEVER: This is entirely unreliable behaviour. Check if the .classname is VALID on the SSQC before doing anything fancy on it.