The Millionth Monkey Gets Its Typewriter. - Page 3

The Millionth Monkey Gets Its Typewriter.

Discuss game development here, from a distinct game project to an accessible third-party mutator, down to the interaction and design of individual units if you like.

Moderator: Moderators

User avatar
Buggi
Posts: 875
Joined: 29 Apr 2005, 07:46

Post by Buggi »

How the heck did you script the tail to move like that? @_@!!

WOW!
User avatar
Snipawolf
Posts: 4357
Joined: 12 Dec 2005, 01:49

Post by Snipawolf »

I was commenting on the picture i saw...

XD this looks great, but I think its legs are too close...

Nice job indeed!!!
User avatar
Wolf-In-Exile
Posts: 497
Joined: 21 Nov 2005, 13:40

Post by Wolf-In-Exile »

Really awesome, especially the tail. :-)
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Um... zwzsg, with all due respect... I don't think that's a better way to do things. I will do some proofs when I get home... which will, I hope, convince everybody that what I am doing here is significantly better than the approach you've posed there.

But, for those of you who can't wait for a proof... do a simple logic problem... which takes longer to go through a stack... 100 commands, or 10 commands? Because, short of making loops that execute every frame, that's what it comes down to...
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

Can you explain more precisely what your radical improvment is?

First you asked other people to guess it, then you said you eliminated "turn now" (I don't understand that part, animation that are seen should never use now anyway), then you talk about synching and lockup (I don't understand that either, how multiplying the number of function running at once can be more synched than having a single function do all the walk animation), and when I look at the actual code I don't see where's the revolution. So please clear that up, and explain clearly what there is to see.
User avatar
Dragon45
Posts: 2883
Joined: 16 Aug 2004, 04:36

Post by Dragon45 »

zwzsg, that scorp anim brought a huge smile to my face. it just made me giddy :D
User avatar
KDR_11k
Game Developer
Posts: 8293
Joined: 25 Jun 2006, 08:44

Post by KDR_11k »

What I see first and foremost is that his approach has less repeating code so if e.g. you wanted each leg to have an additional keyframe you'd add one line instead of however many you have there.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

It decreases the nubmer of items on the stack allowing mroe to be put on, aka faster code, allowing more of the units to appear onscreen for less lag.

Simply put. Yours may do the job but his is both easier to use understand and ammend/code while being a heck of a lot more efficient for the cob virtual machine to execute.

Once I'd read Arghs script it was nice and I could start thinking about changes and additions. What you posted was an intimidating mass of text I just didnt want to read it in full and go over it a second time like I did with Arghs.

We all have our preferences though
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

KDR_11k wrote:What I see first and foremost is that his approach has less repeating code so if e.g. you wanted each leg to have an additional keyframe you'd add one line instead of however many you have there.
AF wrote:What you posted was an intimidating mass of text I just didnt want to read it in full and go over it a second time like I did with Arghs.
Maybe it was a bad idea to compare a unit with 8 legs totalling 32 degree of liberty with a unit with two legs totalling 4 degrees of liberty. And the macros I used made it easier to amend, but longer to read. Here's how I scripted a 2 legged unit:

Code: Select all

#define SIG_BUILD 32

#define WALK_FASTER 300
#define WALK_SLOWER 100


