Game slow problem on Android

the game runs in slow motion after 5 minutes of testing everything works well except this slowness the game is no longer reactive in your opinion where can this come from?
i am using pixel 5 api 32 android emulator
mac i5 2.34G

thank you in advance

Sounds like a memory leak. I.e. something in your code is allocating memory and never releasing it, so over time it builds up until it is unmanageable. You wouldn’t notice it as much on PCs or other high-memory/high-performance devices.

1 Like

hey
thank you for your reply
If I try with a physical device will it work better?
how can i diagnose this leak?

No, you probably won’t see much/any difference between a real device and an emulator for this one. In visual studio, make use of your memory profiler while your debug build is running. See if it is constantly climbing (using more memory). If so, you have some sort of unmanaged data type(s) that are not being disposed properly. For instance, if your game loop is constantly creating render targets without disposing them.

1 Like

thank you i will test the memory profiler
How do I know that items are deleted?

Luckily c# (the garbage collector) will care for deleting any items which are not longer referenced anywhere.

Start your profiler (or task mananger) and see if it keeps allocating more and more memory. If yes you somehow create lots of objects and keep them referenced.

If your game starts to get slower and slower (not suddenly slow) you most likely have some list filling bigger and bigger, so you process a growing amount of data which takes more and more time.

Finding those things means stepping through your code and find out where things go wrong - could be as simple as not clearing some list every frame. Let it run, pause from debugger, inspect any objects for unexpectedly high counts etc.

1 Like

Thanks for your help
yes I notice a progressive slowness
and I have a list of sprites the enemy sprites are deleted but I think it comes from the player, but how can I empty the player without deleting it?

I did not understand how stacking collection works
do you have an example?

thanks in advance

i have something like this

keep those objects somewhere , for example a list or pool of used objects, then when you need a new one, instead of creating it you pull from that pool and re-initialize the values in that class, so you never delete any object that requires constant creation, otherwise your game will run very slow due to collecting garbage everywhere.

1 Like

THANKS
very interesting but I don’t know how I could do that do you have an example?

I did this in my previous game Space Bugs Wars where I had thousands of enemies and many hundreds bullets around on each frame, let me show you some code

        List<BulletParticle> bulletFree = new List<BulletParticle>();
        List<BulletParticle> bulletInUse = new List<BulletParticle>();

I had a class BulletParticle for example, it had the typical Update, Draw methods like:

      public virtual void Update( GameTime gameTime ) {
               // update code here, where  I can check  collisions and other things
        } 
        public virtual void Draw( SpriteBatch spriteBatch ) {
              // standard draw logic here
        }

so, whenever I needed a new bullet, instead of doing

      BulletParticle = new BulletParticle();

I did something like this

            if (bulletFree.Count > 0 ) {
                  BulletParticle bullet = bulletFree[0];
                  bulletFree.RemoveAt(0);
                  bulletInUse.Add(bullet);
                  bullet.Reset( < insert your parameters here like position, speed, etc.. > );
            }
        }

and whenever I need to update the bullet I just did , this will free the bullet if it is dead , removing it from the bulletInUse list into the free list of bullets:

                for ( int idx = bulletInUse.Count - 1; idx >= 0; idx-- ) {
                    BulletParticle bp = bulletInUse[idx];
                    bp.Update( elapsed );

                    if ( bp.IsDead ) { 
                        bulletFree.Add( bp );
                        bulletInUse.RemoveAt( idx );
                    }
                }

And you will need to add a bunch of free bullets when starting your game for the first time like

           for ( int idx =0 ; idx<500; idx++){
                 BulletParticle bullet = new  BulletParticle();
                 bulletFree.add(bullet);
           }

So during gameplay, I never do a “= new Something()” , because that may be trashed later when you don’t need it anymore, so instead moved to a free list of that object type so I can re-use it multiple times like the bullets here. That saves a lot of time since allocation and garbage collection take too much time, so instead of doing cleaning , just recycle it. I do the same logic with enemies, bullets, power ups, pick ups , pretty much everything, and when I restart the game for a second play or more, you need to always move all the items from the used list into the free list. So you start the 2nd or 3rd or more rounds from zero without creating additional garbage.

