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

Shared entities CSQC

| Inside3d Forums Forum Index -> QuakeC Programming

View previous topic :: View next topic
Author | Message
--- | ---
Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Tue Mar 25, 2008 12:43 pm Post subject: Shared entities CSQC |

The thread subject might not fit considering I only have a simple question, not something large concerning the whole act of shared entities. But then again, this thread could be used for all shared entities related questions in the future. Just in case you don't know what a shared entity is, it's a serverside entity which has a copy of itself in csqc. Why? Because you can do all kinds of cool things on the entity which you can't do in ssqc, atleast not cheap. All kinds of cool effects at no networking cost, prediction stuff, you name it.
My question right now is, I have an entity with a model, and it seems that the model shows up even though I haven't precached it in csqc. I recall someone said it needs to be precached in *atleast* csqc to show up, server doesn't matter. Currently it's only precached on server. It uses setmodelindex, and later because of shared code it also does a setmodel.
The reason I'm asking is I just want to check that I'm not delusional, since these sort of things matter to me. I want to be able to have models in csqc which don't even exist on the server, at some point, so I'm planning to ditch the setmodel on the server, and the setmodelindex in csqc, and only use setmodel on csqc.
_________________
Look out for Twigboy

Back to top |

daemon Joined: 07 Nov 2007 Posts: 62 |

Posted: Tue Mar 25, 2008 5:10 pm Post subject: |

as far as I know, in darkplaces models have to be precached on the server at least a few ticks before you use them in csqc. otherwise i've never needed to precache in csqc. not to say that won't change in the future... _________________ -daemon [ daemonforge.org ]

Back to top |

Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Wed Mar 26, 2008 6:51 am Post subject: |

Yes I recall that, but I also recall someone saying that it should be possible to only have it available on the client, without the server knowing about it. _________________ Look out for Twigboy

Back to top |

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

Posted: Wed Mar 26, 2008 8:38 am Post subject: |

In FTE, there are two seperate model precache lists. Models precached only in the csqc have negative indexes. I was under the impression that DP worked the same way. Note that precaches shouldn't be required in csqc. The engine should load them on demand, so it doesn't matter too much, just keeps all loading out of the actual gameplay.
Modelindexes from the server are 100% usable in csqc. The only exception to this is if you didn't precache the model at load time on the server. In which case, the model name on the client might not be known immediatly. But as soon as the relevent packet arrives it'll be known and take effect. Until then the ent will be invisible. Note that the chances of this happening are fairly slim, but if you depend on model names, its best to precache. If you don't care about model names, its just a bit of extra lag.
_________________
What's a signature?

Back to top |

LordHavoc Joined: 05 Nov 2004 Posts: 243 Location: western Oregon, USA |

Posted: Wed Mar 26, 2008 8:51 am Post subject: |

Spike wrote:
In FTE, there are two seperate model precache lists. Models precached only in the csqc have negative indexes. I was under the impression that DP worked the same way.

A correct impression.
However there has been some bug in DP at some point in the past that made it not work - I never understood the bug and had no test cases, so I don't know if it has been fixed.

Spike wrote:
Note that precaches shouldn't be required in csqc. The engine should load them on demand, so it doesn't matter too much, just keeps all loading out of the actual gameplay.

Loading freezes during gameplay = oww.

Spike wrote:
Modelindexes from the server are 100% usable in csqc. The only exception to this is if you didn't precache the model at load time on the server. In which case, the model name on the client might not be known immediatly. But as soon as the relevent packet arrives it'll be known and take effect.

This only works because entities contain model indices into one of two separate tables, if they were remapped to one table it would fail to fix the model on an entity later on when the precache is eventually received.
Luckily both engines implementing csqc use separate tables for client side and received server side precaches.
To answer Urre's question about precaching - precaching is not required in ssqc or csqc and doing so or not has no impact on the models, however when ssqc code calls setmodel without precaching first, a developer warning is posted, as it's generally a sign of lazy code.

Back to top |

Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Wed Mar 26, 2008 3:31 pm Post subject: |

What happens if a shared entity is removed in csqc before csqc recieves a call from the server that it is to be removed (CSQC_Ent_Remove that is). Does CSQC_Ent_Remove still get called, or does it detect that the entity no longer exists? _________________
Look out for Twigboy

Back to top |

LordHavoc Joined: 05 Nov 2004 Posts: 243 Location: western Oregon, USA |

Posted: Thu Mar 27, 2008 9:23 am Post subject: |

Urre wrote:
What happens if a shared entity is removed in csqc before csqc recieves a call from the server that it is to be removed (CSQC_Ent_Remove that is). Does CSQC_Ent_Remove still get called, or does it detect that the entity no longer exists?

In all likelyhood 'bad things happen'
There's no real support for clientside termination of a subscription to entity updates in DarkPlaces, I'd recommend making the entity become 'dead' (by some definition) rather than removing it forcefully.
Perhaps Spike can chime in on how FTEQW handles this case.

Back to top |

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

Posted: Thu Mar 27, 2008 7:55 pm Post subject: |