StartMoving()
	{
	signal SIG_MOVE;
	set-signal-mask SIG_MOVE;
	while(1)
		{
		turn jambd to x-axis <8> speed <8>*WALK_FASTER/WALK_SLOWER;
		turn tibd to x-axis <34> speed <34>*WALK_FASTER/WALK_SLOWER;
		turn jambg to x-axis <0> speed <26>*WALK_FASTER/WALK_SLOWER;
		turn tibg to x-axis <0> speed <34>*WALK_FASTER/WALK_SLOWER;
		sleep 1000*WALK_SLOWER/WALK_FASTER;
		turn jambd to x-axis <-52> speed <60>*WALK_FASTER/WALK_SLOWER;
		turn tibd to x-axis <68> speed <34>*WALK_FASTER/WALK_SLOWER;
		turn bassin to y-axis <20> speed <20>*WALK_FASTER/WALK_SLOWER;
		turn jambd to y-axis <-20> speed <20>*WALK_FASTER/WALK_SLOWER;
		turn jambg to y-axis <-20> speed <20>*WALK_FASTER/WALK_SLOWER;
		sleep 1000*WALK_SLOWER/WALK_FASTER;
		turn jambd to x-axis <0> speed <26>*WALK_FASTER/WALK_SLOWER;
		turn tibd to x-axis <0> speed <34>*WALK_FASTER/WALK_SLOWER;
		turn jambg to x-axis <8> speed <8>*WALK_FASTER/WALK_SLOWER;
		turn tibg to x-axis <34> speed <34>*WALK_FASTER/WALK_SLOWER;
		sleep 1000*WALK_SLOWER/WALK_FASTER;
		turn jambg to x-axis <-52> speed <60>*WALK_FASTER/WALK_SLOWER;
		turn tibg to x-axis <68> speed <34>*WALK_FASTER/WALK_SLOWER;
		turn bassin to y-axis <-20> speed <20>*WALK_FASTER/WALK_SLOWER;
		turn jambd to y-axis <20> speed <20>*WALK_FASTER/WALK_SLOWER;
		turn jambg to y-axis <20> speed <20>*WALK_FASTER/WALK_SLOWER;
		sleep 1000*WALK_SLOWER/WALK_FASTER;
		}
	}

StopMoving()
	{
	signal SIG_MOVE;
	turn jambd to x-axis <0> speed <90>*WALK_FASTER/WALK_SLOWER;
	turn tibd to x-axis <0> speed <90>*WALK_FASTER/WALK_SLOWER;
	turn jambg to x-axis <0> speed <90>*WALK_FASTER/WALK_SLOWER;
	turn tibg to x-axis <0> speed <90>*WALK_FASTER/WALK_SLOWER;
	turn bassin to y-axis <0> speed <50>*WALK_FASTER/WALK_SLOWER;
	turn jambd to y-axis <0> speed <50>*WALK_FASTER/WALK_SLOWER;
	turn jambg to y-axis <0> speed <50>*WALK_FASTER/WALK_SLOWER;
	}
Better to compare what's comparable.


AF wrote:It decreases the nubmer of items on the stack allowing mroe to be put on, aka faster code, allowing more of the units to appear onscreen for less lag. [...]being a heck of a lot more efficient for the cob virtual machine to execute.
I'm not sure what you call stack. But what I see is that with Arg's walkscript, you get eight function running at once just for the walk animation (MotionControl() , Go, MotionControl2() , Go2, MotionControl3() , Go3, MotionControl4() , Go4()), while for mine there is only one (StartMoving()). That means the cob machine has to run eight parrelel threads for each kbot. Well, if we assume that "call-script" is well optimised, the Go function would insert thmselves into each of the MotionControl, so you'll just have 4 threads. But that's still 4 threads to run in parallel for the COB virtual machine, it has to keep in the lines adresses of each, at each tick the COB virtual machine has to decrease 4 timers and check them, and so basically it's 4 times slower than having a single thread do the walk animation. Where's the efficiency gain, in multiplying the workload of the COB machine by 4? That can only bring more lag, what makes you say it could decrease lag? That I really don't get.

