T3D torquescript performance
by Justin Knight · in Torque 3D Professional · 01/18/2010 (7:46 am) · 9 replies
I have a simple ai to fly a flock of birds around and I'm getting very jerky performance. I get 30 fps, but the bird's positions are not being updated smoothly. You can see a short video clip here:
http://www.youtube.com/watch?v=75U3zWJoJF8
My system is currently Vista 64, Intel Quad Core Q6600, GeForce GTX 260, 1GB RAM.
I initially tried using setVelocity rather than manually changing the position information but that didn't seem to have any effect. I guess setVelocity doesn't work on StaticShape?
I've made the update interval as long as I think I can make it (100ms).
Is torquescript just inefficient and I should rewrite in C++, or is there a way I can make this more efficient?
Are there any profiling tools available which can help find performance bottlenecks?
Here's my code:-
http://www.youtube.com/watch?v=75U3zWJoJF8
My system is currently Vista 64, Intel Quad Core Q6600, GeForce GTX 260, 1GB RAM.
I initially tried using setVelocity rather than manually changing the position information but that didn't seem to have any effect. I guess setVelocity doesn't work on StaticShape?
I've made the update interval as long as I think I can make it (100ms).
Is torquescript just inefficient and I should rewrite in C++, or is there a way I can make this more efficient?
Are there any profiling tools available which can help find performance bottlenecks?
Here's my code:-
// Bird AI
// @TODO prevent going out of bounds
$state = 0; // 1=fly 2=circle
$updateIntervalMS = 100; // How often to update position in ms
$flapping = true;
$flyDelta = 0.4;
$angleDelta = 0.0;
$flockSpacing = 2.5;
$flockSize = 9;
function startAI( %bird) {
$flock[0] = %bird;
spawnFlock();
updateFlock();
for( %i=0; %i<$flockSize; %i++)
$flock[%i].playThread( 0, "ambient");
decideState(); // Decide initial state.
scheduleFlap();
}
function spawnFlock() {
for( %i=1; %i<$flockSize; %i++) {
$flock[%i] = new StaticShape() {
dataBlock = "BirdDB";
position = "0 0 0";
rotation = "0 0 1 0";
scale = "1 1 1";
};
MissionCleanup.add( $flock[%i]);
}
}
// Decide what to do next
function decideState() {
//$state = getRandom( 1, 2);
// Just fly forwards for now
$state = 1;
// Initialise chosen state.
switch( $state) {
case 1: // Fly
// nothing to initialise
case 2: // Circle
$angleDelta = getRandom( 1, 7) / 1000.0;
}
// Schedule first update
scheduleNext();
// Schedule next decision
%decisionInterval = getRandom( 5000, 20000);
schedule( %decisionInterval,0, decideState);
}
function scheduleFlap() {
if( isObject($flock[0])) {
$flapping = ! $flapping;
if( $flapping) {
for( %i=0; %i<$flockSize; %i++)
$flock[%i].playThread( 0, "ambient");
%flapInterval = getRandom( 5000, 20000);
} else {
for( %i=0; %i<$flockSize; %i++)
$flock[%i].stopThread( 0);
%flapInterval = getRandom( 1000, 2000);
}
schedule( %flapInterval, 0, scheduleFlap);
}
}
function scheduleNext() {
if( isObject($flock[0])) {
switch( $state) {
case 1:
schedule( $updateIntervalMS,0, updateBirdFly);
case 2:
schedule( $updateIntervalMS,0, updateBirdCircle);
}
}
}
function isOdd( %i) {
return( (%i % 2)!=0);
}
// Update flock position relative to lead bird
function updateFlock() {
%forward = $flock[0].getForwardVector();
%forward = VectorScale( %forward, $flockSpacing);
%left = (-%forward.Y) SPC %forward.X SPC 0;
%right = %forward.Y SPC (-%forward.X) SPC 0;
%pbird = $flock[0].getPosition();
for( %i=1; %i<$flockSize; %i++) {
if( isOdd(%i)) {
%scale = $flockSpacing * (%i+1.0) / 2.0;
%sideOffset = VectorScale( %left, %scale);
%backOffset = VectorScale( %forward, %scale);
} else {
%scale = $flockSpacing * %i / 2.0;
%sideOffset = VectorScale( %right, %scale);
%backOffset = VectorScale( %forward, %scale);
}
%position = VectorSub( %pbird, VectorAdd( %backOffset, %sideOffset));
%tBird = $flock[0].getTransform();
%transform = %position SPC getWord( %tBird, 3) SPC getWord( %tBird, 4) SPC getWord( %tBird, 5) SPC getWord( %tBird, 6);
$flock[%i].setTransform( %transform);
}
}
// Flying
function updateBirdFly() {
if( isObject($flock[0]) && $state==1) {
// Move forward by $flyDelta
for( %i=0; %i<$flockSize; %i++) {
%forward = $flock[%i].getForwardVector();
%tbird = $flock[%i].getTransform();
%tbird.X += %forward.X * $flyDelta;
%tbird.Y += %forward.Y * $flyDelta;
$flock[%i].setTransform( %tBird);
}
scheduleNext();
}
}About the author
#2
I have tackled a few glaring things for 1.1 Beta (like the tremendous amount of dynamic memory allocation the script evaluator used to perform) but given that TorqueScript's lifetime is probably slowly coming to a close, more significant overhauls will probably not be worth the investment.
//Offtopic:
I've also added two new statements to TorqueScript:
and
Aside from being convenient, they also perform better. Especially the string version is significantly faster in extracting strings than using getWord(%str,i).
01/18/2010 (8:54 am)
TorqueScript is indeed really slow. Been working some with the VM lately and from the viewpoint of performance, it is horribly written. Example: stack frames are full hashtables instead of arrays pre-layouted by the compiler.I have tackled a few glaring things for 1.1 Beta (like the tremendous amount of dynamic memory allocation the script evaluator used to perform) but given that TorqueScript's lifetime is probably slowly coming to a close, more significant overhauls will probably not be worth the investment.
//Offtopic:
I've also added two new statements to TorqueScript:
foreach( %obj in $MySimSet ) doSomethingWith( %obj );
and
foreach$( %str in "my string vector" ) doSomethingWith( %str );
Aside from being convenient, they also perform better. Especially the string version is significantly faster in extracting strings than using getWord(%str,i).
#3
??? Can you explain this a bit Rene?
01/18/2010 (10:54 am)
Quote: ...given that TorqueScript's lifetime is probably slowly coming to a close ...
??? Can you explain this a bit Rene?
#4
Just general observation. Everyone these days seems to be moving towards graphical scripting and just generally away from proprietary scripting languages and custom bytecode VMs.
01/18/2010 (10:59 am)
Just general observation. Everyone these days seems to be moving towards graphical scripting and just generally away from proprietary scripting languages and custom bytecode VMs.
#5
I agree and, beside the fact that what you learn in a language generally can be usefull when you start to learn another language, the possibility to reuse knowledge of a standard scripting language in many context is awesome... For example using knoledge of js achieved in web-dev for game-dev...
01/18/2010 (11:56 am)
Ok so never planned yet... :-)I agree and, beside the fact that what you learn in a language generally can be usefull when you start to learn another language, the possibility to reuse knowledge of a standard scripting language in many context is awesome... For example using knoledge of js achieved in web-dev for game-dev...
#6
01/18/2010 (12:02 pm)
I'd expect that most scripting languages have a fair bit in common (C style syntax). I actually chose to work with TGE because TorqueScript seemed like a less user-friendly version of Game Script Code that I'd become familiar with whilst modding CoD.
#7
Yep, they do. And personally, I like TorqueScript quite a bit. Mostly, it's pretty fun and easy to work with and architecture of Torque that goes with it is a great thing rather.
However, as with many engine components today, it often just doesn't make sense to not move over to dedicated middleware and utilize third-party tech. Specialized packages usually see a level of investment and development that is really hard to outmatch with custom built components. Plus justifying the development effort is difficult when there are other, often higher priority parts calling for attention.
But ok, enough of my dangerously close to off-topic musings here.
01/18/2010 (12:21 pm)
Yep, they do. And personally, I like TorqueScript quite a bit. Mostly, it's pretty fun and easy to work with and architecture of Torque that goes with it is a great thing rather.
However, as with many engine components today, it often just doesn't make sense to not move over to dedicated middleware and utilize third-party tech. Specialized packages usually see a level of investment and development that is really hard to outmatch with custom built components. Plus justifying the development effort is difficult when there are other, often higher priority parts calling for attention.
But ok, enough of my dangerously close to off-topic musings here.
#8
I've been where you are now. You can achieve what you wan by using the item class. They are perfect objects to use if you want a simple object(non-player,non-vehicle) which moves using setvelocity. Item class also has a cool property called "gravitymod" which if set to zero will disable gravity for the object creating a weightless, frictionless object.
IMO, the item class is the best most flexible object class in torque.
01/18/2010 (2:19 pm)
Justin-I've been where you are now. You can achieve what you wan by using the item class. They are perfect objects to use if you want a simple object(non-player,non-vehicle) which moves using setvelocity. Item class also has a cool property called "gravitymod" which if set to zero will disable gravity for the object creating a weightless, frictionless object.
IMO, the item class is the best most flexible object class in torque.
#9
Anything more complicated and I'd probably create my own Object Class to handle it.
@Rene: I've grown to like foreach from doing lots of php, that will be a nice addition.
01/19/2010 (7:50 am)
@Sean: Thanks the item class did indeed do the job. Anything more complicated and I'd probably create my own Object Class to handle it.
@Rene: I've grown to like foreach from doing lots of php, that will be a nice addition.
Torque Owner Justin Knight
TCE