Hey there friends 👋
first off, I'd like to mention that I've read the documentation twice now and I dug into the ECS samples for Netcode for Entities. But for someone new to Netcode for Entities it is still difficult to wrap my head around some of the concepts. In general, a more problem-oriented approach for the docs would be nice, e.g. "use this concept to solve these types of problems, and for these other types of problems do this instead". The code in the samples also lacks comments, making it difficult to figure out why certain design decisions were made, and whether they were necessary or a choice. I hope you consider this constructive criticism, as I've been trying to learn this framework for a couple weeks now and still feel like I barely understand the basic concepts. Every time I read the docs, I feel like half the stuff is new again 😅
That said, I have some concrete questions, I hope someone might be able to help me with.
-
The docs say one needs to use the GhostFieldAttribute in order to sync components on a Ghost entity. In the samples, this is for example used for the ServerHitMarker in the HelloNetcode HitScanWeapon sample. The ApplyHitMarkSystem of the same sample updates inside the PredictedSimulationSystemGroup and uses IsFirstTimeFullyPredictingTick to abort execution when rolling back. But I'm not entirely sure why or when this check is needed (see next question). And why even check for the first time a tick is predicted? What if the prediction is wrong? Then whatever executed can't be rolled back, right? So wouldn't it make more sense to check for the tick just before the first fully predicted tick? I think a diagram about the exact order of all the things happening in Netcode for Entites would go a long way for new people to better understand it.
-
What adds to my confusion is that in the Respawning sample, the Health component e.g. does not use any GhostFieldAttributes. On top of that, the DamageSystem (which also updates inside PredictedSimulationSystemGroup) does not check for IsFirstTimeFullyPredictingTick. So if checking IsFirstTimeFullyPredictingTick is required in PredictedSimulationSystemGroup to prevent things from executing too often during rollbacks, then why isn't that required for deducting Health as well? And how is it even synced to the client without the GhostFieldAttribute? How does it manage to be server authoritative in this case?
-
When do I need to work with NetworkTime and ticks and all that, and when can I just use SystemAPI.Time.DeltaTime?
-
One of the things I would like to do is make slight (client authoritative) adjustments to the LocalTransform of Ghosts in the client world. What would be the best way of doing that? Have a system run in the PresentationSystemGroup that changes the LocalTransform on those Ghosts?
.