What I see first and foremost is that his approach has less repeating code so if e.g. you wanted each leg to have an additional keyframe you'd add one line instead of however many you have there.
In his method, each time he want one piece to be turned to a certain position, that's still one more line of codes, right? Has for the pause, he seem to have exactly as many as me but spread over more function, (so they are run in parallel instead of one after the other). And then he added all the complex mess of the MotionControl, which add lots of lines for nothing. Oh well, let's just count. My walkscript has four "phase" between four "pose", I'll assume his to since he roughly has the same number of turn. The two leg walkscript I posted has 44 lines. His code, when stripped of everything irrelevant to walkscript, is still 210 lines. For me 44<210. Btw here's what I kept to count his lines
static-var bMoving;
#define SIG_MOVE 1
Go()
{
// normal steps
if (bMoving)
{
// RightFront fronts
wait-for-turn rfbodyshaft around x-axis;
turn rfbodyshaft to x-axis <-50> speed <325>;
wait-for-turn rfbodyshaft around x-axis;
move rfpistonarm to y-axis [-0.3] speed [15];
turn rfbodyshaft to x-axis <0> speed <325>;
}
if (bMoving)
{
// RightFront backs
wait-for-turn rfbodyshaft around x-axis;
turn rfbodyshaft to x-axis <50> speed <325>;
move rfpistonarm to y-axis [0.4] speed [10];
wait-for-turn rfbodyshaft around x-axis;
turn rfbodyshaft to x-axis <0> speed <325>;
}
return 0;
}
Go2()
{
// normal steps
if (bMoving)
{
// RightBack backs
wait-for-turn rrbodyshaft around x-axis;
turn rrbodyshaft to x-axis <50> speed <325>;
move rrpistonarm to y-axis [0.4] speed [10];
wait-for-turn rrbodyshaft around x-axis;
turn rrbodyshaft to x-axis <0> speed <325>;
}
if (bMoving)
{
// RightBack fronts
wait-for-turn rrbodyshaft around x-axis;
turn rrbodyshaft to x-axis <-50> speed <325>;
wait-for-turn rrbodyshaft around x-axis;
move rrpistonarm to y-axis [-0.3] speed [15];
turn rrbodyshaft to x-axis <0> speed <325>;
}
return 0;
}
Go3()
{
// normal steps
if (bMoving)
{
// LeftBack fronts
wait-for-turn lrbodyshaft around x-axis;
turn lrbodyshaft to x-axis <-50> speed <325>;
wait-for-turn lrbodyshaft around x-axis;
move lrpistonarm to y-axis [-0.3] speed [15];
turn lrbodyshaft to x-axis <0> speed <325>;
}
if (bMoving)
{
// LeftBack backs
wait-for-turn lrbodyshaft around x-axis;
turn lrbodyshaft to x-axis <50> speed <325>;
move lrpistonarm to y-axis [0.4] speed [10];
wait-for-turn lrbodyshaft around x-axis;
turn lrbodyshaft to x-axis <0> speed <325>;
}
return 0;
}
Go4()
{
// normal steps
if (bMoving)
{
// LeftFront backs
wait-for-turn lfbodyshaft around x-axis;
turn lfbodyshaft to x-axis <50> speed <325>;
move lfpistonarm to y-axis [0.4] speed [10];
wait-for-turn lfbodyshaft around x-axis;
turn lfbodyshaft to x-axis <0> speed <325>;
}
if (bMoving)
{
// LeftFront fronts
wait-for-turn lfbodyshaft around x-axis;
turn lfbodyshaft to x-axis <-50> speed <325>;
wait-for-turn lfbodyshaft around x-axis;
move lfpistonarm to y-axis [-0.3] speed [15];
turn lfbodyshaft to x-axis <0> speed <325>;
}
return 0;
}
Stop()
// stop motion
{

sleep 200;

// RF and LR legs to start
turn rfbodyshaft to x-axis <0> now;
move rfpistonarm to y-axis [0] now;
turn lrbodyshaft to x-axis <10.2> now;
move lfpistonarm to y-axis [0] now;

sleep 100;

// RR and LF legs to start
turn rrbodyshaft to x-axis <10.2> now;
move rrpistonarm to y-axis [0] now;
turn lfbodyshaft to x-axis <0> now;
move lfpistonarm to y-axis [0] now;

sleep 100;

return 0;
}
MotionControl()
{ var moving,just_moved;
just_moved = 1;
WHILE ( TRUE )
{ moving = bMoving ;
IF (moving)
{
just_moved = 1;
call-script Go(bMoving);
}
IF (!moving)
{ IF (just_moved)
{ just_moved = 0;
call-script Stop();
}
SLEEP 50;
}
}
}
MotionControl2()
{ var moving,just_moved;
just_moved = 1;
WHILE ( TRUE )
{ moving = bMoving ;
IF (moving)
{
just_moved = 1;
call-script Go2();
}
IF (!moving)
{ IF (just_moved)
{
just_moved = 0;
}
SLEEP 100;
}
}
}
MotionControl3()
{ var moving,just_moved;
just_moved = 1;
WHILE ( TRUE )
{ moving = bMoving ;
IF (moving)
{
just_moved = 1;
call-script Go3();
}
IF (!moving)
{ IF (just_moved)
{
just_moved = 0;
}
SLEEP 100;
}
}
}
MotionControl4()
{ var moving,just_moved;
just_moved = 1;
WHILE ( TRUE )
{ moving = bMoving ;
IF (moving)
{
just_moved = 1;
call-script Go4();
}
IF (!moving)
{ IF (just_moved)
{
just_moved = 0;
}
SLEEP 100;
}
}
}
start-script MotionControl();// In Create() but I don't count the "Create()" line as it has to be there anyway
start-script MotionControl2();
start-script MotionControl3();
start-script MotionControl4();
bMoving = 0;// In Create() but I don't count the "}" line as it has to be there anyway
StartMoving()
{
bMoving = 1;
return 0;
}
StopMoving()
{
bMoving = 0;
return 0;
}
Argh wrote:which takes longer to go through a stack... 100 commands, or 10 commands? Because, short of making loops that execute every frame, that's what it comes down to...
I don't understand this. Please explain! What do you call stack? In which way you code has less commands being executed? Why is the only alternative something that execute every frame? Which loop?

