Game Development Community

My ghosts keep disappearing!

by Chris \"Hobbiticus\" Weiland · in Torque Game Engine · 01/15/2004 (12:38 pm) · 4 replies

This is quite possibly the strangest thing ever to happen to me besides the compilation error "Error: operator '=' illegal - cannot convert F32 to F32".

I'm coding/scripting up this gametype that is quite similar to PlanetSide in that there is a "lattice" of sorts with a bunch of links, and you can only capture objectives that you have a link to. Well, it all works perfectly...at least for the first map.

The strange part is that on the second map, NONE of the links get to the clients properly. This happens on both dedicated and non-dedicated server setups (join/host).

The way links work is that they are regular mission objects with 2 nodes. Each node is a plain old SceneObject*. The only thing that links work with right now are capture switches, which is just fine. So, on Switch::onAdd() in script, I set the switch to scopeAlways so that there will be a ghost on the client. Then, when a link is placed into the scene, it also sends which two objects it links, being 2 (should be) always scoped switches. I know this won't work if the link is created before the switches, but that is not the case in this situation.

However, when the links get sent to the client, the switches have been set to scopeAlways on the server, but the client doesn't seem to have a ghost for them. The first mission the client DOES have ghosts for them, however. It gets even stranger, when I force a packUpdate and voila!! The client suddenly has ghosts! I even tried scripting a scheduled forced packUpdate for 1-10 seconds, and it was a no-go. So a scripted packet send doesn't work, but a console-typed packet send does.

What the hell is going on here?

#1
01/15/2004 (3:59 pm)
I had good luck just retrying until the ghost system returned a valid ghost ID for the objects in question. It's unclear to me if that's what you tried here or not. My code is basically...

if(ghostId == -1)
{
   stream->writeFlag(false);
   retMask &= FlagWe_reAddresing;
}
else
{
   stream->writeFlag(true);
   stream->writeInt(ghostId);
}
#2
01/16/2004 (7:21 am)
There must be a more elegant solution than this though. Perhaps a callback in script when an object gets ghosted or something?
#3
01/16/2004 (8:23 am)
You wish. :)

Ghosts are dynamically added/removed and their IDs can change on the fly. I suppose you could add an onGhosted(%conn) callback to NetObjects but I've found that just spinning until the ghost occurs works pretty well.
#4
01/16/2004 (1:45 pm)
HA! I win!

Ok, best coding/scripting ever.

Before, ObjectiveLink's where set to scope always in the class constructor, and switches were plain old staticshapes. Well, I found a "ScopeAlwaysShape" class that inherits from StaticShape and just sets the object's net flags to ghostable and ghost always. GREAT! So I change all of my switches to ScopeAlwaysShape's, and still no luck. Ok, so I figure that the only way this would happen is if the links were getting scoped BEFORE the switches since they're both in the scope always group.

So, I set the ObjectiveLinks to just Ghostable (NOT scopeAlways) then in the gametype, when a client joins, it scopes all of the links to that client. This works because the scope always group gets sent before the onClientJoin callback, so then the links get scoped AFTER the switches. Not only that, I don't think it should matter if the links are defined before/after the switches anymore in the .mis file because they should be added to the scene after the switches!

BOOYA!