Running out of object id numbers
by Lee Latham · in Torque Game Engine · 02/12/2008 (2:00 pm) · 35 replies
Okay, this is kinda embarassing but here goes:
Is it possible to run out of object id numbers? I'm not even sure if I have the right terminology. What is the right term for those on the server side?
Reason I ask is I'm running into issues when I have my dedicated server up for a long time. I have some items, like a jetpack that generates a LOT of particles, each with their own unique id number, that go through those pretty darn fast.
So I'm wondering if there is a limit, say a 32 bit float or something, that I could be hitting that could be causing a crash? Is there a way to "reset" this?
Or am I just chasing phantoms?
Is it possible to run out of object id numbers? I'm not even sure if I have the right terminology. What is the right term for those on the server side?
Reason I ask is I'm running into issues when I have my dedicated server up for a long time. I have some items, like a jetpack that generates a LOT of particles, each with their own unique id number, that go through those pretty darn fast.
So I'm wondering if there is a limit, say a 32 bit float or something, that I could be hitting that could be causing a crash? Is there a way to "reset" this?
Or am I just chasing phantoms?
#2
it's maybe unlikely.
i know empirically can handle simIDs up to at least 32,413,474.
If you think it's happening tho, you might consider putting in an error print into SimObject::registerObject():
02/12/2008 (2:53 pm)
Lee,it's maybe unlikely.
i know empirically can handle simIDs up to at least 32,413,474.
If you think it's happening tho, you might consider putting in an error print into SimObject::registerObject():
bool SimObject::registerObject()
{
mFlags.clear(Deleted | Removed);
if(!mId)
{
SimObjectId soid = Sim::gNextObjectId;
mId = Sim::gNextObjectId++;
if (Sim::gNextObjectId < soid)
{
Con::errorf("AWOOOGA AWOOOGA. Wrapped SimObjectID Space! %d -> %d", soid, Sim::gNextObjectId);
}
}
Sim::gIdDictionary->insert(this);
Sim::gNameDictionary->insert(this);
// Notify object
bool ret = onAdd();
if(!ret)
unregisterObject();
AssertFatal(!ret || isProperlyAdded(), "Object did not call SimObject::onAdd()");
return ret;
}
#3
@Stefan: I am intrigued by this idea. I'm a little unclear about how one would go about doing it client side, but I'm wondering if I could since this is a network game, and I need the other clients to be able to see the jetpack trails from each other?
I have been long annoyed by the idea that all those particles are using up network bandwidth.
@Orion: Thanks for that! You know I can't code so I appreciate the effort. I'll try it out if it continues to be a problem. I'm thinking that my issues may have just been script related. I've been cleaning up my console spam, and lo and behold, it was more than just an annoyance--there were actual problems and crashes happening because of functions being called with destroyed object and client id's.
Anyway, since I made the post I fixed one more issue and now the dedicated server is making it through the level rotation without crashing, so maybe that's all it was. For what it's worth, the simID's are up to the 100,000's without any problems, so I imagine you're right.
So, okay, this is a slightly off the subject but let me ask you guys--is there an elegant way of testing a supposed clientid to see if it's legit or not? That is, I delete AI clients whenever they die (and create new ones if I respawn them), but I was getting console spam from functions being called with those client id's that was causing crashes.
The only way I could figure out to test to see if it was valid was to test one of it's members, a la:
if (%client.armor !$= "Light")
return;
Which I think you'll agree is really, really lame.
02/12/2008 (4:33 pm)
Wow, thanks y'all. You've given me a lot to work with. @Stefan: I am intrigued by this idea. I'm a little unclear about how one would go about doing it client side, but I'm wondering if I could since this is a network game, and I need the other clients to be able to see the jetpack trails from each other?
I have been long annoyed by the idea that all those particles are using up network bandwidth.
@Orion: Thanks for that! You know I can't code so I appreciate the effort. I'll try it out if it continues to be a problem. I'm thinking that my issues may have just been script related. I've been cleaning up my console spam, and lo and behold, it was more than just an annoyance--there were actual problems and crashes happening because of functions being called with destroyed object and client id's.
Anyway, since I made the post I fixed one more issue and now the dedicated server is making it through the level rotation without crashing, so maybe that's all it was. For what it's worth, the simID's are up to the 100,000's without any problems, so I imagine you're right.
So, okay, this is a slightly off the subject but let me ask you guys--is there an elegant way of testing a supposed clientid to see if it's legit or not? That is, I delete AI clients whenever they die (and create new ones if I respawn them), but I was getting console spam from functions being called with those client id's that was causing crashes.
The only way I could figure out to test to see if it was valid was to test one of it's members, a la:
if (%client.armor !$= "Light")
return;
Which I think you'll agree is really, really lame.
#4
Orion's "you've gone over the line!" error test is awesome as well, but unless you are talking weeks of up time with quite a bit of constant 24/7 play, I honestly doubt you're pushing the objectID count limit--32 million is pretty huge ;)
What made you start thinking in this direction? If it's the warnings you get in the console, it's most probably something different from what you originally thought. It is possible you have some memory leaks that build up over time, but a quick check of executable memory size (see how many MB the running application is using) should point that out quickly.
02/12/2008 (7:36 pm)
As Stefan suggested, particles themselves are client side only--they are never networked.Orion's "you've gone over the line!" error test is awesome as well, but unless you are talking weeks of up time with quite a bit of constant 24/7 play, I honestly doubt you're pushing the objectID count limit--32 million is pretty huge ;)
What made you start thinking in this direction? If it's the warnings you get in the console, it's most probably something different from what you originally thought. It is possible you have some memory leaks that build up over time, but a quick check of executable memory size (see how many MB the running application is using) should point that out quickly.
#5
Hi Stephen. Well that is news to me! Actually, I'm quite pleased to hear that. So I guess the server just kinda sends off the particle emitter "on" command to all the clients, and each client manages the actual particles themselves?
This client/server stuff still blows my mind sometimes--I just discover it when something doesn't work right when networked.
I started thinking along this line when I noticed that my server crashing seemed to be a function of time, and indeed it wasn't using more memory--so I started looking for other possibilities. Usually my instincts are pretty good, but sometimes they're just not, and I'm convinced now that this is one of those times :-)
I'm pretty sure it's my scripting that's the problem now, and in fact now it's crashing without error messages in the console after several hours now. I'm reasonably confident it's something happening with the AI, doing something I hadn't planned, and crashing the engine offhand before it even has a chance to give me an error.
So...I guess I kinda wasted y'alls time sorta...sorry...but I do understand better now, so thanks anyway! This question has been bugging me in the back of my mind for a long time now.
02/12/2008 (9:12 pm)
As Stefan suggested, particles themselves are client side only--they are never networked.Hi Stephen. Well that is news to me! Actually, I'm quite pleased to hear that. So I guess the server just kinda sends off the particle emitter "on" command to all the clients, and each client manages the actual particles themselves?
This client/server stuff still blows my mind sometimes--I just discover it when something doesn't work right when networked.
I started thinking along this line when I noticed that my server crashing seemed to be a function of time, and indeed it wasn't using more memory--so I started looking for other possibilities. Usually my instincts are pretty good, but sometimes they're just not, and I'm convinced now that this is one of those times :-)
I'm pretty sure it's my scripting that's the problem now, and in fact now it's crashing without error messages in the console after several hours now. I'm reasonably confident it's something happening with the AI, doing something I hadn't planned, and crashing the engine offhand before it even has a chance to give me an error.
So...I guess I kinda wasted y'alls time sorta...sorry...but I do understand better now, so thanks anyway! This question has been bugging me in the back of my mind for a long time now.
#6
Think about it this way. Each client is already aware of the jetpack, why would you then also want them to be "aware" (networking-wise of course) of the particle emitter? Since the particle emitter follows the jetpack around, you can do it all client side.
Look, you got quite a few examples in the source on how to accomplish this. FlyingVehicle has JetNoozles, Player has SplashParticles and FootPuffs, ShapeImage has it's own system and Explosions has it as well.
Basically, just add the emitter (which is defined in your datablock, of the Player/Jetpack whatever) when the datablock has been loaded or when the object is added (look at the example classes) and make sure it stays at whatever node you tell it to stay at. Don't forget to delete it when the jetpack is deleted.
Doing this in script pretty much forces you into the server, since there's no smart way (but it can be done) to spawn objects on the client. Trust me, if you spend a few hours looking at the JetNoozle code and how they "mount" emitters to nodes, you'll be so happy you got it afterwards. Don't be afraid to rip it out and test it seperatly.
02/13/2008 (2:41 am)
Quote:
@Stefan: I am intrigued by this idea. I'm a little unclear about how one would go about doing it client side, but I'm wondering if I could since this is a network game, and I need the other clients to be able to see the jetpack trails from each other?
Think about it this way. Each client is already aware of the jetpack, why would you then also want them to be "aware" (networking-wise of course) of the particle emitter? Since the particle emitter follows the jetpack around, you can do it all client side.
Look, you got quite a few examples in the source on how to accomplish this. FlyingVehicle has JetNoozles, Player has SplashParticles and FootPuffs, ShapeImage has it's own system and Explosions has it as well.
Basically, just add the emitter (which is defined in your datablock, of the Player/Jetpack whatever) when the datablock has been loaded or when the object is added (look at the example classes) and make sure it stays at whatever node you tell it to stay at. Don't forget to delete it when the jetpack is deleted.
Doing this in script pretty much forces you into the server, since there's no smart way (but it can be done) to spawn objects on the client. Trust me, if you spend a few hours looking at the JetNoozle code and how they "mount" emitters to nodes, you'll be so happy you got it afterwards. Don't be afraid to rip it out and test it seperatly.
#7
Although I think Stephen Zepp was correct that by default the particles are done on the client side. For kicks I checked and the jetpack particles do not increase the SimID count on the server :-)
02/13/2008 (11:56 am)
Thanks Stefan, I think you've pointed me in the right direction.Although I think Stephen Zepp was correct that by default the particles are done on the client side. For kicks I checked and the jetpack particles do not increase the SimID count on the server :-)
#8
02/13/2008 (12:20 pm)
This is nice to know for those Virtual Galaxy games that will start coming out soon to avoid GG licensing queries! ;)
#9
Particles yes but not nessecarily (sp?) their emitters. Those are server side if you create them from TorqueScript. They are also server side if you have them in your mission, so it's not as simple as to say it's default since so many use TorqueScript.
Good thing you didn't though :)
Edit: Good thing you didn't create them from there, that is :P
02/13/2008 (1:06 pm)
Quote:
Although I think Stephen Zepp was correct that by default the particles are done on the client side. For kicks I checked and the jetpack particles do not increase the SimID count on the server :-)
Particles yes but not nessecarily (sp?) their emitters. Those are server side if you create them from TorqueScript. They are also server side if you have them in your mission, so it's not as simple as to say it's default since so many use TorqueScript.
Good thing you didn't though :)
Edit: Good thing you didn't create them from there, that is :P
#10
At least I think I created it all in script. I used the Mounted Particle Emitter resource, so I presume that would count as "created in script".
02/13/2008 (2:25 pm)
Hmmm, well, I did, actually. But is that such a big deal? Are we talking about total supremo computer geek efficiency or a seriously waste of resources?At least I think I created it all in script. I used the Mounted Particle Emitter resource, so I presume that would count as "created in script".
#11
And as long as it doesn't show up as a problem on your end or when profiling, I wouldn't worry about it. But it's good to keep it clean from the start to avoid rewrites later.
02/13/2008 (5:41 pm)
I don't know what that resource adds, so it could be either.And as long as it doesn't show up as a problem on your end or when profiling, I wouldn't worry about it. But it's good to keep it clean from the start to avoid rewrites later.
#12
I start getting a bunch of these after almost exactly 24 hours:
Ok, so I scroll back a bit and I see this starts happening at the beginning of a new mission load, and I'll show you the transition:
At the top you can see the consolespam which I have since gotten rid of. Then I kick all the AI clients and cycle the game. Then the mission loads, the new AI clients are added, and it seems to be interpreting the simID's as exponents! Is that weird or what?
What on earth could I have done to those poor simID's? It starts doing this with every single function call (not just setimagetrigger).
Wow. Any thoughts would be greatly appreciated.
02/14/2008 (12:55 am)
Actually, what do y'all think of this (I've copied this from another thread since it suddenly seems relevant to this one:I start getting a bunch of these after almost exactly 24 hours:
singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00021e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00024e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00023e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00022e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00023e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00021e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00024e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00023e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00022e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00023e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00021e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00024e+006' attempting to call function 'setImageTrigger'
Ok, so I scroll back a bit and I see this starts happening at the beginning of a new mission load, and I'll show you the transition:
singularity/server/scripts/car.cs (1247): Unable to find object: '' attempting to call function 'isAIControlled' singularity/server/scripts/car.cs (1247): Unable to find object: '' attempting to call function 'isAIControlled' singularity/server/scripts/car.cs (1127): Unable to find object: '' attempting to call function 'getId' <input> (0): Unable to find object: '' attempting to call function 'getId' singularity/server/scripts/player.cs (865): Unable to find object: '' attempting to call function 'setControlObject' CDROP: 924382 ai:local CDROP: 954775 ai:local CDROP: 969913 ai:local CDROP: 969929 ai:local CDROP: 985419 ai:local CDROP: 985426 ai:local CDROP: 985434 ai:local CDROP: 985440 ai:local CDROP: 985449 ai:local Sending heartbeat to master server [IP:208.109.238.41:28002] singularity/server/scripts/game.cs (185): Unable to find object: 'AIManager' attempting to call function 'delete' *** MISSION RESET *** ENDING MISSION *** LOADING MISSION: singularity/data/missions/terrarium.mis *** Stage 1 load *** Stage 2 load Executing singularity/data/missions/terrarium.mis. *** Mission loaded CADD: 1000188 ai:local CADD: 1000191 ai:local CADD: 1000196 ai:local CADD: 1000199 ai:local CADD: 1000202 ai:local CADD: 1000205 ai:local CADD: 1000208 ai:local CADD: 1000211 ai:local singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00021e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00024e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/player.cs (865): Unable to find object: '' attempting to call function 'setControlObject' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00022e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00023e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00021e+006' attempting to call function 'setImageTrigger' singularity/server/scripts/aiPlayer.cs (596): Unable to find object: '1.00024e+006' attempting to call function 'setImageTrigger'
At the top you can see the consolespam which I have since gotten rid of. Then I kick all the AI clients and cycle the game. Then the mission loads, the new AI clients are added, and it seems to be interpreting the simID's as exponents! Is that weird or what?
What on earth could I have done to those poor simID's? It starts doing this with every single function call (not just setimagetrigger).
Wow. Any thoughts would be greatly appreciated.
#13
02/15/2008 (3:41 pm)
Anybody know of a posted fix somewhere for simID numbers above one million going to exponents?
#15
Have I mentioned that you're a stud? :-)
02/15/2008 (4:02 pm)
Thanks! I've been searching and searching the forums, but it's a hard thing to search for.Have I mentioned that you're a stud? :-)
#16
Kinda surprised this is still happening in TGE 1.5.2 tho...
02/15/2008 (4:33 pm)
Gah, too much has changed or something. For the heck of it, I replaced all %g with %9g with no luck. Which I guess is what happens when you don't really understand what you're doing :-)Kinda surprised this is still happening in TGE 1.5.2 tho...
#17
Looks more like you're trying to call setImageTrigger on an uninitialized "pointer". What does aiPlayer.cs look like around line 596? Find the offending "pointer" variable and trace it back. Where is it set? That's where I would start looking.
02/15/2008 (6:45 pm)
I rather doubt your actually hitting the ceiling on your SimIDs. Someone correct me if my math is wrong but with an unsigned 32bit integer ID, even if you created 100 new objects a second it should be over a year before you run out of IDs. I suspect your problem actually lies elsewhere, and the fact that the trouble starts on a mission change supports that supposition. Looks more like you're trying to call setImageTrigger on an uninitialized "pointer". What does aiPlayer.cs look like around line 596? Find the offending "pointer" variable and trace it back. Where is it set? That's where I would start looking.
#18
This is something that happens after the server has been up about 24 hours, in my game.
02/15/2008 (6:48 pm)
No, I'm pretty sure it's because the simID's are above a million. There is a known issue with this as per Orion's links above, where Torque interprets numbers above 1 million as exponents.This is something that happens after the server has been up about 24 hours, in my game.
#19
02/15/2008 (7:15 pm)
Yes, when you start doing maths in Script. But you can still$bigvalue = 2123123123; echo($bigvalue);and get 2123123123. So unless you're doing maths with your "pointer" variables, it shouldn't be a problem. Unless this is different since I split off at v1.3.
#20
It looks like somewhere they're getting converted to strings and then back again.
Edit: Seeing as how I don't need to do math with those numbers, where in the source is specifically the conversion from/to text in script?
02/15/2008 (7:28 pm)
Well, this is in the assigned simID numbers. All of a sudden my scripts start going haywire when they hit one mil. See the log snippet pasted above on Feb 14, 2008 02:55 .It looks like somewhere they're getting converted to strings and then back again.
Edit: Seeing as how I don't need to do math with those numbers, where in the source is specifically the conversion from/to text in script?
Torque Owner Stefan Lundmark
1. Of course you can use up all Ghost ID's if you have enough objects in the simulation at once.
2. You should however be able to reuse old ID's that are no longer used. I'm not sure when this got in, or if it was in Tribes II. Someone might want to correct me there.
With that said, you're probably not looking at this the right way. Never ever do client side effects on the server. Save those for the client, it will be much smoother, easier for the server and in the end more scaleable - for you.
Create the particle emitter once (onAdd) and make sure it follows the jetpack around. When the jetpack is destroyed, destroy the emitter. You don't even need to ghost it which saves you bandwidth and ID's.