I still don't see the radical improvment in Argh's script. I eventually gathered he used one function for each limb, instead of one function for every limb, but that only make his code less efficient and more laggy! I fail to see where's the brillant idea. Please open my eyes!
User avatar
Argh
Posts: 10920
Joined: 21 Feb 2005, 03:38

Post by Argh »

Ok... first off, I'm developing some further, concrete proofs. This will take a bit, because of IRL circumstances, so please understand that I'm not being rude by refusing to answer your questions in full at this point.

But, here are a few answers:

1. Your code has to execute many, many more mathematical operations per cycle than mine does. Each one of your lines:
turn leg111 to z-axis 0 - (LEG__1_DOWN_ANGLE) now;
Has a Turn, which is conditional on the results of (z-axis 0 - (LEG__1_DOWN_ANGLE)). This is a major disadvantage from a speed standpoint. Spring has to do several things here:

A. Run through the BOS's many, many lines every frame, because you don't have MotionControl limiting how many times a second you're checking the state of Moving.

B. Move to the Function being called.

C. Move to the appropriate line in the Function.

D. Execute a mathematical operation on the line.

E. Put that into memory, and pass that to the part of Spring that actually moves and draws parts of models.

2. Yes, my code looks longer than your two-leg example script. However, most of it is not being called on any given frame. In fact, most of it is either in the process of Wait-For-Turn, or is sleeping. The only real bugbear, which is unfortunately unavoidable, is the series of logical checks in MotionControl, which must be executed every tenth of a second or so (which is not too burdensome).

Your script, however, is executing commands every frame, because of the math checks and other things. This is not ideal... and it's why, along with other problems, I have been searching for a real alternative, because, as your Scorpion clearly points out, there is a point where it's inefficient. I don't suppose anybody tried building 20 of them and then watching CPU load? It's quite instructive! I will be tackling that beast and optimizing it also... but not yet, unfortunately IRL issues are in the way today and tomorrow, so please be patient, I will hit all of this in greater detail Friday.

3. You're using NOW, which has fundamental limitations in Spring, which I will get into more detail about later.

4. Here's a two-leg walk-cycle with three axis of motion. Please bear in mind that this is just an example, as I don't have a two-legged walking thing in NanoBlobs (yet).

Code: Select all

Go()   
   {
   // normal steps   
     if (bMoving)
   {   
   // RightSide fronts
   wait-for-turn R_THIGH around x-axis;
   turn R_THIGH to x-axis <-50> speed <325>;
   turn R_KNEE to x-axis <40> speed <325>;
   turn R_FOOT to x-axis <15> speed <150>;
   wait-for-turn R_THIGH around x-axis;
   turn R_THIGH to x-axis <0> speed <325>;
   }
     if (bMoving)
   {   
   // RightSide backs
   wait-for-turn R_THIGH around x-axis;
   turn R_THIGH to x-axis <50> speed <325>;
   turn R_KNEE to x-axis <0> speed <325>;
   turn R_FOOT to x-axis <-50> speed <325>;
   wait-for-turn R_THIGH around x-axis;
   turn R_THIGH to x-axis <0> speed <325>;
   }
   }

Go2()   
   {
   // normal steps
   if (bMoving)
   {   
   // LeftSide backs
   wait-for-turn L_THIGH around x-axis;
   turn L_THIGH to x-axis <50> speed <325>;
   turn L_KNEE to x-axis <0> speed <325>;
   turn L_FOOT to x-axis <-50> speed <325>;
   wait-for-turn L_THIGH around x-axis;
   turn L_THIGH to x-axis <0> speed <325>;
   }
   if (bMoving)
   {   
   // LeftSide fronts
   wait-for-turn L_THIGH around x-axis;
   turn L_THIGH to x-axis <-50> speed <325>;
   turn L_KNEE to x-axis <40> speed <325>;
   turn L_FOOT to x-axis <15> speed <150>;
   wait-for-turn L_THIGH around x-axis;
   turn L_THIGH to x-axis <0> speed <325>;
   }
   }

