Game get slower on long play

Advanced game related topics
User avatar
bfernhout
Enthusiast
Enthusiast
Posts: 123
Joined: Mon Feb 26, 2018 10:41 pm
Location: Netherlands
Contact:

Game get slower on long play

Post by bfernhout »

I have create a game that was converted from GameMaker to Puebasic.
The game is working perfect. There is only one small problem. On the long run the game is starting to slow down.
I have timed all the procedures that i using and only one procedure is causing this problem. But when i look at the code there is no reason why this can happend here.
The procedure is:

Code: Select all

Procedure MakeField()
  Protected x.i,y.i
  Protected x1.i,y1.i
  Protected Color.i
  
  DisplaySprite(Spr_BackGround,0,0)
  
  ;Put everthing in the field what is visable
  StartTime = ElapsedMilliseconds()  ;-----------------------------------
  For x = 0 To 39
    For y = 0 To 39
      If Field(x,y) > 0 And field(x,y) < 3
        DisplaySprite(Spr_Wall(Field(x,y)),x*32,y*32)
      EndIf
      If Not(ExplosionActive)
        If x= tank1()\FieldX And y = Tank1()\FieldY
          DisplayTransparentSprite(Spr_Tank1(Tank1()\Direction),x*32+Tank1()\PosX,y*32+Tank1()\PosY)
        EndIf
        If x= tank2()\FieldX And y = Tank2()\FieldY
          DisplayTransparentSprite(Spr_Tank2(Tank2()\Direction),x*32+Tank2()\PosX,y*32+Tank2()\PosY)
        EndIf
      EndIf
      If Field(x,y) > 9 And Field(x,y) < 14
        DisplayTransparentSprite(Spr_PickUp(Field(x,y)-10),x*32,y*32)
      EndIf
    Next
  Next
  EndTime = ElapsedMilliseconds()   ;------------------------------------------
  Between = EndTime - StartTime
  ;Work on the bonus picked up
  UpdateShield()
  UpdateRocket()
  UpdateBouncing()
  
  ;The wall that are shoot away
  UpdateWall()
  
  ;Explosions General
  UpdateExplosionSmall()
  UpdateExplosionLarge()
  
  ;Display health bar above the tanks
  HealtBarTank1()
  HealtBarTank2()
  
  ;Display Bonus if picked up by tanks
  BonusAtTank1()
  BonusAtTank2()
  
  ;Colliding tank vs tank
  TankColliding()
  
  ;Move shell over screen
  ShowShell1()
  ShowShell2()
  
  ;Check hitting Something for Tanks
  CollideTank1()
  CollideTank2()
  
  ;Create viewport 1 and 2
  CreateViewPort1()
  CreateViewPort2()
  
EndProcedure
The timers are marked and between the two lines the timing is slowing down. The game is starting with 12 Ms in the loop but in time its going up. When i do nothing or just running with the tanks. After about 15 min i notice a slowdown of the game, the time that is meassured is up to 45 Ms. When the game is runnen for say 45 minutes the meassured is at 61 ms.

The Sprites and images are not changed during the game. The viewports are sprite that are grabed.
The screen is in windows mode, and because of the 2 viewports its 800 * 460. The screen to work in is 1500 * 1500. This is bigger than the viseble part but all is down on the background. When the viewports are made all is cleared and the view ports are made. Then the screen is flipped and then cleared.

When i see the code i see no reason why this part is slowing down.
From my first self made computer till now I stil like computers.
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: Game get slower on long play

Post by Tenaja »

Have you tried moving the time statements to isolate the section further?
wombats
Enthusiast
Enthusiast
Posts: 663
Joined: Thu Dec 29, 2011 5:03 pm

Re: Game get slower on long play

Post by wombats »

Have you forgotten to free something that you're no longer using anywhere?
User avatar
Fig
Enthusiast
Enthusiast
Posts: 351
Joined: Thu Apr 30, 2009 5:23 pm
Location: Côtes d'Azur, France

Re: Game get slower on long play

Post by Fig »

what about collision tests ?

