p2.js icon indicating copy to clipboard operation
p2.js copied to clipboard

Wiki page idea: high-level optimization advice

Open danneu opened this issue 8 years ago • 1 comments

It'd be a great asset to the community if there was a high-level bulleted-list / check-list of sorts that enumerates the various optimizations to consider, ideally with some sample implementation, from simple to advanced.

I reckon a lot of people are like me, kind faking it til they make it with their physics simulation, and could use some preliminary guidance and examples to get into the headspace of optimizing a physics simulation and where to find the low-hanging fruit.

For example, in which cases would one use shape.sensor = true vs shape.collisionResponse = false, and what's the actual impact of them?

I'm definitely not in a position to write such a list, but here are some examples that might not be accurate -- just for demonstration:

  • Reduce the amount of shapes and bodies when you can.
    Example: Instead of creating a fixed-size p2.Box for each collidable wall-tile in your map, replace lines of adjacent tiles with a single p2.Box that spans all of those tiles.

  • Use collision groups and masks to avoid extraneous collision calculations. Example: If your game has a red team and a blue team, and players on the same team cannot shoot each other (no friendly-fire), then the simulation would be doing extra work by checking for collisions between red team's bombs and red team's players. Instead, you can use groups/masks like this: [flesh out with better code example]:

    redPlayer.collisionGroup = RED_PLAYER
    redPlayer.collisionGroup = WALL | BLUE_BOMB
    redBomb.collisionGroup = RED_BOMB
    redBomb.collisionMask = WALL | BLUE_PLAYER 
    
  • [Explain broadphase vs narrowphase and how/why you'd want to filter out bodies in the broadphase]. Outdated, but a good example of an easy to understand explanation: http://paulsalaets.com/posts/selecting-broadphase-p2

  • How to profile your p2 simulation.

danneu avatar Jul 28 '16 17:07 danneu

Good idea! I think the list could become pretty long and contain many game-genre specific things...

Some things I'd like to add to the list:

  • Use larger timesteps (fixedDeltaTime).
    For example, running world.step(fixedDeltaTime, deltaTime, maxSubSteps) with fixedDeltaTime=0.2 instead of 0.1 will improve performance with 2x! On the other hand, it can make your collisions spongy and allow more penetration. If so, try reducing velocity of your objects, or reducing gravity a bit.

  • Reduce the number of solver iterations

    world.solver.iterations = 3; // Fast, but contacts might look squishy...
    world.solver.iterations = 10; // Slow, but contacts look better!
    
  • Use simplified collision shapes.
    The simplest collision shapes are best for performance. If you can use a p2.Circle instead of a p2.Convex for your player shape, then you should.

  • Turn off friction.
    If you don't need friction for an object, then turn it off. Just set myContactMaterial.friction=0. This will reduce the load on the solver.

  • Enable sleeping
    If an object is not moving, it can be automatically deactivated by using the following code.

    body.allowSleep = true;
    body.sleepSpeedLimit = 1; // Body will feel sleepy if speed < 1
    body.sleepTimeLimit =  1; // Body falls asleep after being sleepy for 1s
    world.sleepMode = p2.World.BODY_SLEEPING;
    

    If you need to make sure a body is activated, just run body.wakeUp();.

  • Remove bodies from the world when they don't need to be simulated. Example: if you're making a large game world, or a game with multiple rooms, you can easily remove physics objects that the player doesn't see on the screen.

    var distanceToPlayer = p2.vec2.distance(playerBody.position, enemyBody.position);
    var isAddedToWorld = enemyBody.world !== null;
    if(distanceToPlayer < 20 && !isAddedToWorld){
        // Enemy is close to the player.
        world.addBody(enemyBody);
    } else if(distanceToPlayer > 20 && isAddedToWorld){
        // Enemy is far away from the player.
        world.removeBody(enemyBody);
    }
    

What do you think?

Any ideas for the format of the "How to profile" part?

schteppe avatar Aug 17 '16 13:08 schteppe