Stop()
   // stop motion
   {   
   sleep 100;
   //  Legs to start
   turn R_THIGH to x-axis <0> now;
   turn L_THIGH to x-axis <0> now;
   turn R_KNEE to x-axis <0> now;
   turn L_KNEE to x-axis <0> now;
   turn R_FOOT to x-axis <0> now;
   turn L_FOOT to x-axis <0> now;
   sleep 100;
   }

MotionControl()
 { var moving,just_moved;
   just_moved = 1;
   WHILE ( TRUE )
   {   moving = bMoving ;
     IF (moving)
         {
         just_moved = 1;
         call-script Go(bMoving);
          }
     IF (!moving)
      { IF (just_moved)
         { just_moved = 0;
           call-script Stop();
          }
        SLEEP 50;
       }
    }
 }

MotionControl2()
 { var moving,just_moved;
   just_moved = 1;
   WHILE ( TRUE )
   {   moving = bMoving ;
     IF (moving)
         {
         just_moved = 1;
         call-script Go2();
          }
     IF (!moving)
      { IF (just_moved)
         {
         just_moved = 0;
         }
        SLEEP 100;
       }
    }
 }
5. Consider the implications of the following:

Spring doesn't care how many scripts are running simultaneously within a given COB- they're all just points on the same thread. What is the limiting factor... is how many simultaneous things are being asked to execute each second by the COB interpreter, not how many Functions are running simultaneously.
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

zwzsg part of what Arghs saying is because of the internal implementation of the COB Virtual machine.

If I recall correctly, it's a stack based system, thus it executes instructions off of the stack.

(for those reading who dont knwo what a stack is, thinking of it as a queue where you put things on the stack/que, then execute/throw away stuff at the other end)

Here you are sayign that Arghs code is worse because ti has more lines.

1 line != 1 instruction

c = a+b != 1 instruction

at the very least

1 :find memory for c
2 :allocate a new value to that memory
3 :get the value of a
4 :get the value of b
5 :find memory for temporary variable d
6 :allocate temporary value d
7 :perform a+b
8 :store the result in temporary value d
9 :assign value c the contents of value d
10 :delete value in d
11 :deallocate memory used for d
12 :destroy all references to temporary value in VM(dependent on implementation(garbage collector))

somewhere around 11 or 12 instructions for a single line.

How large is your bos script when compiled? How does it compair to Arghs bos script? For one if it's larger then it definately has more instructions as thats the whole point of compiling, to translate into cob vm instructions as bytecode.

Ontop of that how many instructions per second are executed?

Argh has a big point with his sleeps and waits.

In ym own experience a certain piece fo java code that shall not be named had a neverending loop running it while(){}, it had no waits or sleeps or delays of any kind. It would check if a connection was open and exit if it wasnt, otherwise run a single large function.

I found it became very laggy at times and as a result was capable of crippling itself and thus wasnt very good for anything but lightweight oeprations as it was originally used for. However I with a few others found that assigning a timer to call the update function at time slots rather than continuosly in a neverendign loop reduced cpu usage by several orders of magnitude from 100% cpu usage to barely measurable amounts.

n# lines dosnt matter. It's number of operations/instructions and calculations that determine speed. Albeit more lines means more chances to add extra instructions.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

1. Your code has to execute many, many more mathematical operations per cycle than mine does. Each one of your lines:
What do you call "cycle"?, Is the cycle of Spring main loop, that's executed between every image, or cycle of the whatever script function? If it's the cycle of Spring main loop, then yours does 4x times as many mathematical operation as mine.
turn leg111 to z-axis 0 - (LEG__1_DOWN_ANGLE) now;

