I’ve upgraded my project from NetCode 0.6 to 0.50 and now when I’m spawning the player’s Ghost I’m getting the warning
“Trying to predict a ghost without having a state to roll back to 0 / 998”
logging every frame.
Full Stack Trace.
Trying to predict a ghost without having a state to roll back to 0 / 998
UnityEngine.Debug:LogWarning (object)
Unity.NetCode.NetDebug:LogWarning (Unity.Collections.FixedString512Bytes&) (at Packages/com.unity.netcode/Runtime/NetDebug.cs:349)
Unity.NetCode.GhostUpdateSystem/UpdateJob:Execute (Unity.Entities.ArchetypeChunk,int,int) (at Packages/com.unity.netcode/Runtime/Snapshot/GhostUpdateSystem.cs:220)
Unity.Entities.JobChunkExtensions/JobChunkProducer1<Unity.NetCode.GhostUpdateSystem/UpdateJob>:ExecuteInternal (Unity.Entities.JobChunkExtensions/JobChunkWrapper1<Unity.NetCode.GhostUpdateSystem/UpdateJob>&,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int) (at Library/PackageCache/com.unity.entities@0.50.0-preview.24/Unity.Entities/IJobChunk.cs:401)
Unity.Entities.JobChunkExtensions/JobChunkProducer1<Unity.NetCode.GhostUpdateSystem/UpdateJob>:Execute (Unity.Entities.JobChunkExtensions/JobChunkWrapper1<Unity.NetCode.GhostUpdateSystem/UpdateJob>&,intptr,intptr,Unity.Jobs.LowLevel.Unsafe.JobRanges&,int) (at Library/PackageCache/com.unity.entities@0.50.0-preview.24/Unity.Entities/IJobChunk.cs:368)
I’m trying to look through how the Ghost snapshot data is being sent, but it’s not very clear what’s preventing the client from receiving the snapshot data.
I was wondering if anyone else has had the same issue and what the solution might be.
If it is happening every frame you should be able to find which ghost on the client has an empty snapshot buffer to see at least what kind of ghost it is and get some hints as to what is happening.
The most common cause for that error is spawning ghosts on the client without receiving them and without predictive spawning. So you should make sure the spawning code is not running on the client unless you preprocess the prefab to make a predicted spawn prefab (which would not make much sense for the player so I assume you’re not)
Yes! Thank you for your comment. It’s evening here atm, but I’ve just gone to check and I think you’re right. I’ll look again in the morning.
It looks like I have a nested prefab where I’m spawning a player on the server, then the player has an inventory which is also a ghost. It looks like it’s the inventory that’s got a SnapshotDataBuffer of length 0 in the client world.
I’m guessing this second ghost is getting created on the client because it’s nested. I’ll test by removing the child object and create a system to spawn and attach this second ghost via another method. Hacking out the player’s inventory the warning has gone away.
Indeed spawning the child ghost separately and re-connecting the entities at runtime worked. Bit strange that it was working in the earlier version of Netcode, but not much work to fix things back up again.
Nested ghosts at authoring time are not supported and we currently have no plan to support that. I am not quite sure exactly how it would work or why you need nested ghosts - can you describe what problem they would solve?
A ghost can already consist of multiple entities, all components marked with GhostField in the ghost will be sent together. If you need to reference one specific entity in the ghost you can usually use the root entity + a child index in the LinkedEntityGroup.
A ghost can be a GhostGroup, in which case you can dynamically associate other ghosts with it an make sure they are sent together. This is generally very expensive and not something you should do unless you really have to.
In my case I have a Ship and a Terminal (on the ship).
I have a piloting feature where I want to be able to switch on the auto command target for the Terminal to receive piloting commands while switching off the auto command target for the player, and vise-versa.
It’s no biggie, I can always have a reference to the Ship entity as a component on the Terminal and get the commands that way.
It also means I needed to make another way to identify things that would otherwise have a ghostId.
For example, my character can interact with the Terminal to start operating it, so it needs a way to ask the server “am I allowed to operate this terminal”, normally I could send the ghostId to tell it which Terminal I’m talking about but in this case my Terminal cant be a ghost so I need my own ID system to do this.
It sounds like I could achieve this using Ship ghostId + LinkedEntityGroup index, but I’m not sure how easy/robust a solution that is, especially with multiple levels of children.
It would be nice if the children of ghosts had some some unique ID to make lookup easier.
EDIT: I’ve since realized that auto command target only works on “owned ghosts” which voids my solution. I’m probably going to have to place a “terminal spawn point” on the ship ghost instead and spawn in game. It’s a bit of a crappy workflow to do manually but I could probably automate the creation of a spawn point with a conversion system… TBC
The following use case can currently be implemented (by spawning multiples and then linking them together) but it would be a lot more convenient if it would be supported out of the box:
Anytime I spawn a physics-based object which is linked with joints, I need to spawn every entity separately and build a specific system to link them together.
If I could spawn them directly linked and set up (like how I can prepare them in sub-scenes) it would be a lot more convenient.