node.js game CPU usage
As I wrote in a comment, changing the code here won't change zlib usage, as that's something that's happening at a lower level. Still, I wanted to review the code. However, as TastyLemons rightfully notes in a comment, if you can simply send less stuff all the time, it'll help. But with that much CPU usage for zlib, I'm guessing there's something wonky in the node/zlib/server configuration.

For the first loop (users loop):


That is a very long and complex if condition! And it's filled with magic numbers, as well as numbers that I assume you don't need to calculate over and over again.
The object you're building is mostly the same in both the inner branches, so it'd be easier to build the common part first, and then only add the parts that differ.
There are other small changes that would make things simpler, like setting the dying boolean in the object before pushing it to the array.
You can make good use of the map and filter array methods


For the condition, you're checking if the user is in the same room, and in view of the u user (Sidenote: u is not a terribly descriptive label, and it doesn't help that you sometimes use player and other times use user to refer to the same kind of entity).

I'd make that a method, for instance on the User prototype, if you have such a thing:

User.prototype.canSee = function (otherUser) {
  // initial check
  if(this.room !== otherUser.room) {
    return false;
  }

  // x and y distances between user and other's "radius"
  var dx = Math.abs(otherUser.x - this.x) - otherUser.radius,
      dy = Math.abs(otherUser.y - this.y) - otherUser.radius;

  return dx &lt;= this.xViewDistance &amp;&amp; dx &lt;= this.yViewDistance;
};


(if you don't have a User prototype, you can change the function to be a plain function that takes two arguments.)

I'm assuming here, that the *ViewDistance values are already calculated, since I imagine they don't really change (or at least don't change all the time). So if the screenWidth doesn't change much, you could calculate a screenHalfWidth and keep it around, so you don't always have to divide by 2 to get the same result. And the 20 needs to be a needs constant (I know JS doesn't have constants; I mean a variable you treat as constant). Something like SCREEN_WIDTH_MARGIN and maybe a similar thing for height.

So xViewDistance might be defined as user.screenHalfWidth - SCREEN_WIDTH_MARGIN, which itself is a value that probably won't change all the time, and can thus be stored.

Point is, you end up with code, where:


your magic numbers are labelled so you know what they mean
your magic numbers are defined in exactly 1 place, so you only need to hunt down the same number in 23 different places if it needs to change
calculations are done once, and the results stored, rather than recalculated constantly despite not having changed.


For building the objects I'd again suggest a method on the User prototype (though again, it can also be a function that just takes an argument). Something like:

User.prototype.getInfo = function (isPlayer) {
  var info = {
    x: this.x,
    y: this.y,
    angle: this.angle,
    hue: this.hue,
    radius: this.radius,
    squeeze: this.squeeze,
    name: this.name,
    dead: this.dead,
    dying: this.dying
  };

  if(isPlayer) {
    info.isPlayer = true;
    info.kills = this.kills;
  }

  return info;
};


Putting it together, you might get:

var visibleUsers = users.filter(function (user) {
  return user.id === currentUser.id || currentUser.canSee(user);
}).map(function (user) {
  return user.getInfo(user.id === currentUser.id);
});


That's everyone's info, including the current user/the player, ready to be sent.

For the energies, the story's similar: Add some methods/functions to do the heavy lifting, and use filter/map to iterate the array. Only trick is that if firstSend is true, we could really skip the filter function, but I've left it pretty much as-is:

var visibleEnergies = energies.filter(function (energy) {
  return currentUser.firstSend || (energy.updated &amp;&amp; energy.room === currentUser.room);
}).map(function (energy) {
  var info = energy.getInfo();
  info.anim = info.anim || currentUser.firstSend; // override anim if necessary
  return info;
});