Has a Turn, which is conditional on the results of (z-axis 0 - (LEG__1_DOWN_ANGLE)). This is a major disadvantage from a speed standpoint. Spring has to do several things here:
Erm, where do you see a condition? 0 - (LEG__1_DOWN_ANGLE) is not a condition, it's the angle the piece is turning toward to. Unless you're using the "spin" command, and you're not, there is no way to avoid passing the desired angle in every turn command.
A. Run through the BOS's many, many lines every frame, because you don't have MotionControl limiting how many times a second you're checking the state of Moving.
What? On most frames, I run only one line, the "sleep", or the "wait-for", and for a few frames, I run max 4 turn, then a "sleep" or "wait-for". As for the state of bMoving, I don't even check it anywhere in the 2 legs walkscript I posted.
3. You're using NOW, which has fundamental limitations in Spring, which I will get into more detail about later.
In the Scorpion walkscript, I'm using "now" only once in the lifetime of every scorpion, in the create, so it's not spawn with legs all horizontal like in the 3do. But there's no "now" in the walkscript".

In the 2 leg walkscript I just posted, there isn't any "now"!. Don't tell me I use "now" which is inefficient, as I'm not using "now".

2. Yes, my code looks longer than your two-leg example script. However, most of it is not being called on any given frame. In fact, most of it is either in the process of Wait-For-Turn, or is sleeping. The only real bugbear, which is unfortunately unavoidable, is the series of logical checks in MotionControl, which must be executed every tenth of a second or so (which is not too burdensome).
Hmm, on any give frame, my code run even lines fewer than yours. The MotionControl is avoidable. Unlike what you said, your MotionControl isn't executed every tenth of a second or so, as most of time it's busy waiting for the "go" function to return, but if it were, then it would be really burdensome.


Your script, however, is executing commands every frame, because of the math checks and other things. This is not ideal...
My script execute the minimal number of commands every frame. Most of frames it sleeps, and when it's done sleeping it turn only what must be turned and sleep again. You sound like you believe the COB machine goes throught the whole walk script every time! Well, it does not, "sleep" and "wait-for" are here for a reason.

5. Consider the implications of the following:

Spring doesn't care how many scripts are running simultaneously within a given COB- they're all just points on the same thread. What is the limiting factor... is how many simultaneous things are being asked to execute each second by the COB interpreter, not how many Functions are running simultaneously.
I don't believe that. I'm pretty sure Spring do care how many scripts are running simultaneously within a given COB. As for many things are done each second by the COB interpreter, I already do the minimum. The only way to have less would be to combine the walkscript function with any other function being run continuously, like the SmokeUnit, but then it wouldn't be easy to stop walking and continue smoking (for instance).
AF wrote:n# lines dosnt matter. It's number of operations/instructions and calculations that determine speed. Albeit more lines means more chances to add extra instructions.
I agree with that. I was just counting the lines because someone said Arg script had less lines, so was easier to read and modify. But Arg's script has both more lines and more instruction effectively being run each frame, so.. And don't worry, I know since long ago that everlooping while without sleep or wait-for are great ways to hang a computer.
Argh wrote:Ok... first off, I'm developing some further, concrete proofs. This will take a bit, because of IRL circumstances, so please understand that I'm not being rude by refusing to answer your questions in full at this point.
[...]
I don't suppose anybody tried building 20 of them and then watching CPU load? It's quite instructive! I will be tackling that beast and optimizing it also... but not yet, unfortunately IRL issues are in the way today and tomorrow, so please be patient, I will hit all of this in greater detail Friday.
I'll mount your script, and mine, on the very same T.M.U. kbot, and upload them and stress them, so you won't have that excuse.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

Ok. So I took the ArmAmazon, an unreleased kbot by Legion from T.M.U.

Made two version:
AmazonA, with Arg walkscript
AmazonZ, with exactly the same motion, (same turn, same angle, same speed), but scripted my way.

I stripped the scripts for everything besides walkscript (no smoking, no aiming, no killed, very bare scripts).

The experimental protocol was the following:
- Quit any Spring running, and run a fresh new instance of Spring
- Played on the map "The Cold Place", which has lots of free place
- .cheat, then pause then
- Spawned 1000 Amazons.
- Gave them a move order
- Moved the camera to the other side of the map, zoomed max to the ground
- Unpaused
- Pressed B and watched the values

Did it both for AmazonA and AmazonZ, and, while the difference is thin, it is still there:
- AmazonA (Arg WalkScript)
- AmazonZ (zwzsg walkscript)
Arg script use 15%, mine 6.5%. Ok, I don't really know percent of what.
So with Arg script, FPS is 4 frame per second, with mine, it's 11 frame per seconds (yes I have an old bad computer).

And that's with the second version of Arg script, with only two threads running at once instead of four. (While I use only one).

