Slow engine updates giving script problems
by Petter Holmberg · in Torque Game Engine · 09/07/2005 (10:25 am) · 6 replies
Is there a way to halt the script interpretation while waiting for the graphics to refresh? I have problems related to scaling static shapes from script, using the setScale() method. Some static shapes are quite complex and there is a visible delay between the time the instruction is called and when the shape is actually visible at the new scale. During this time things are interpreted in the script that are dependant on the shapes already having been re-scaled, but this is not the case during this delay. I really don't want to put a constant-time delay there and hope for the best. I want either a callback or a function call that halts script interpretation until the engine has updated the graphics. Is there such a feature in the engine already?
#2
It should be added that the update delay appears to be related to the complexity of the static shape. As an example, I have a really big and complex static shape that I scale up, and a small, much simpler one that I scale up later. I can however see the small shape before the big shape being scaled up.
To tell you the truth, I'm not dependant on the scaling function if it gives a problem that is tricky to solve. What I really need is a way to toggle static shapes between visible and invisible. Scaling them to "0 0 0" will work in that sense, and has positive effects on the framerate too, but if there is a smarter way to do it, possibly without the problem I've described here, I would like to try that instead.
09/09/2005 (2:08 am)
Thanks for the reply! It's indeed odd. I'm not doing something over a network, and I know that the execution flow of the script is ok. I am scaling a small number of static shapes sequentially in the program, but it's only one call after another, happening once. Interestingly, in the situation when I see the scaling delay I first scale the static shapes from "0 0 0" to "1 1 1". Then I change the camera view to see the area where the shapes are. Then I change the transform of an AIPlayer to appear in view. These things are done in that order. (In case you're wondering, the camera handling has been modified in the game, so it's not dependant on the player position here.) But when I run this code, I will actually see on screen the new camera view with the AIPlayer correctly moved first. Then after some fraction of a second, I see a static shape popping into view, and some other is appearing later, with a visible delay. It's quite fast, but the delay and out-of-order updating of the graphics is unmistakable! The graphics not updated in script order. And again, I have verified that the script runs in the order I believe it runs. Actually, I'm not worried too much about the order, but I need to know when the uptates are completed.It should be added that the update delay appears to be related to the complexity of the static shape. As an example, I have a really big and complex static shape that I scale up, and a small, much simpler one that I scale up later. I can however see the small shape before the big shape being scaled up.
To tell you the truth, I'm not dependant on the scaling function if it gives a problem that is tricky to solve. What I really need is a way to toggle static shapes between visible and invisible. Scaling them to "0 0 0" will work in that sense, and has positive effects on the framerate too, but if there is a smarter way to do it, possibly without the problem I've described here, I would like to try that instead.
#3
First thing you may want to take a look at is ShapeBase::setHidden(). The purpose of this function is to change the visibility of the objects w/o having to scale them. It works pretty well but you will see a slight delay on it b/c it is happening over the "network" even in singleplayer/local situations (Torque's singleplayer is still a server with a local client attached to it). You can combat this delay a bit by changing $pref::Net::PacketSize to 450 (only for singleplayer games). If this is fast enough then you are good to go =)
If not then you are going to have to make some C++ changes to get this working the way you want (buy a license and start a thread in the Private forum and I will share the code =).
09/09/2005 (7:02 pm)
Funny, I literally just solved this problem for one of our projects =)First thing you may want to take a look at is ShapeBase::setHidden(). The purpose of this function is to change the visibility of the objects w/o having to scale them. It works pretty well but you will see a slight delay on it b/c it is happening over the "network" even in singleplayer/local situations (Torque's singleplayer is still a server with a local client attached to it). You can combat this delay a bit by changing $pref::Net::PacketSize to 450 (only for singleplayer games). If this is fast enough then you are good to go =)
If not then you are going to have to make some C++ changes to get this working the way you want (buy a license and start a thread in the Private forum and I will share the code =).
#4
09/12/2005 (9:26 am)
Thanks for the post, Matt! Although the packet size change had seemingly no effect at all, the server/client delay is definitely the culprit here. I tried replacing my setScale calls with commandToClient(setScale, ...) calls and suddenly the delay was gone! It would be interesting to learn why this works though.
#5
09/12/2005 (2:30 pm)
You may want to make sure you call setScale on the server and the client...otherwise you could get weird collision discrepencies.
#6
I'm beginning to think that some problems related to walking AIPlayers are related to the server/client updates too. Besides for the spinning problem which I've mentioned in another problem, I want to be able to teleport a walking AIPlayer to a precise position, but if you change its transform directly when he arrives at the point that triggers this, there's still some movement going on after changing the position, even if you expressively call its stop() method first. This is with a setMoveDestination with no slowdown though, so it's possible it's just Torque's walking code that won't allow it.
Generally though, since this is exclusively a single-player game I'm working on, this spiffy network handling stuff has unfortunately only introduced these kinds of little problems for me. :)
09/12/2005 (2:59 pm)
So, you say I should call both setScale and commandToClient(setScale, ...) for all shapes? So far I have had no troubles because the test shapes have no collision meshes in them, but that is not the case with all the shapes I'm going to scale, so this sounds relevant.I'm beginning to think that some problems related to walking AIPlayers are related to the server/client updates too. Besides for the spinning problem which I've mentioned in another problem, I want to be able to teleport a walking AIPlayer to a precise position, but if you change its transform directly when he arrives at the point that triggers this, there's still some movement going on after changing the position, even if you expressively call its stop() method first. This is with a setMoveDestination with no slowdown though, so it's possible it's just Torque's walking code that won't allow it.
Generally though, since this is exclusively a single-player game I'm working on, this spiffy network handling stuff has unfortunately only introduced these kinds of little problems for me. :)
Associate Matt Fairfax
PopCap
Something odd is going on here. Calling setScale() simply updates a single VectorF (which is used in a glScalef call) and then sends the update across the network. It doesn't effect any actual geometry so having more verts/triangles won't make it any slower. This should be the same speed for *every* object.
Perhaps you are calling it more often than you should be (a bad loop somewhere) or calling it for a bunch of objects at the same time? You might need to trace through your logic a bit closer and make sure nothing is going wrong there.
So you have something on the client side that is dependent on the scale changing? This could be tough to fix since no matter how "fast" the scaling operation takes it is isn't ever going to make it to the client faster than "time to next tick" + "client latency" so on a bad internet connection you are going to be waiting several hunred milliseconds for the scaling to reach the client.