If you create ennemies (tanks ?) and forget to erase them (from you foes' list ?) and if you use a "naive" collision algo, it's exponential !
There are 2 methods to program bugless.
But only the third works fine.

Win10, Pb x64 5.71 LTS
User avatar
bfernhout
Enthusiast
Enthusiast
Posts: 123
Joined: Mon Feb 26, 2018 10:41 pm
Location: Netherlands
Contact:

Re: Game get slower on long play

Post by bfernhout »

I was not aware that my question was to fage.

This game is a complete rebuild from GameMaker. This is done for tutoring boys and girls to program a game. In dutch.

I keep the whole code as simple as posible. That means all graphis is loaded at in Init file at startup. No gaphics is to much, so all is staying in memory.
There are two (Semi animated) tanks in the game so two players is playing to each other. controle, movement all is working.

The only thing i do create are List elements from a structure. There are 2 reasons that the bullets are removed from the list.
1. When a time i passd the element is removed using DeleteElement(ElementName())
2. When its hit a wall/opponent its removed to.

Now the update of those elements is done in another Procedure, and they are always at the same time.

Another point i can accept that the loop will take a little more time is when Bonus elements is placed in the grid Named: Field.
But there is a max of bonus items that can be placed in the grid. And that is 25 items.
So if the time is going up from 12 to say 15 ms i can understand. But th items are staying a max time of 12 seconds in the grid.
Then the items are removed from the grid. (This placing and removing is done is a array that has a fixed size)
But its counting slowly up.

I have another little game that has much more elements on the screen and a lot of animation. But the game is and stay runnig om the same speed.
The Beauty of it is, that the whole game loop takes 9 ms. And to keep it running at a FPS of 60 i needed to creatd a delta timing for the game to run smooth.
I know you can set the game at 60 FPS but for the tutorial purpose this was nicer.

There is a difference in game speed when i compile te game to a exe. The counting up is taking langer to get to a point that it is going to be a problem. And i mean way longer.

I checked up the use of memory by the Structures that are made and remove. But there is no growing is size. It stay the same the whole time.

There is only one thing, that is total differend in all the tutorial games, that is made, is that this game has a bigger work screen then showed on screen. Is this some kind of memory leak.
From my first self made computer till now I stil like computers.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Game get slower on long play

Post by #NULL »

Just keep narrowing it down.
Comment-out all Display[Transparent]Sprite() commands.
Add a counter for each branch to see which branch might be taken to often, or comment out branches.
Field, Spr_Wall, Spr_Tank1, Spr_Tank2 and Spr_PickUp are arrays, not functions, right?
User avatar
bfernhout
Enthusiast
Enthusiast
Posts: 123
Joined: Mon Feb 26, 2018 10:41 pm
Location: Netherlands
Contact:

Re: Game get slower on long play

Post by bfernhout »

The Spr_ are indeed graphic arrays. The tanks can on every 6 degreed a image. That give the idea of rotating aniamtion if the player wants. There are two types of wall's a solid one and a breakable wall.

I try to narrow down the problem but there is the problem that when i time the placing of the items itself then the time stay the same.
Only when the loop is measured the time is going up.

I wil try to find a place to upload the complete code, including everything that is needed.
From my first self made computer till now I stil like computers.
User avatar
bfernhout
Enthusiast
Enthusiast
Posts: 123
Joined: Mon Feb 26, 2018 10:41 pm
Location: Netherlands
Contact:

Re: Game get slower on long play

Post by bfernhout »

I have narrowed it down to where the problem is coming up.

Code: Select all

  For x = 0 To 39
    For y = 0 To 39
      If Field(x,y) > 0 And field(x,y) < 3
        DisplaySprite(Spr_Wall(Field(x,y)),x*32,y*32)
      EndIf
    Next
  Next

This peice of code is causing the slow down. I have split out the code in 3 parts. It did speed up the game with 1 ms. But the slowdown is stil occuring.

This code is using up 1 ms and in about 10 min its climb up to 27 ms. Even if i do not toucht the game this stay happening.
I did go to somebody who have a Windows 7 system 32 bit computer. (I use Win 10, 64 bit, 7i core, Gfore GTX950M graphic card, 32 Gb mem and 1Tb ssd).
And on his system the game is running for about 5 min. And then crashed. The run time was 0 ms at start and when the number hits 4 ms the game is stuck. No error or some thing. Just freez up and only by killing the game using system manager the game got removed.
From my first self made computer till now I stil like computers.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Game get slower on long play

Post by #NULL »

Are you redimming any of the arrays somewhere, so they keep growing accidentally?
If you can share the code/files it will be much easier to help you.
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: Game get slower on long play

Post by Tenaja »

Also check your ram use. Does it increase with time?
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Game get slower on long play

Post by #NULL »

Tenaja wrote:Also check your ram use. Does it increase with time?
Good guess. He sent me the code and we found sprites were recreated without freeing the previous ones.
User avatar
bfernhout
Enthusiast
Enthusiast
Posts: 123
Joined: Mon Feb 26, 2018 10:41 pm
Location: Netherlands
Contact:

Re: Game get slower on long play

Post by bfernhout »

The memory check was the clue. It took up ram while running. And #NULL did helped me and looked into the code. He found out that creating a sprite did not take any time, but it used up memory. And in the game this sprite dissapeared and when i needed a it again, i created a new one. While the old one was stil active. This used up slowly the memory.

A procedure called CreateViewPort() was the guilty one.

Code: Select all

Procedure CreateViewPort1()

  ;Calculate the grab position
  MainX1 = (Tank1()\FieldX-6)*32+Tank1()\PosX
  MainY1 = (Tank1()\FieldY-6)*32+Tank1()\PosY
  
  ;Correction on edge
  If Tank1()\FieldX < 6
    MainX1 = 0
  ElseIf Tank1()\FieldX > 33
    MainX1 = 800
  EndIf
  
  If Tank1()\FieldY < 6
    MainY1 = 0
  ElseIf Tank1()\FieldY > 30
    MainY1 = 800
  EndIf
  
  ;Now grab it  
  Spr_Play1 = GrabSprite(#PB_Any,MainX1,MainY1,395,480)  ;<---------------------

EndProcedure
I changes it to

Code: Select all

Procedure CreateViewPort1()

  ;Calculate the grab position
  MainX1 = (Tank1()\FieldX-6)*32+Tank1()\PosX
  MainY1 = (Tank1()\FieldY-6)*32+Tank1()\PosY
  
  ;Correction on edge
  If Tank1()\FieldX < 6
    MainX1 = 0
  ElseIf Tank1()\FieldX > 33
    MainX1 = 800
  EndIf
  
  If Tank1()\FieldY < 6
    MainY1 = 0
  ElseIf Tank1()\FieldY > 30
    MainY1 = 800
  EndIf
  
  ;Now grab it  
  GrabSprite(Spr_play1,MainX1,MainY1,395,480)  ;<-------------------

EndProcedure
Where Spr_Play1 got a number 100
Thank you all for helping me out with this problem
I was already 3 weeks hunting for this a was starring blind on the wrong place.
I did made a list of all the things that are in the program and strike out the points that was checked.
I did overlook this one. The only one that cause the problem.

This problem gives the example that a problem is not always there where the error occure.

Thanks again.....
From my first self made computer till now I stil like computers.
Post Reply