yeah, bad things happen. even worse things happen after the 2-sec grace period. the whole point of a 'shared' entity is that its shared. if you're going to remove it client side then its not shared any more... The only case where I could think of that happening is with predicted rocket explosions (which are not the most reliable thing really).
CSQC_Ent_Remove is still called, yup. beyond the 2-secs grace it is still called... when the ent might be something else.
Worse is that CSQC_Ent_Update is also still called. At least in FTE.
You're expected to just leave it there in a non-solid state without a drawmask and stuff. Part of that is so that when the server next updates it it doesn't get recreated. The client cannot block updates to removed ents because it doesn't know how big the data is (it needs the csqc to parse entities to keep in sync with the server).
So yeah, if you really need to make it dead, you'll need to mark it as dead yourself. The client is not able to do it for you. Presumably just clear out the draw mask (the isnew parameter finally has a use!).
I accept that the client can't properly cope with remove()ing an ent while its still in use is ugly, but just recreating the entity if its updated again is worse.
It should warn, but I don't really want to loop through 5000 gibs. :P
_________________
What's a signature?

Back to top |

LordHavoc Joined: 05 Nov 2004 Posts: 243 Location: western Oregon, USA |

Posted: Thu Mar 27, 2008 10:41 pm Post subject: |

Spike wrote:
yeah, bad things happen. even worse things happen after the 2-sec grace period.

Clearly remove should warn and do nothing on a shared ent.

Back to top |

Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Fri Mar 28, 2008 3:00 pm Post subject: |

Ugh. Shared ents are a pain. Somehow I get the feeling it might be possible to design this differently... _________________ Look out for Twigboy

Back to top |

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

Posted: Fri Mar 28, 2008 4:59 pm Post subject: |

shared entity is perhaps not the best name... replicated entity seems more apropriate somehow. The server is meant to stay in overall control of everything. These entities then are either one-time events that trigger when they appear on the client (isnew == true), or actual entities that move around.
'Events' need to be left spawned, and removed when the client says to do so, as a means to cover any packet loss/resends. This can be done fairly genericly. Use the initial update to spawn any other ents you want and remove the parent as soon as asked. That's the easiest way.
Actual entities will rarely be removed clientside first. In the case of a rocket explosion, you ought to remember where it exploded to be able to adjust prediction properly anyway (although my own code never got to this stage, it is perhaps the biggest advantage of csqc in id-like deathmatch mods).
Entities duplicated in csqc are really no different from entities that could be obtained from the deltaing in the engine (except that you have to do interpolation yourself). The big advantage is that you can do interpolation yourself, instead of having the engine resend every single detail that changed every single packet.
Its more complicated, this makes it a pain by definition. :P
But I admit that making your own interpolation code is a major pain though.
_________________
What's a signature?

Back to top |

Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Fri Mar 28, 2008 5:37 pm Post subject: |

Well, I'm doing something significantly more complicated than that. I'm working on an RTS, and all my units are shared entities. All actions can be done in both versions (ssqc and csqc), and server sends updates of all important fields to csqc to make sure they match, in case something might get out of sync. There are major networking optimizations to be made here. The only times updates are sent, is in the case of new events. This includes enemy update (new enemy spotted, or enemy dead), order update (we are going to move over here), and something else I've forgotten right now. All movement and shooting and everything happens without any networking.
_________________
Look out for Twigboy

Back to top |

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

Posted: Tue Apr 01, 2008 11:37 am Post subject: |

This nearly reminds me of Total Annihilation. For the uninitiated, Total Annihilation is a peer-to-peer real-time strategy game. Basically, each client runs the units belonging to the local player, with the other clients seeing copies of those units. There's some sort of interpolation in there too, to keep it smooth.
The effects of lag in this game proves to be fairly interesting. Other people's units that are killed by you linger after death until your client has told the other player's client that you just hit them for X damage, and for their client to tell yours that they've actually died. Until that response, their unit will continue moving around shooting at stuff.
In your mod's case, the server ultimately controls all units, preventing any manipulation by lag (aka: invincible units).
Your mod is still a pure client/server architecture. The server owns all units. If a unit is destroyed by another unit ('enemy dead'), then the server will be removing the unit shortly anyway. Entities required for 'Shooting and everything' are never known by the server, so can be removed freely.
If the 'unit dead' event is the same unit, but morphed, you can spawn an explosion where the unit died. On the plus side, you can extend the remove/spawn grace period. :)
So, if a unit is killed locally, set its health to 0 and wait for the server to kill it properly. This is safest when it comes to prediction inaccuracies anyway, and may prevent inaccuracies from building up further.
_________________
What's a signature?

Back to top |

Urre Joined: 05 Nov 2004 Posts: 1073 Location: Sweden |

Posted: Tue Apr 01, 2008 1:46 pm Post subject: |

Aye, will do. Not sure wether I'll spawn the explosion at its current origin, or the actual one. If I do it at the actual origin, it makes more sense to the player, knowing that unit was out of sync, rather than "ah, spontaneous unit explosions. makes sense."
_________________
Look out for Twigboy

Back to top |

LordHavoc Joined: 05 Nov 2004 Posts: 243 Location: western Oregon, USA |

Posted: Fri Jul 18, 2008 6:29 am Post subject: |

I believe Total Annihilation actually ran the units on all peers simultaneously, and units only took damage from projectiles that hit them in their owner's simulation, meaning a peer could say a unit now exists, and could say a unit exploded, but could not do anything else, and someone else might damage their own units when that message is received for example (if within radius).
I do remember its handling of resyncs being rather bruteforce - basically every peer was continuously sending entity updates to all other peers, whether they thought they needed them or not, this caused units to teleport to other locations, some units every second (it was clearly a cyclic process), so it gradually fixed desyncs.
I also remember that the units only began shooting if their owner's simulation knew about the targets being close enough.
It was pretty strange playing in a very lagged game.

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