Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
gdevelop5:events:draft-optimization [2020/03/18 00:27]
bouh
gdevelop5:events:draft-optimization [2020/11/15 19:51] (current)
bouh
Line 1: Line 1:
-<note important>​This page is a draft for good rule to apply for optimize a game.</​note>​ +<note important>​This page is a draft for good practices ​to apply for optimizing GDevelop games.</​note>​ 
-<note warning>​This ​is a draft in progress ​@Bouh</​note>​+<note warning>​This draft is WIP by @Bouh</​note>​
  
 +<note important>​
 +Could be merged with 
 +http://​wiki.compilgames.net/​doku.php/​gdevelop5/​tutorials/​how-to-debug-poor-performance
 +</​note>​
  
-Game optimization is an important concept of making a game. Good optimization will allow the game to work faster, making it more fluid. 
  
-GDevelop 5 gives you total freedom in eventsWhile this can be awesome, it can also be very costly if you don't have the reflex of build a good structure in your events, the processor can be overload when running ​the game, this can have for effect to slower your game.+Game optimization is an important concept of game developmentGood optimization will allow the game to work fastermaking it more fluid.
  
-It is important to [[gdevelop5:​tutorials:​basic-game-making-concepts|understand what events ​are]] and that all events ​are //each called once per second//.+GDevelop 5 gives you total freedom in events. While this can be awesome, it can also be very costly if you don't have the reflex of writing optimized ​events, as the processor could get overloaded when running the game. This would cause lag in the game.
  
-<​note>​For example: With a game at 60 frames per second (FPS), if you have a single event, without condition, and just one action, then this action ​will be executed 60 times in a second.</​note>​+It is important to [[gdevelop5:​tutorials:​basic-game-making-concepts|understand what events are]] and that all events are //called once every second// and //in the order they were written//​. 
 + 
 +<​note>​For example: With a game at 60 frames per second (FPS), if you have a single event, without condition, and just one action, then this action ​should ​be executed 60 times in a second.</​note>​
  
  
 ====== Optimization already in the engine ====== ====== Optimization already in the engine ======
-The GDevelop ​engine does one simple thing for optimizationit tells the graphic api to not render ​the object not in viewport.+GDevelop ​has built in optimizations,​ like //culling//, the process of automatically hiding off-screen objects. That way less is rendered and the render gets faster.
  
 This doesn'​t affect the person creating the game because it's handled in the background. It's totally transparent for everyone. This doesn'​t affect the person creating the game because it's handled in the background. It's totally transparent for everyone.
 +For example, when a sprite is off screen all the animations are paused.
  
-<​note>​It ​can still be important to hide or disable what you don't need. This is the key of the optimization.</​note>​+<​note>​It ​is still important to hide or disable what you don't need. This is the key to optimization.</​note>​
  
 +====== Optimizations you can perform ======
  
-====== Trigger once ======+===== Trigger once =====
  
-The **Tigger ​once** condition causes event actions ​to only run once each time the conditions have been met.+The **Trigger ​once** condition causes ​conditions preceding it in the same event to trigger ​only once every time they are met.
  
-Let's take an example ​where we want to create an object every time the mouse button ​is clicked. This will show you the wrong way and the right way to do it.+For example, if you want to create an object every time a click is done, this is what you should //​not// ​do:
  
 {{:​gdevelop5:​events:​bad_event_optimisation.png?​nolink|}} {{:​gdevelop5:​events:​bad_event_optimisation.png?​nolink|}}
  
-  * What should ​happen : When the mouse left button is pressed, an object is created called **MyObject**. +  * What is expected to happen: When the left mouse button is pressed, an object is created called **MyObject**. 
-  * What actually happens : When the mouse left button is pressed, ​multiple objects called ​**MyObject** are created.+  * What actually happens : As long as the mouse left button is pressed, **MyObject** ​instances ​are created.
  
-This occurs ​because when the mouse button is pressed, it is likely held down for longer than a single frame like 0.3 seconds. During this period of time the event is called multiple times, and the object is created more than once.+This is problematic ​because when the mouse button is pressed, it is likely held down for longer than a single frame like 0.3 seconds. During this period of time the event is called multiple times, and the object is created more than once.
  
