You probably should add the "else if" anyway, because just because something works right sometimes doesn't mean it always works that way, especially with command timing issues, different amounts of processor load or timing across threads could actually cause it do something unexpected, e.g. if the spawn.spawning flag happens to be set quicker than your second function call one out of 10 times then it won't have predictable results.
There's also a fair bit of overhead in doing both function calls, and in a game where you get limited CPU you should use conditional branching effectively to minimize the CPU hit so you can cram more logic in, especially since this is interpreted JavaScript with no optimization:
Slower:
if ( !spawn.spawning && harvesters < 3 ) {
spawn.createCreep ( [ Game.CARRY, Game.WORK, Game.WORK, Game.MOVE, Game.MOVE ], 'harvester' + Game.time , { role : 'harvester' } );
}
if ( !spawn.spawning && builders < 3 ) {
spawn.createCreep ( [ Game.CARRY, Game.CARRY, Game.WORK, Game.WORK, Game.MOVE ], 'builder' + Game.time , { role : 'builder' } );
}
Faster
if ( !spawn.spawning )
{
if (harvesters < 3 )
spawn.createCreep ( [ Game.CARRY, Game.WORK, Game.WORK, Game.MOVE, Game.MOVE ], 'harvester' + Game.time , { role : 'harvester' });
else if (builders < 3 )
spawn.createCreep ( [ Game.CARRY, Game.CARRY, Game.WORK, Game.WORK, Game.MOVE ], 'builder' + Game.time , { role : 'builder' } );
}
This is faster because you only check spawn.spawning once per cycle, not twice, and if it spawns a harvester, you skip the check for builders altogether.
Worst-case scenario in the old version was 4 comparisons, two function calls (complete with pushing all the parameters to the stack), whereas worst-case now is 3 comparisions, and 1 function call. Function calls are where almost all the overhead are, because it has to save local state, then push the parameters, run the function then restore local state when the function returns.
Best-case scenario before was 2 comparisons, and in the new version it's one comparison.