Also if you think you may need more bullets you can add "= new … " into the free buffer, but you need to make sure you have enough memory, or limit the number of items in each list if you want to make sure you don’t go over the hardware limits, usually you will never have more than 200 or 300 of each type of thing but it depends on your game. In Space Bugs Wars I had 1500 enemies and I ran at 144 FPS (sync to my monitor refresh rate) without any issues and about 500 bullets at all times, with more than 2000 enemies I had some issues sometimes going to 100 FPS or less, so just to make sure it may work in more computers I pull down the number of enemies per frame.

3 Likes

Hi
je comprends mieux la logique une approche très intéressante
Je vais tester cela
Merci beaucoup pour votre aide c’est super :+1:

bulletFree.RemoveAt(0);

This will induce an Array.Copy of the whole underlying array of the list - which is pretty slow. Better use a Queue<>.Dequeue() instead, it’s multiple times faster(or at least remove the last, not the first item in the list :slight_smile: )

3 Likes

hmm that I didn’t know :slight_smile:
I used index = 0 since it will be always there if the List is not empty which make the code a lot easier to manage.

So after looking at the differences between a list and a queue, a queue will be suitable for storing the free list of objects , but still a list will be needed for the used list of objects since i need random access to the list and remove items in any order.

So in summary , I think I can change the Free List of objects to a queue for those lists that are very large, like bullets and things like that, but for small number of objects I think it may not make much difference.

1 Like

you are welcome, hope it works for you now.

1 Like

Hi,

I understand the principle but I can’t put it into practice :thinking:

my basic algorithm

I have a sprite class
and the player and the enemies inherit the same sprite
it makes it easier for me to process collisions, etc. I process this in the player class
everyone is in a list sprites
I call the player in Loadcontent

sprites = new List<Sprite>
                 {
                    new Player(texturePlayer)
                     {
                         _position = new Vector2(100,100),

                     },
                 };

can it come from her?

For enemies are created at regular intervals
using Timer
they are called as follows
sprites. Add(new Enemy(Content.Load<Texture2D>("enemy1")));

how can i adapt all these
thanks in advance

You need to make a main class and make player and enemy inherit from the main class

so for example

public class MyEntities {
// your generic code here for all entity types
}

then you have Player and enemy class like:

public class Player : Entity {
// your specific code for player here
}


public class Enemy : Entity {
 // another enemy class that derives from Entity
}


and in your list you do:
List<Entity> entitiesUsed = new List<Entity>();
List<Entity> entitiesFree = new List<Entity>();

and you can do later:
entitiesFree.add( new Player());

and to add all into the entities list
entitiesFree.add( new Enemy());

also instead of doing → new Enemy(Content.Load(“enemy1”))
cache the content load into a variable so you don’t need to type the same thing everywhere.
Like
Texture2D myEnemyTexture1 = Content.Load(“enemy1”);

and use myEnemyTexture1 when you create the class
so you don’t need to do a new Enemy whenever you need an enemy, you do that only when you start your game once, and then pull from the free list.

Check the bullet example I put up, replace bullet with entity and it will work.

1 Like

Merci pour votre aide
les appels des listes est-ce que je le fait dans la méthode LoadContent() ?

List<Entity> entitiesUsed = new List<Entity>();
List<Entity> entitiesFree = new List<Entity>();

et code que vous avez envoyé est-ce lui aussi dans le LoadContent() ou dans update?

merci encore

Dans ma classe Sprite j’ai cela

        //virtual update
        public virtual void Update(GameTime gameTime, List<Sprite> sprites, GamePadState gamePadState)
        {
        }

        //virtual draw
        public virtual void Draw(SpriteBatch spriteBatch)
        {
        }

dans la classe principale Game1.cs
je les parcours
//update

foreach (var sprite in sprites)
            {
                sprite.Update(gameTime, sprites, gamePadState); 
            }

//draw

 foreach (var sprite in sprites)
            {
                sprite.Draw(spriteBatch);
            }