| 02-09-2009, 08:51 PM | #1 |
Yea, I have got the following problem: A timer in my map (I am sure that it is the source of the lagg, because I use only this timer) makes the game lagging after an undefined time of playing. I disabled any component of code which is executed by the timer - and the laggs disappear, of course. Than I enabled step by step any of the components to find out which of them is causing the lagg. And no one of the components laggs if it is the only one runned by the timer. But together they cause a lagg after some time - a lagg which make it impossible to play. So, here's the code:globals timer Timer = null boolean GameIsPaused = true constant player NEUTRAL_PLAYER = Player(11) dialog DefeatDialog = DialogCreate() button array DefeatDialog_Button unit Ball real Ball_FallSpeed = 800 * DISPLAY_INTERVAL real Ball_MovementSpeed = 600 * DISPLAY_INTERVAL real Ball_Radius = 80 integer Ball_Movement = 0 constant integer BALL_MOVEMENT_NONE = 0 constant integer BALL_MOVEMENT_LEFT = 1 constant integer BALL_MOVEMENT_RIGHT = 2 boolean resetBallMovement = false real Line_MovementSpeed = 200 * DISPLAY_INTERVAL group Line_Dummies real Line_MaxDistance = 1000 real Line_Distance = Line_MaxDistance real GapSize = 500 real DashWidth = 42 // Coordinates of the playable map real MIN_X real MAX_X real MIN_Y real MAX_Y multiboard Multiboard real Score = 0 real ScorePerInterval = 1 integer ScoreLevel = 0 integer array ScoreThreshold endglobals //=========================================================================== // function MoveLineDummiesUp takes nothing returns nothing local unit Dummy = GetEnumUnit() local real y = GetUnitY(Dummy) + Line_MovementSpeed if y > GetRectMinY(gg_rct_Top) then call GroupRemoveUnit(Line_Dummies, Dummy) call RemoveUnit(Dummy) else call SetUnitY(Dummy, y) endif set Dummy = null endfunction function MoveLines takes nothing returns nothing //call DMsg("MoveLines") call ForGroup(Line_Dummies, function MoveLineDummiesUp) endfunction // //=========================================================================== //=========================================================================== // function CreateNewLine takes nothing returns nothing local real GapStart = GetRandomReal(MIN_X, MAX_X - GapSize) local real x = MIN_X + DashWidth local unit Dummy set GapStart = (MIN_X + MAX_X) / 2 loop exitwhen x >= MAX_X if x >= GapStart and x <= (GapStart + GapSize) then set x = GapStart + GapSize + DashWidth endif set Dummy = CreateUnit(NEUTRAL_PLAYER, 'dash', x, MIN_Y + DashWidth, 0) call GroupAddUnit(Line_Dummies, Dummy) set x = x + DashWidth endloop set Dummy = null endfunction // //=========================================================================== //=========================================================================== // function IsDash takes nothing returns boolean return GetUnitTypeId(GetFilterUnit()) == 'dash' endfunction function MoveBall takes nothing returns nothing local unit u local real AngleBetweenUnits local real x = GetUnitX(Ball) local real y = GetUnitY(Ball) local real dx local real dy local real newY local boolean isOnLine = false local real distance = 0 call GroupEnumUnitsOfPlayer(TempGroup, NEUTRAL_PLAYER, Condition(function IsDash)) loop set u = FirstOfGroup(TempGroup) exitwhen u == null call GroupRemoveUnit(TempGroup, u) set dx = x - GetUnitX(u) set dy = y - GetUnitY(u) set distance = SquareRoot(dx * dx + dy * dy) if distance <= Ball_Radius then set isOnLine = true exitwhen true endif endloop call GroupClear(TempGroup) set u = null if isOnLine then if Line_MovementSpeed + distance >= Ball_Radius then set newY = y + Line_MovementSpeed else set newY = y + Line_MovementSpeed + Ball_Radius - distance endif if newY > GetRectMinY(gg_rct_Top) then call DialogSetMessage( DefeatDialog, "Defeated!|nScore: " + I2S(R2I(Score + .5))) call DialogDisplay(Player(0), DefeatDialog, true) set GameIsPaused = true else call SetUnitY(Ball, newY) endif else set newY = y - Ball_FallSpeed if newY >= MIN_Y + DashWidth + Ball_Radius then call SetUnitY(Ball, newY) endif endif endfunction // //=========================================================================== //=========================================================================== // function ControlBall takes nothing returns nothing local real x if Ball_Movement != BALL_MOVEMENT_NONE then set x = GetUnitX(Ball) if Ball_Movement == BALL_MOVEMENT_RIGHT then set x = x + Ball_MovementSpeed elseif Ball_Movement == BALL_MOVEMENT_LEFT then set x = x - Ball_MovementSpeed endif if x >= MIN_X and x <= MAX_X then call SetUnitX(Ball, x) else set Ball_Movement = BALL_MOVEMENT_NONE endif if resetBallMovement then set resetBallMovement = false set Ball_Movement = BALL_MOVEMENT_NONE endif endif endfunction // //=========================================================================== //=========================================================================== // function AdjustScore takes nothing returns nothing set Score = Score + ScorePerInterval if Score >= ScoreThreshold[ScoreLevel] then call UpdateOnScoreThreshold() endif call MBSetItemText(Multiboard, 1, 1, I2S(R2I(Score + .5))) call MBSetItemText(Multiboard, 3, 1, I2S(R2I(ScoreThreshold[ScoreLevel] - Score + .5))) endfunction // //=========================================================================== function Timer_Actions takes nothing returns nothing if not GameIsPaused then // Lock Camera call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, CameraSetupGetField(gg_cam_StartCam, CAMERA_FIELD_TARGET_DISTANCE), 0) call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 270.00, 0) // Move existing lines call ExecuteFunc("MoveLines") set Line_Distance = Line_Distance + Line_MovementSpeed if Line_Distance >= Line_MaxDistance then set Line_Distance = 0 // Create a new line call ExecuteFunc("CreateNewLine") endif // Ball-Movement call ExecuteFunc("MoveBall") // Ball-Control call ExecuteFunc("ControlBall") // Increase the score call ExecuteFunc("AdjustScore") endif endfunction //=========================================================================== function InitTrig_Timer_Copy takes nothing returns nothing set Timer = CreateTimer() call TimerStart(Timer, DISPLAY_INTERVAL, true, function Timer_Actions) set Line_Dummies = CreateGroup() endfunction Thanks in advance. |
| 02-09-2009, 09:01 PM | #2 |
Well, there are some ways you can optimize this code. I don't know exactly what the problem is, that would take deeper inspection. But I do know that ExecuteFunc is pretty outdated, and I've heard it's slow - just call the function itself. I was going to recommend using structs but it appears you really only need one instance of these globals. |
| 02-12-2009, 10:39 AM | #3 |
Why should ExecuteFunc be outdated? There aren't any faster methods to run code in a custom thread :) I know that a simple function-call is faster than an ExecuteFunc. But I already tested it by replacing all ExecuteFuncs with calls, but that doesn't fix the main-problem: A lagg which nearly kills the game after some time :\ |
| 02-12-2009, 11:09 AM | #4 |
You're leaking conditions: use a global boolexpr or filterfunc instead of creating one each time you call MoveBall. |
| 02-12-2009, 11:11 AM | #5 |
I'm sure that boolexpr where cached by warcraft instead of creating them every time. |
| 02-12-2009, 11:36 AM | #6 | |
Quote:
You do not need a thread here man, if just calling the functions causes a limit op then your functions are way too heavy for a periodic timer and that's the cause of your lag. --- Regarding your leak, The native called "Condition" does not 'leak' , but I am kind of sure you have a leak in that MBSetItemText function, please post it. |
| 02-12-2009, 01:42 PM | #7 |
DISPLAY_INTERVAL equal to ? |
| 02-12-2009, 08:31 PM | #8 |
I didn't know that conditions were leakless... I'll stop telling people that. Storing it on init will reduce the function calls to 1 though... |
| 02-12-2009, 09:05 PM | #9 |
Ok, I will call the functions in the normal way. function MBSetItemText:function MBSetItemText takes multiboard mb, integer row, integer col, string text returns nothing local multiboarditem mbitem = MultiboardGetItem(mb, row, col) call MultiboardSetItemValue(mbitem, text ) call MultiboardReleaseItem(mbitem) set mbitem = null endfunction constant real DISPLAY_INTERVAL = 1. / 32. They strange thing is that the game runs all time stable, there aren't any performance issue but suddenly there's a huge lagg... And thanks alot to you all for your help :) |
| 02-13-2009, 04:48 AM | #10 | |
Quote:
|
| 02-13-2009, 12:40 PM | #11 |
when you say lagging - do you mean the game slowly approaches unplayableness - or that you get random lag spikes later into the game? the latter most likely being some op limit or some preload your forgot to do otherwise, you are probably leaking memory prety heavily some place, or creating too many units you never get rid of, etc. ( you get the idea) as far as your script goes - i see not reason for massive lag all of a sudden, which begs the question, what else are you triggering in your map? |
| 02-13-2009, 04:53 PM | #12 |
When I say lagg I ment the second thing - sudden lagg spikes. There are nearly no other triggers in the map. Just some DialogClickings and Init-Triggers. As I said, when I turn out this timer, there isn't any lagg at all. There's only one function-call in my code which wasn't explained by me yet function UpdateOnScoreThreshold:function Update_Ball_MovementSpeed takes nothing returns nothing set Ball_MovementSpeed = 1.1 * Ball_MovementSpeed endfunction function Update_Line_MovementSpeed takes nothing returns nothing set Line_MovementSpeed = 1.15 * Line_MovementSpeed endfunction function Update_Line_MaxDistance takes nothing returns nothing set Line_MaxDistance = 0.975 * Line_MaxDistance endfunction function Update_ScorePerInterval takes nothing returns nothing set ScorePerInterval = ScorePerInterval + 1 endfunction function UpdateOnScoreThreshold takes nothing returns nothing set ScoreLevel = ScoreLevel + 1 call MBSetItemText(Multiboard, 2, 1, I2S(ScoreLevel)) call Update_Ball_MovementSpeed() call Update_Line_MovementSpeed() call Update_Line_MaxDistance() call Update_ScorePerInterval() endfunction |
| 02-17-2009, 08:35 PM | #13 |
Sorry for doubleposting - but this lagg really makes me sick... Until now I tried everything I could imagine to fix, but nothing helps. And it seems to me nobody else out there knows the reason... I think the reason can't be a leak, because the memory usage of war.exe remains the same when the lagg appears (or just increase a little, not to mind). This seems to be a really strange issue :( |
| 02-22-2009, 10:57 PM | #14 |
Are you maybe displaying large amounts of game messages, debug or otherwise? |
| 02-23-2009, 08:07 AM | #15 |
No, in this case I just show at the beginning of the game a little instruction via textmessages JASS:call DisplayTimedTextToPlayer(Player(0), 0.5, 0, 9999, "Willkommen bei " + GAMETITLE) call DisplayTimedTextToPlayer(Player(0), 0.5, 0, 9999, " ") call DisplayTimedTextToPlayer(Player(0), 0.5, 0, 9999, " Nutze <- und ->") call DisplayTimedTextToPlayer(Player(0), 0.5, 0, 9999, " um den Ball zu steuern") call DisplayTimedTextToPlayer(Player(0), 0.5, 0, 9999, " Bleibe unter der Bildoberkante!") call DisplayTimedTextToPlayer(Player(0), 0.5, 0, 9999, " <ESC> zum Pausieren") call DisplayTimedTextToPlayer(Player(0), 0.5, 0, 9999, " Drücke <- oder -> zum starten") |
