In agar.io, how much overlap is needed to eat another player or virus?

Let

  • R = the radius of the larger circle
  • r = the radius of the smaller circle
  • d = the distance between the centers

When two circles touch (d < R + r), nothing happens. However, I noticed that even when the center of a smaller circle is in a larger circle (d < R), nothing happens until they move slightly closer.

What is the condition for eating other objects? How much overlap is needed?


There is a clone of the game available on Github, however it may be modified from the original game. It's stated in the description that the real game is closed source, and that this clone is for people who would like to play their own version of the game with whatever modifications they wish to make. That being said, I have no reason to think that someone would have altered this portion of the code below to change how collisions work.

There is a function called collisionCheck, which I believe to be the section of code that controls if you will be consumed or not by another user. Looking at it, it performs some math using the two users X and Y coordinates, and then also checks if the User's radius is larger than the others.

function collisionCheck(collision) {
    if (collision.aUser.mass > collision.bUser.mass * 1.1  && collision.aUser.radius > Math.sqrt(Math.pow(collision.aUser.x - collision.bUser.x, 2) + Math.pow(collision.aUser.y - collision.bUser.y, 2))*1.75) {
        console.log('[DEBUG] Killing user: ' + collision.bUser.id);
        console.log('[DEBUG] Collision info:');
        console.log(collision);

        var numUser = util.findIndex(users, collision.bUser.id);
        if (numUser > -1) {
            if(users[numUser].cells.length > 1) {
                users[numUser].massTotal -= collision.bUser.mass;
                users[numUser].cells.splice(collision.bUser.num, 1);
            } else {
                users.splice(numUser, 1);
                io.emit('playerDied', { name: collision.bUser.name });
                sockets[collision.bUser.id].emit('RIP');
            }
        }
        currentPlayer.massTotal += collision.bUser.mass;
        collision.aUser.mass += collision.bUser.mass;
    }
}

What we want to examine more is the if statement at the top:

if (collision.aUser.mass > collision.bUser.mass * 1.1  && collision.aUser.radius > Math.sqrt(Math.pow(collision.aUser.x - collision.bUser.x, 2) + Math.pow(collision.aUser.y - collision.bUser.y, 2))*1.75)

What this is saying is:

  • If User A's mass is greater than User B's mass times 1.1 (110% of User B's mass)

AND

  • User A's Radius is greater than the square root of User A's X coordinate minus User B's X coordinate to the power of 2 plus User A's Y coordinate minus User B's Y coordinate to the power of 2 multiplied by 1.75.

I think what you are primarily interested in is the second portion of the if (the part after the &&), since you want to know how much overlap is needed. For this, lets make an example.

  • User A's X Coordinate: 50
  • User A's Y Coordinate: 100
  • User A's Radius: 50
  • User A's Mass: 100
  • User B's X Coordinate: 75
  • User B's Y Coordinate: 120
  • User B's Mass: 90

Lets plug these values into the part of the if statement that follows the &&:

Math.sqrt(Math.Pow(50 - 75, 2) + Math.Pow(100 - 120, 2)) * 1.75 = ~42.35

Now lets look at the rest of the if statement, with our answer of ~42.35 put in place, as well as the other variables above:

if (100 > 99 && 50 > 42.35) { //User A's Mass > User B's Mass * 1.1 and User A's Radius > The evaluation made above

 //do the stuff in here

}

So, when the expression inside of the if evaluates to true, it will drop down into the statements code block, and run any code in there. For this statement, it looks like it outputs some text to the console, takes User B out of the game, does some other if statement logic (I'm not quite sure what), and adds User B's mass to User A's mass. So to answer how much overlap is needed, I suppose the correct answer would be if User A's Radius is greater than the square root of User A's X coordinate minus User B's X coordinate to the power of 2 plus User A's Y coordinate minus User B's Y coordinate to the power of 2 multiplied by 1.75. Don't forget however, that User A's mass must also be greater than 110% of User B's mass.

For viruses, I believe your mass only has to be larger than the Viruses mass for it to split you. The Wiki for viruses states this, and that is what is appears to be from actually playing the game. I think the code for this is:

if(virusCollision > 0 && currentCell.mass > virus[virusCollision].mass) {
          sockets[currentPlayer.id].emit('virusSplit', z);
          virus.splice(virusCollision, 1);
        }

Edit:

How Mass is calculated:

I found this bit of code in a different javascript file called util.js. It is referenced a lot in the server.js file, which is where the code above is from. Based off the comment in the code, this looks like how mass is determined:

// determine mass from radius of circle
exports.massToRadius = function (mass) {
    return 4 + Math.sqrt(mass) * 6;
};

It seems to be the square root of the mass of the player times 6 plus 4. All players start with a defaultPlayerMass of 10, which can viewed in the config.json file.


Here's a summary of Timmy Jim's answer for an agar.io clone.

  • (R-4)² > 1.1(r-4)² and 1.75d < R to eat players
  • d < R to eat viruses

Interestingly, d < R - r when the small circle is entirely inside the large circle. 1.75d < R means when R > 7r/3 (the larger circle is 2.3x larger in radius, or ~5.4x larger in mass), the small circle can survive even if it's entirely inside the large one.