I'm developing for xna game studion using XNA 3.1, and I've noticed a problem with some games, where they lag despite the system having plenty of resources to handle them, along with an inexplicable excess of processor usage. When the window from the game is in focus, process #1 (in task manager) goes to 100% usage, and the game shows signs of minor lag (largely notable when sound effects are repeated in sequence). When the game loses window focus, it continues to draw and update at real time, but the process usage decreases, and the lag disappears.
I have tested this with various games, and the results remain the same, proving that it has nothing to do with my code or code efficiency.
Is this a problem isolated to Xna 3.1, and is there fix for it? Or do I just have to switch to 4.0 and hope my games don't use anything that isn't backwards compatible?
The problem may occur because of garbage collector. Everytime garbage collector runs, the frame rate may drop for a second or two, though on Windows it shouldnt be a problem.
Add this line to your code and see how much heap memory is generated. Every time the value goes down, garbage collector is ran.
SpriteBatch.DrawInt64(FONT, GC.GetTotalMemory(false) / 1000 /* in kilobytes */, new Vector2(5, 30), Color.White, 0f);
SpriteBatch.DrawInt64 is a SpriteBatch extension which doesnt generate garbage on int, long etc. You can alternatively just use SpriteBatch.DrawString(..., (GC.GetTotalMemory(false) / 1000).ToString(), ... )
SpriteBatchExtensions.cs : http://pastebin.com/z9aB7zFH
XNA, from my experience, runs up to 60 frames per second while in focus, and at about 20 frames per second when out of focus. IF however, you have set IsFixedTimeStep = false; the game will run as fast as it possibly can when the process is in focus. With my game, on my machine, it runs at about 500-700 fps. This is also tied in to the number of Update() calls that occur. So my game is also updating 500-700 times per second.
My bet is that you have disabled the fixed timestep, and the massive number of Update and Draw calls are consuming 100% of your core and it is messing with your music. I would recommend removing the line IsFixedTimeStep = false; if it's there. If that line does not exist in your code, this is not the problem, although I would bet that your Update or Draw is doing more work than it should be.
Just noticed this in my own game, I have a Console.WriteLine statement (for debugging) in my update loop, this causes lots of lag.
XNA add a sleep when the window is not in focus!
I solved this problem some time ago overriding Game class and changing the way the Game class understand its form is active or not.
There is not way, as much as i know, to disable this behaviour without modifying Game class behaviour with code.
In particular, the way i found some time ago is a real hack\quirk!
Very unclean solution, but the only way i found.
public class MyGame
{
private MethodInfo pActivate;
public MyGame()
{
// We need to access base HostActivate method, that unfortunally, is private!
// We need to use reflection then, of course this method is an hack and not a real solution!
// Ask Microsoft for a better implementation of their class!
this.pActivate = typeof(Game).GetMethod("HostActivated", BindingFlags.NonPublic | BindingFlags.Instance);
}
protected sealed override void OnDeactivated(object sender, EventArgs args)
{
base.OnDeactivated(sender, args);
// Ok, the game form was deactivated, we need to make it believe the form was activated just after deactivation.
if (!base.Active)
{
// Force activation by calling base.HostActivate private methods.
this.pActivate.Invoke(this, new object[] { sender, args });
}
}
}
Related
So, I as trying to create an "Open world exploration" game in C# WinForms, And while coding the mining, (which works just fine), I encountered a problem with saving the number of broken blocks to the inventory (a label). Basically, for every block player breaks, it gets added to the inventory as inventoryWrite.Text = $"Grass: {grassHolder}, Rock: {rockHolder}";.
Now, the thing is, sometimes, even though I use the ++ operator, it adds up to 4 to the inventory. I'm citing the code below.
private void Remove(object sender, EventArgs e, PictureBox itm)
{
if (itm.BorderStyle == BorderStyle.FixedSingle)
{
if (itm.Tag.Equals("grass") && items.Contains(itm))
{
grassHolder++;
itm.Tag = "";
}
if (itm.Tag.Equals("rock") && items.Contains(itm))
{
rockHolder++;
itm.Tag = "";
}
if (itm.Tag.Equals("dio") && items.Contains(itm))
{
dioHolder++;
itm.Tag = "";
}
this.Controls.Remove(itm);
items.Remove(itm);
}
}
I update the inventory in a public loop, don't worry about that (interval is 1ms). But I don't think that's the problem, since I tried putting it in the Remove() function, and nothing seemed to change.
I've even double locked the if statement, but nothing! It still adds more than 1. Can anybody tell me how to solve this? Thank you a lot.
EDIT:
As a reply to Ronald's comment, the if statement is called ONLY when the block is selected. ONLY once when the method is called.
There are too many points to cover in a comment and so I've had to enter an answer.
In itself the ++ operator is not the issue and will always behave as it should, but as someone reviewing a small piece of code the following points crop up.
grassHolder, rockHolder, dioHolder appear to have
accessibility beyond this function and so could be altered
elsewhere.
Function void Remove(object sender, EventArgs e, PictureBox itm) appears to be an event handler and yet there is no locking mechanism to ensure that the externally accessible parameters are not changed or used elsewhere whilst the function code is executed. Specifically items which is appears to be a collection of sorts and is used both in logic to determine whether parameters in (1) are incremented, but also has its contents changed within the function.
From comments made it would appear that this logic is run in
response to user interaction, maybe by use of a mouse button or key
event. Is this base event de-bounced to ensure that multiple
triggers aren't handled?
Your statement "saving the number of broken blocks to the inventory (a label)." Implies that you are storing game data within the UI. This should be avoided as it ties game data directly to the UI implementation and therefore makes it difficult to alter the game, but also ties any handling of game data directly to the UI thread.
Recommended actions:
Ensure that the parameters in question are not accessed and altered
elsewhere causing the issue seen.
Utilize a lock(x) statement to ensure that items is not changed
whilst this function is being executed. More information here
De-bounce the mouse button or key click that triggers this function
to ensure that multiple events aren't triggered. This is performed
by placing a minimum time between event triggers. A minimum time
period of say 150ms would be a good starting point. This would equate to a reasonably quick, conscious user action, but be slower than multiple events triggered by partial/poor switch contact. Incidentally this is especially true on touch screen interfaces.
Consider controlling access to global parameters through use of
access functions. For example
int IncrementRockHolder(){ rockHolder++;} Although implementation may appear onerous, they can greatly help with debugging as call stack information is then available showing what code is calling the function and thus making the change.
Implement a game engine class to control access to game data and implement game logic. This
would allow you to unit test game functionality whilst also freeing
it from UI implementation and restrictions.
How often is while(true) called in C# Unity? Is it like Update(), where it's called every frame?
It will recurse infinity in a single frame unless there is a break or yield (coroutine). With a coroutine if you do something like
yield return null;
it will continue the next frame.
It will keep going within one frame drawing out the frame time to infinity. Unbroken, it will crash the editor or, if in a full build, the game.
The answer is once ... the frame where while(true) is entered, assuming it has no break/return or other mechanism to stop it, will be the last frame before Unity crashes to your desktop, probably with no warning or error message.
I've crashed Unity before with accidental recursion, like writing public int Number => Number; instead of public int Number => number; (property that returns itself to itself infinitely) and Unity just crashes, silently. And it can be hard to find something like that after you've copied and pasted some code around. Infinite loops/recursion are basically fatal to Unity on the main thread.
You probably picked up that while(true) idea from a scripting language for a much simpler game engine where it handles a lot of stuff behind the scenes for you. I've seen it before in "3D Game Studio" engine, many, many years ago, in their "Lite C" scripting language. You'd simply put while(1) and it would run an iteration of your script loop on each frame and shut it down for you when it ended, very conveniently. But you can't do that in C#. Even though Unity calls it "scripting", C# is still a compiled programming language and it does exactly what you tell it to do. And while(true) is telling it "Repeat this loop until true is no longer true" (which means forever), so the loop never ends (unless you use break, return or something else to explicitly stop it).
I'm trying to make a model that acts like sub-atomic particles for an interesting project. I understand that C# isn't exactly the best coding language for this kind of undertaking, however since I'm pretty newish to coding and only now C# and Java I decided I would just try on C#.
Currently what I'm trying to do is get the ovalShape, representing a particle, to passively move towards oppositely charged particles. To get this to run in the background all the time I decided to use threads, but when I ran my simple test for proof of concept of moving the ovalshape with a thread, it didnt move at all and I don't understand why.
I set up the thread normally using
Thread thrFOA = new Thread(new ThreadStart(ForceOfAttraction));
and then made my test background function:
public void ForceOfAttraction()
{
ovalShape1.SetBounds(ovalShape1.Location.X + 1, ovalShape1.Location.Y, ovalShape1.Width, ovalShape1.Height);
ovalShape1.Refresh();
}
So I thought this should just make it so that the oval slowly moves across the screen, being moved a pixel at a time, however there was no movement at all and I don't understand why not. I also tried this.Refresh(); instead of ovalShape1.Refresh(); as it is in the form class, but the same result.
I appreciate the time and help, thanks!
I found a memory leak in my XNA 4.0 application written in C#. The program needs to run for a long time (days) but it runs out of memory over the course of several hours and crashes. Opening Task Manager and watching the memory footprint, every second another 20-30 KB of memory is allocated to my program until it runs out. I believe the memory leak occurs when I set the BasicEffect.Texture property because that is the statement that finally throws the OutOfMemory exception.
The program has around 300 large (512px) textures stored in memory as Texture2D objects. The textures are not square or even powers of 2 - e.g. can be 512x431 - one side is always 512px. These objects are created only at initialization, so I am fairly confident it is not caused by creating/destroying Texture2D objects dynamically. Some interface elements create their own textures, but only ever in a constructor, and these interface elements are never removed from the program.
I am rendering texture mapped triangles. Before each object is rendered with triangles, I set the BasicEffect.Texture property to the already created Texture2D object and the BasicEffect.TextureEnabled property to true. I apply the BasicEffect in between each of these calls with BasicEffect.CurrentTechnique.Passes[0].Apply() - I'm aware that I'm calling Apply() twice as much as I should, but the code is wrapped inside of a helper class that calls Apply() whenever any property of BasicEffect changes.
I am using a single BasicEffect class for the entire application and I change its properties and call Apply() any time I render an object.
First, could it be that changing the BasicEffect.Texture property and calling Apply() so many times is leaking memory?
Second, is this the proper way to render triangles with different textures? E.g. using a single BasicEffect and updating its properties?
This code is taken from a helper class so I've removed all the fluff and only included the pertinent XNA calls:
//single BasicEffect object for entire application
BasicEffect effect = new BasicEffect(graphicsDevice);
// loaded from file at initialization (before any Draw() is called)
Texture2D texture1 = new Texture2D("image1.jpg");
Texture2D texture2 = new Texture2D("image2.jpg");
// render object 1
if(effect.Texture != texture1) // effect.Texture eventually throws OutOfMemory exception
effect.Texture = texture1;
effect.CurrentTechnique.Passes[0].Apply();
effect.TextureEnabled = true;
effect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices1, 0, numVertices1, indices1, 0, numTriangles1);
// render object 2
if(effect.Texture != texture2)
effect.Texture = texture2;
effect.CurrentTechnique.Passes[0].Apply();
effect.TextureEnabled = true;
effect.CurrentTechnique.Passes[0].Apply();
graphicsDevice.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, vertices2, 0, numVertices2, indices2, 0, numTriangles2);
It's an XNA application, so 60 times per second I call my Draw method, which renders all my various interface elements. This means that I could be drawing between 100-200 textures per frame, and the more textures I draw, the faster I run out of memory, even though I am not calling new anywhere in the update/draw loops. I am more experienced with OpenGL than DirectX, so clearly something is happening behind the scenes that is creating unmanaged memory I'm not aware of.
My only suggestion to you that I can come up with, is to group your textures into atlases rather than one by one. It will speed up your rendering time and reduce the load on the GPU, provided that you are rendering a massive amount of textures per frame. The reason for this, is because the GPU will not have to swap textures to render so often which is an expensive operation. I am using my knowledge of OpenGL, but my guess is that XNA is based on DirectX and I am assuming they load textures in a similar manner (unless you are using Monogame which lets you use OpenGL)
That said, you did not provide very much information. The memory leak can be coming from the texture switching, but it can also be coming from somewhere else. Most of your memory is occupied with textures, which is probably why you are getting a crash there rather than somewhere else. I am guessing a few things are happening here:
The garbage collector is not working fast enough to pick up all the RAM being allocated inside the rendering functions
You have a memory leak somewhere else in your code, and it is showing up here instead
Once again, it is difficult to figure out what is on here provided how little I know about your code. But to my best ability, I have a few suggestions for you:
Run through your code and look at how you are referecing things. Make sure that you don't have any temporary references inside of classes and structs. If you use something and pass it around to difference classes and consider it later as "discarded", there is good chance that someone is still holding onto that object, preventing it from being deleted
Do a search for all the "new" keywords you have in the solution. If you have something that constantly gets using the "new" keyword, this can be a huge memory leak as it's creating a massive ammount of objects in the heap. The garbage collector SHOULD be picking them up, but I wouldn't say I trust the garbage collector very much. Worst case that garbage collector is not coming around often enough to deal with this memory leak.
Find ways to reduce the sizes of textures. Atlasing is a solution that will reduce the overhead of packaging each texture in it's own Texture2D. This can be a bit more work because you will have to work in a system of swapping textures from the same file, but in your case that very well maybe worth it.
If you are convinced that there is an issue within XNA, try a different implementation called Monogame. It follows the exact same structure as XNA but is maintained by a community. As a result, the guts of the libraries you are using have been rewritten and there is a good chance that whatever is destroying your heap has been fixed.
My advice to you? If you are really familiar with OpenGL and what you are doing is fairly simple, then I would check out OpenTK. it is a thin linker layer that takes OpenGL and "ports" it into C#. All the commands are the exact same and you have the flexibility of using the entire .NET library for all the extra fluff.
I hope this helps!
I have a list of entities which implement an ICollidable interface. This interface is used to resolve collisions between entities. My entities are thus:
Players
Enemies
Projectiles
Items
Tiles
On each game update (about 60 t/s), I am clearing the list and adding the current entities based on the game state. I am accomplishing this via:
collidableEntities.Clear();
collidableEntities.AddRange(players);
collidableEntities.AddRange(enemies);
collidableEntities.AddRange(projectiles);
collidableEntities.AddRange(items);
collidableEntities.AddRange(camera.VisibleTiles);
Everything works fine until I add the visible tiles to the list. The first ~1-2 seconds of running the game loop causes a visible hiccup that delays drawing (so I can see a jitter in the rendering). I can literally remove/add the line that adds the tiles and see the jitter occur and not occur, so I have narrowed it down to that line.
My question is, why? The list of VisibleTiles is about 450-500 tiles, so it's really not that much data. Each tile contains a Texture2D (image) and a Vector2 (position) to determine what is rendered and where. I'm going to keep looking, but from the top of my head, I can't understand why only the first 1-2 seconds hiccups but is then smooth from there on out.
Any advice is appreciated.
Update
I have tried increasing the initial capacity to an approximate amount of elements, but no difference was observed.
Update
As requested, here is the code for camera.VisibleTiles
public List<Tile>
{
get { return this.visibleTiles; }
}
Whenever you have a performance issue like this, the correct response is not to guess at what possible causes might be; the correct response is to profile the application. There are a number of options available; I'm sure you can find suggestions here on StackOverflow.
However, I'm feeling lucky today, so I'm going to ignore the advice I just gave you and take a wild guess. I will explain my reasoning, which I hope will be helpful in diagnosing such problems in the future.
The fact that the problem you describe only happens once and only at the beginning of gameplay leads me to believe that it's not anything inherent to the functionality of the list itself, or of the collision logic. This is assuming, of course, that the number of objects in the list is basically constant across this period of time. If it was caused by either of these, I would expect it to happen every frame.
Therefore I suspect the garbage collector. You're likely to see GC happening right at the beginning of the game-in other words, right after you've loaded all of your massive assets into memory. You're also likely to see it happen at seemingly random points in the code, because any object you allocate can theoretically push it over the edge into a collection.
My guess is this: when you load your game, the assets you create are generating a large amount of collection pressure which is nonetheless not sufficient to trigger a collection. As you allocate objects during the course of gameplay (in this case, as a result of resizing the list), it is increasing the collection pressure to the point where the GC finally decides to activate, causing the jitter you observe. Once the GC has run, and all of the appropriate objects have been relegated to their correct generations, the jitter stops.
As I said, this is just a guess, albeit an educated one. It is, however, simple to test. Add a call to GC.Collect(2) prior to entering your render loop. If I'm right, the jitter should go away.
If you want to be more thorough than that-and I highly recommend it-Microsoft provides a tool which is useful for debugging memory issues, the CLR Profiler. This tool will show you exactly when collections are occurring and why. It's very useful for XNA development.
1-2 seconds may be caused by GC adjusting sizes of each generation. Look at corresponding perf counters and see if there is large number of Gen1/2 collections in first seconds (minimizing GC is useful goal for games)
Additional random guess: all your objects are struct for whatever reason. And very large. So copying them takes long time. (would not explain smoothing out after first seconds)
Notes:
instead of merging items in single list consider creating iterator that will avoid all copying.
get profiler
learn to look at perf counters for your process. Interesting categories are memory, GC, CPU, handlers.
You can use an overloaded constructor for List<T> to initialize the list with a predefined size:
var collidableEntities = new List<object>(500);