I'm working on a fighting scene where the player fights against an AI character. Scriptwise everything seems to work fine but if the character is standing or walking near the enemy the game REALLY slows down and it's almost impossible to play. Since this can hardly be a matter of my PCs memory or anything similar I guess that certain parts of my script are written too badly for letting the game run smoothly.
Well, here's the script for the enemy movement (which is the only relevant part I guess). It would be nice if somebody could take the time and go through it and then let me know if the script could be improved in a way to make the game run normally.
// --------- aiming ---------
if((character[1].View==1)||(character[1].View==4)){
if((gzielx==character[1].x)&&(gziely==character[1].y)&&(gziel==false)){
a=Random(20);
if ((character[1].x>=cEgo.x+100)&&(a>=10)){ // to the right of the player
gzielx=cEgo.x+130;gziely=cEgo.y;gziel=true;
}
if ((character[1].x<cEgo.x+100)&&(a>=10)){ // to the left of the player
gzielx=cEgo.x-130;gziely=cEgo.y;gziel=true;
}
if a<10){
while ((Region.GetAtRoomXY(gzielx, gziely) != region[1])){ // somwhere
gzielx=30+Random(700);gziely=300+Random(270);gziel=true;
}
}
}
}
// --------- moving ---------
if (gziel){
gziel=false;
character[1].Walk(gzielx, gziely);
}
if((gzielx>=character[1].x-2)&&(gzielx<=character[1].x+2)){gzielx=character[1].x;}
if((gziely>=character[1].y-2)&&(gziely<=character[1].y+2)){gziely=character[1].y;}
// --------- strikes ---------
if((character[1].View==1)||(character[1].View==4)){
if((character[1].y>cEgo.y-15)&&(character[1].y<cEgo.y+15)){
a=Random(1);
if((character[1].x>cEgo.x+60)&&(character[1].x<cEgo.x+160)){
gzielx=character[1].x;gziely=character[1].y;
character[1].FaceCharacter(cEgo);
if (a==0) {gschlag="links"; character[1].ChangeView(2);} // normal strike left
if (a==1) {gschlag="links"; character[1].ChangeView(3);}} // upper strike left
if((character[1].x<cEgo.x-60)&&(character[1].x>cEgo.x-160)){
gzielx=character[1].x;gziely=character[1].y;
character[1].FaceCharacter(cEgo);
if (a==0) {gschlag="rechts"; character[1].ChangeView(2);} // normal strike right
if (a==1) {gschlag="rechts"; character[1].ChangeView(3);}} // upper strike right
}
}
//--------- normal view after strike animation
if((character[1].View==2)||(character[1].View==3)&&(character[1].Frame==4)){
character[1].ChangeView(1);
}
// ----- character looks either left or right ------------
if ((!player.Moving)&&((character[1].View==1)||(character[1].View==4))) {
if (character[1].Loop == 1 && character[1].NormalView != LEFT) character[1].ChangeView(LEFT);
if (character[1].Loop == 2 && character[1].NormalView != RIGHT) character[1].ChangeView(RIGHT);
}
// -------- strike animations are played -------------
if(gschlag!=""){
if(gschlag=="links"){character[1].Animate(1, 2, eOnce, eNoBlock);}
if(gschlag=="rechts"){character[1].Animate(2, 2, eOnce, eNoBlock);}
gschlag="";
}
My guess is that its getting stuck in the while loop for longer than you expect: stick a counter in there and display it if it goes over, say, 10.
Unfortunately that wasn't the problem. I temporarily disabled the while loop but the game was still damn slow...
My guess would be that this line is being called too often:
character[1].Walk(gzielx, gziely);
When you call Walk, AGS has to run the pathfinder to calculate the route, so if that was being called very often then it could cause a slowdown.
Quote from: Pumaman on Mon 02/02/2009 19:22:31
My guess would be that this line is being called too often:
character[1].Walk(gzielx, gziely);
When you call Walk, AGS has to run the pathfinder to calculate the route, so if that was being called very often then it could cause a slowdown.
Yes, I do think so too, because I had that problem before, ahem. (http://www.adventuregamestudio.co.uk/yabb/index.php?topic=36681.0)
I just tried to change the script in a way that it isn't called too often but it didn't quite work. I guess I have to try around a bit and see if can solve that problem. I'll report back soon.
Even if I remove the whole aiming / moving part and the enemy is just standing around the game slows down when the player is near... very strange..
When you say "slows down", does it seem to be going uniformly slower, or is it jerky (fast-stop-fast-stop-etc)?
Would you be able to upload a sample game that demonstrates this?
It slows down rather jerky than uniformly I think.
Well, I uploaded it here. (http://www.webfilehost.com/?mode=viewupload&id=4408445) (At the bottom to the right is the download-button)
You can walk around (without animation) and use left Alt and left Ctrl to strike. You'll notice that it's getting slower the more you approach the enemy.
Tell me if you want me to upload the whole game (with the script which is the double of what I posted here).
EDIT: I forgot to mention that there's currently no way to exit the game so you'll have to use Alt-F4 to do so...
Yeah, can you upload the game source code, please. The problem isn't necessarily in the bits of script that you posted here, it might be elsewhere. With the compiled exe, I do get the slowdown, but it's pretty much impossible to narrow down where it's coming from without the source code.
Okay, I've uploaded the source game here. (http://www.webfilehost.com/?mode=viewupload&id=3229833)
In a hurry I changed the comments from german to english, but some variables still are german, I hope that this doesn't confuse you.
Many thanks for going into it, CJ. I have to get this to work cause otherwise it doesn't make sense to continue the game.
PM me if you have any questions.
Hmm, when I run that version, I don't get any slowdown no matter where I move. Are you sure you haven't already fixed it?
You don't?
That's strange because I do. I haven't changed a thing since the other upload. Back then you experienced the slow-down too but now you don't?
Well, I'm clueless..
Really? With the EXE version that you posted first, I get the slowdown. If I just load the source version and run it, it runs fine.
Are you sure it's identical? The EXE is dated 20:57, but the room1.asc is dated 22:00, which indicates it has been changed since the EXE was built?
Can someone else try these two and see what happens?
For me the same happens as for CJ. Runs jerky with the first exe but runs fine when i run the source game.
Yep, same for me. Ran the EXE and there was a slowdown. Compiled the game with 3.1 and there wasn't a slowdown.
Haha, you're right about that, I must have confused it somehow. The last "version" indeed works as it's supposed to be.
The strange thing is: I can't figure out the difference between both versions.
I know a little change I made for the second upload. In addition to the aiming/moving part I disabled two more lines:
if((gzielx>=character[1].x-2)&&(gzielx<=character[1].x+2)){gzielx=character[1].x;}
if((gziely>=character[1].y-2)&&(gziely<=character[1].y+2)){gziely=character[1].y;}
But the point is that this doesn't make any difference at all. These lines aren't called at all when the AI movement is disabled.
But nevertheless I got a working version now which I will use from now on. So my problem is solved. In case I can figure out the difference between the versions I let you know. This is too strange....
EDIT: Thanks for trying out the uploads..
Now I know what the problem and the difference between the uploads was:
I was going to use SSH's pixel-perfect collision module and had a (yet senseless) line of code at the end of the rep-ex, which I deleted before the second upload ::).
if(PPColliding.CWithC(cEgo, cChar1)){}
That was the cause for the slowdown. As you said in the module's thread, CJ, the pixel-detection might be slow when used in the rep-ex. Well, this is a very sad thing since my character sprites are much larger than the actual images and therefore I need such a detection. Now I'm trying to mix the detection with narrowing it down through manual coordinate-detection, but that doesn't really solve this issue.
I guess there's no way to speed things up while using the collision-detection... so perhaps I'll need to just use simple coordinate detection, which will be a complicated thing to script :'(.
EDIT:
I figured out a way to use the pixel-perfect collision without having any slowdowns. Yay! ;D
Thanks again guys, and have a nice day.
Glad you figured it out! :)
Just one minor thing -- the "character[1].x" type syntax is quite obsolete now, it's faster and more readable to use "cChar1.x" (or whatever his script name is) instead.
Quote from: Pumaman on Wed 04/02/2009 18:20:57
Just one minor thing -- the "character[1].x" type syntax is quite obsolete now, it's faster and more readable to use "cChar1.x" (or whatever his script name is) instead.
You're right and I normally use the character's name but this fight scene was more or less an experiment and I will rewrite the variable and character names anyway when I integrate this script into my original game. I just wanted to get that fight working before using the code.
Quote from: Pumaman on Wed 04/02/2009 18:20:57
Just one minor thing -- the "character[1].x" type syntax is quite obsolete now, it's faster and more readable to use "cChar1.x" (or whatever his script name is) instead.
I hope obsolete doesn't mean character[num].x will be trashed from the compiler completely in later versions. It's handy using while statements to control all characters, etc.
Ah, I forgot to say that in my actual (turn-based) game there are four players (which are optionally controlled either by human players via hotseat or by AI), so I need to use the character[player] command to determine the current player.
Ryan, if the possibility of a character-array would get trashed I'd begin to doubt that CJ's mind is still in mint condition. No, I'm exaggerating ;), but it wouldn't make sense and take away certain possibilities (like what I'm doing in my game).
Quote from: Ryan Timothy on Thu 05/02/2009 04:31:44
I hope obsolete doesn't mean character[num].x will be trashed from the compiler completely in later versions. It's handy using while statements to control all characters, etc.
No, it won't be removed. The only reason I commented was because having it in threads like this pose the danger that newbies searching the forums will come across the script posted here and think it's the "correct" way to do things.
Anyway, glad everything's sorted.