This was the comparaison between walkscript when the unit is actually walking, if we were to also give a look at what happens when the units are not walking: Arg script still has two threads busy looping when the 1000 kbots are standing still, which show as a 13% next to script in "B" mode, while on my script, there are 0 thread running when the 1000 kbots are standing still, which show as a 0.0% next to script in "B" mode.


I uploaded AmazonA and AmazonZ here:
Amazon_WalkScript_StressTest.ufo
In case anyone wants to examine the script to check I didn't corrupt Arg script, to check that both do exactly the same animation, and to repeat the experiment.

I am still wondering what's the improvment in Argh script, as I cannot find any aspect in which his way his better::
- Argh's way make longer BOS than mine
- Argh's way make longer COB than mine
- Argh's way use one static var and two local var, mine none of each.
- Argh's way has two function continuously looping, mine only one, and only when walking. (Heavier to run ingame)
- Argh's way has 6 functions (not counting create) in the bos, mine 2. (More difficult to read)
- Argh's way keep the messy and confusing Cavedog's way, with MotionControl, mine is clean and fresh and to the point.
- Argh's way eat twice more CPU than mine when walking
- Argh's way eat +oo more CPU than mine when standing still
etc...
Last edited by zwzsg on 16 Aug 2006, 22:54, edited 1 time in total.
User avatar
Buggi
Posts: 875
Joined: 29 Apr 2005, 07:46

Post by Buggi »

Also, look at the difference in your unithandler and your sim time.

Dramatic differences!
User avatar
AF
AI Developer
Posts: 20687
Joined: 14 Sep 2004, 11:32

Post by AF »

Arghs shot looks like the square has had mroe tiem to disperse which might lead to mroe changes anyways as they start bumping into eachother, which would cause a large spike in UnitHandler and slow update anyways. I expect the same would happen for zwzsg script too a second or two later regardless of what script zwzsg used.

This test should be reran with the units spaced out before told to move.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

AF wrote:This test should be reran with the units spaced out before told to move.
Please do, as an experiment result can only be truely accepted once it has been repetead by other people:

Here's the units : Amazon_WalkScript_StressTest.ufo
User avatar
Lindir The Green
Posts: 815
Joined: 04 May 2005, 15:09

Post by Lindir The Green »

Well, I did my own experiment with my 2.8 Ghz Pentium 4 and 1 Gig of RAM.

The map was greener_fields, and I did the same test as zwzsg. For the idle test, I just tested for 30 seconds, and for the moving test, I waited until the units were pretty much staying in the same position relative to each other, and had moved about a third of the way across. Results:

AmazonZ====
Idle: 85 FPS
Moving: 31 FPS

AmazonA====
Idle: 85 FPS
Moving: 31 FPS

Hey, look at that. They are exactly the same. There may be a difference, but it is negligable with a mid-high end machine.
User avatar
LathanStanley
Posts: 1429
Joined: 20 Jun 2005, 05:16

Post by LathanStanley »

why does everyone in this community get a harddon for shooting others down???

Argh said he is STILL working on it.. meaning, it isn't finished yet, you are comparing a cake half-baked to a finished one...

let him finish it, then compare it... in ALL types of situations... just because yours works better on a bipedal robot dosen't mean that args may not work better on something with 200 legs... :wink:

thats the whole point of the way his code is scripted, it SHORTENS the calculations for a VERY heavy legged object >4 legs... vs. your calculation gets huge for a creature with >4 legs....

Argh's script will have its place, as so will yours.. just quit telling him he's "wrong" etc.
User avatar
zwzsg
Kernel Panic Co-Developer
Posts: 7052
Joined: 16 Nov 2004, 13:08

Post by zwzsg »

LathanStanley wrote:thats the whole point of the way his code is scripted, it SHORTENS the calculations for a VERY heavy legged object >4 legs... vs. your calculation gets huge for a creature with >4 legs....
I still cannot understand what makes you say that, that's why I'm looking and comparing and investigating and asking.
User avatar
LathanStanley
Posts: 1429
Joined: 20 Jun 2005, 05:16

Post by LathanStanley »

I'm not much of a scripter myself, but I can comprehed code if I stare long enough...

but reading this thread, Argh has a VERY GOOD theory.. if it'll work right.. just give him a few days to get his "proofs" done and you'll probably be suprised...

he's a pretty smart guy :wink:
Post Reply

Return to “Game Development”