-For fix that we need add the condition ​**Trigger once** ​in the condition.+To fix that we can use the **Trigger once** condition:
 {{:​gdevelop5:​events:​good_event_optimisation.png?​nolink|}} {{:​gdevelop5:​events:​good_event_optimisation.png?​nolink|}}
  
 +Now, the condition will trigger only once while it is true. That means that the event will fire only once every time it's condition goes from unfulfilled to fulfilled. It resolves the problem above as the condition will fire only the first frame of the click, and will wait for the click to end before letting the click event fire again.
  
  
 +===== Decativate unused behaviors =====
  
-====== ​Behaviors ​======+Behaviors ​take performance,​ especially the //​Pathfinding//​ and //Physic Engine 2.0// behaviors. Remember to disable them when they are not needed.
  
-There is multiple behaviors//​Pathfinding// ​and //Physic Engine 2.0// are the biggest consumers of power.+Let's take as example the following situation: I want 100 enemies to move to a position close to them every 2 seconds, and to take into account ​the wall obstacles.
  
-==== Delete ​the object unused ====+This would be an intuitive but wrong way to do it: 
 +{{:​gdevelop5:​events:​bad_behavior.png?​nolink|}} 
 +If you do this, all objects will move, including ​the ones that are off-screen.
  
-Let's take the example where I have a gun and I create one bullet when i do fire. +<note tip>Why calculate movement that the player won'​t ​see?</​note>​
-This bullet have a force toward a direction. +
-If you shot very often bullets will increase in number on scene and each have a physic. +
-If you didn'​t ​manage the bullets you will get some lag during the game. +
-The good solution is to delete the bullets if there is off screen.+
  
-An behavior ​exist **"​Destroy when outside ​of the screen"​** attach ​it on the bullet object. +Instead, you can limit the movement to visible objects. This can be done the following way: disable the Pathfinding ​behavior of the objects not visible in the viewport, and also enable ​it when they are visible in the viewport.
-All bullets moving offscreen will be deleted.+
  
-==== Disable ​the object unused ====+<note tip>​Don'​t forget trigger onces to make sure the behavior gets disabled or enabled only when it's state changes from not visible to visible or the other way around</​note>​
  
-Behaviors can be disable. +===== Delete unused objects =====
-This is perfect when you didn't need to affect the instance out of the screen.+
  
-Let's take the example ​where want 100 enemies to move to position each 2 seconds close to their taking into account the obstacles (For simulate guardian rounds with random paths)+Let's take as example ​the following situation:​ 
- +have gun and I create one bullet object instance when I press the key to fire
-Bad way is to move the enemies like this : +This bullet has a force toward a direction. 
-{{:​gdevelop5:​events:​bad_behavior.png?​nolink|}} +If the player shoots many bullets, their amount will increase on the scene and each one requires calculations of the force applied ​to them in the event loop
-If you do only this all objects will move, but maybe you don'​t ​need the objects ​are not in viewport+If you don'​t ​delete old bullet ​objects ​they will add up and take more and more performance causing lag to appear after playing for some time
- +The best solution ​is to delete ​the bullets that are off screen.
-<note tip>Why calculate something what we didn't see?</​note>​ +
- +
-Instead you can move only the object visible (in viewport), there is a simple way: +
- +
-- Disable ​the behavior Pathfinding of the objects not in viewport once time. +
-- And do the invert event, when the objects ​are in viewport, enable the behavior once time.+
  
 +The behavior **"​Destroy when outside of the screen"​** does just that. Attach it to an object, and all bullets that go off-screen will be deleted.
  
  
 <note important>​TODO <note important>​TODO
- 
-- no more 248px on image 
-- optimize sprite animation, reduce image almost similar is the animation. 
 </​note>​ </​note>​
  
- +- The smaller the images the smaller gets the rendering time. 
- +- Images bigger than 2000px may not work well especially on mobile devices where they may not load at all. 
- +- Reduce the number of frames of a sprite animation as much as possible, get rid of frames too similar to the one before and next. 
- +- Use the profiler in GD5 for see which events are taking the most of the performance to try and optimize it 
- +- Reduce number of conditions as object selection is a heavy process.
- +