From Armagetron
Revision as of 19:12, 23 August 2021 by Cadillac (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

You have a gauge for it, but you don't know what it means. Or, you know what it means, but you think it's stupid. Here's what rubber is all about and why it's important.


Rubber exists to compensate for network latency. That is, it's there to deal with the fact that when you hit a wall, and the server thinks you've hit the wall, it's a physical impossibility for you to be certain you're near the wall. So rubber makes it possible. In short, without rubber, there would be no internet game. Once upon a time, it was an internal mechanism that existed for server administrators to configure, allowing them to build different types of servers that were playable that might otherwise not have been so. It was never intended to be revealed to the player as a concept. Part of that is because different mechanisms to accomplish the same thing could be implemented, and the player never need deal with it. Now it's become a part of the game and players are aware of it, and knowing what it is and what it isn't is an important part of playing the game.

What Rubber Is

As mentioned in the introduction, rubber is a way to deal with network latency. It's very simple in concept, when you think about it. Let's say you connect to a server and your ping is 200 milliseconds. Now, some other guy and you are racing towards each other. Just before you would pass each other, the other guy turns and blocks your path. It will take you 200 milliseconds to get aware of this and send your reaction back to the server, assuming you yourself can react instantly. Of course, you don't have 200 milliseconds, you'll collide and be dead in 100 milliseconds.

Enter: rubber. When you get close to a wall, rubber artificially slows your cycle at a certain distance from the wall. This change in speed is artificial, it doesn't affect your actual speed in any way. But the time it takes for you to crash against that wall is stretched. By making this stretch, it is possible for you to see that you are in fact touching the enemy wall that popped up in front of you, and to react to it, all in the 200 milliseconds your hypothetical connection has to send a turn to the server.

What Rubber Isn't

Rubber is nothing other than what it is. It is not a tool to make it possible to turn around against a wall. It is not a way to make it easier to get close to a wall. It is not a new type of gameplay. It is none of these things.

How Rubber Works

Rubber works two ways, depending on how the server is configured. You either have time-based rubber or distance-based rubber. Time-based rubber works by measuring how long (in milliseconds) it will take for you to hit the wall and applying rubber to it. Distance-based rubber works by measuring the actual distance between you and the wall. Both have the same intent, but work slightly differently.

Distance-based rubber is good for servers that have very little changes in speed. Some examples are the Tigers Classic servers, the Goshdarn clones, and a few others. Low cycle acceleration is what distance-based rubber is good for. And it's really good for that! This is the traditional behavior of rubber, and until v0.2.8 it was the only behavior of rubber available.

Time-based rubber is good for servers that have a lot of cycle acceleration, resulting in large differences in speed between cycles. In this case, the application of rubber will vary for each wall approach, but it will behave consistently and predictably for players.

After rubber kicks in, it begins to deplete. When it is depleted, you are touching the wall and the server destroys your cycle. When you leave the wall, you begin to recharge your available rubber until it is full. This unique system makes it possible to carefully plan a wall approach, run your rubber up to its maximum, and turn, making a very tight grind against that wall. Then, if you wish to turn towards the wall again too quickly afterwards, you will die, because you don't have enough rubber. In a tight maze, this means you might make the first couple of turns, but your chances of surviving drop with each grind because your rubber cannot recharge fast enough.

Rubber Settings

There are a number of settings that affect rubber. In a perfect world, you would only ever work with CYCLE_RUBBER, and all other settings will be left as they are. This is not, however, a perfect world. It may be necessary to work with some of the other settings in order to get the type of gameplay you are after. The rule of thumb is that you should only adjust any of these settings in order to compensate for other changes that cause the rubber system to break down. For example, if you change cycle acceleration to some really high amount, you will have a server where high speed players will tend to crash because they lack rubber. You probably want high speed players to be able to grind as easily as low speed players, so you might want to increase CYCLE_RUBBER to compensate. The flip side is that lower speed players will be able to grind deeper against the wall. There's always a trade-off, so consider carefully what you are after.

It is generally considered a bad idea to increase rubber too terribly high. If you set it high enough, you can make death impossible on your server, and that's probably not a good thing. On the other hand, if you set it too low (or to a negative number), you make living impossible on your server. So you should only adjust rubber when it's needed to compensate for some other change you've made in your server.

Here is a brief description of each rubber setting available as of v0.2.8:

niceness when hitting a wall
niceness when hitting a wall: bonus for higher ping players
rubber usage is based on distance travelled if this is set to 0 (default) and the time passed if this is set to 1. Intermediate values and values out of these bounds are supported as well.
logarithmic speed of wall approximation when rubber is in effect (every second, you get closer to the wall by a factor of ~0.4^{this value} )
The minimal distance rubber code keeps cycles from walls
Additional distance for every length unit of the wall you have in front of you
Addidional distance if you have an empty rubber meter (gets faded out gradually as you use up all your rubber)
Additional distance for unprepared grinds; it gets applied when the cycle's last turn was just a fraction of a second ago and faded out preparation times larger than CYCLE_RUBBER_MINDISTANCE_PREPARATION.
Timescale in seconds a cycle's last turn time is compared with to determine the effect of CYCLE_RUBBER_MINDISTANCE_UNPREPARED.
the cycle's width. Attempts to enter tunnels that are narrower than this result in instant death. (not yet supported)
when adjusting to or 180ing into a wall, allow going closer by at least this amount (relative to the last distance)
fallback to old, frame-dependant rubber code when old clients are present
Timescale rubber is restored on
during this fraction of the cycle delay time, rubber efficiency will be multiplied...
by this factor (meaning that rubber usage goes up by the inverse; a value of zero means rubber is completely disabled)

Inner Rubber Workings

The original post by z-man may be found here — this is an edited version.

As you know, your speed gets decreased a bit on every turn by 5%. This factor can now be tuned in CYCLE_TURN_SPEED_FACTOR. It's the numerical value the speed gets multiplied with. Make it bigger than one if you like weird settings.

The Rubber Code

There's a new property called rubber effectiveness. It's usually a value between 0 and 1. If a certain action consumes x rubber, at effectivity e it will consume x/e rubber. At effectivity 0, rubber gets disabled completely. At default settings, rubber effectivity is constant and always 1. Two things possibly influence the effectivity of rubber:

  • Shortly after you make a turn, a certain portion of the time (given by CYCLE_RUBBER_DELAY) until you are legally allowed to make your next turn determined by CYCLE_DELAY, the effectivity gets multiplied by CYCLE_RUBBER_DELAY_BONUS (Hmmm. We should rename that to _FACTOR, _BONUS sounds too positive). The logical use of this mechanism is to punish 180s and adjusts by higher rubber usage or death.
  • Then there is another state variable, the rubber malus. Initially it is set to 0. On every turn, CYCLE_RUBBER_MALUS_TURN gets added. It decays over the time of CYCLE_RUBBER_MALUS_TIME seconds. The rubber effectiveness gets divided by 1 + rubber malus. This setting is to punish to hectic turning and repeated 180s. (or to provoke floating point chaos if you make CYCLE_RUBBER_MALUS_TURN negative). The new experimental red rubber gauge displays 100/(1+malus), it should display the full effectivity in the end. (Umm, would that rather be efficiency? Definition lawyers, please to the rescue!)

<Comment: either use 'efficiency' or 'effectiveness', both good. On the other hand, 'effectivity' is poor English (at least from a UK Englishman point of view, YMMV in the USA)>

The time rubber decays on (formerly hardcoded 10 seconds) can now be controlled by CYCLE_RUBBER_TIME. Setting it to 0 will disable the decay. New clients will sync the rubber state and brake reservoir from the server, old clients will display horribly wrong values if you play with the settings too much.

Experimental Settings

Those were the new experimental settings, that's why they are not yet documented.

There is the way rubber prevents you from hitting walls. Formerly, if you got close to a wall, the rubber code would allow you to cut the distance to it in half. The new code (from will not let you closer to a wall than determined by the _MINDISTANCE settings.


  • right after a turn, you are always allowed to go a bit forward. How much is determined by CYCLE_RUBBER_MINADJUST, useful values are between 0 and 1. Values bigger than 1 will also kill all 180ers. Setting _MIDISTANCE to a small negative value is another way of punishing all kinds of rubber whores, because then rubber will stop you only a bit after the wall, while making you slower before the hit and therefore still faciliating grinding to an extent. (Not recommended right now because the old clients will ignore it.)
  • The speed at which you approach a wall is determined by CYCLE_RUBBER_SPEED. Mathematically, if you are at distance d from a wall, rubber makes sure you don't approach it faster than CYCLE_RUBBER_SPEED * d.
  • Since this speed of approaching may be slower or faster than with the old code depending on the framerate, people complain about it. Therefore the new client reverts back to almost the old code ( a tiny minimal distance to walls is still kept ) when any pre- server or client is involved. The server admin can disable this admittedly dangerous behavior with CYCLE_RUBBER_LEGACY 0.

Client Synchronization Settings

Old servers would send all cycle syncs once per second. Since, the interval is configurable separately for the client that owns a cycle and all other clients in the CYCLE_SYNC_INTERVAL_ settings.

New clients since send the time of turn commands to the server. This makes it possible to avoid grinding lag sliding ( you move towards a wall, grind it shortly and turn away again, and you'll slide ) by letting the cycle on the server turn not before the time sent by the client. At the low speeds before the grind, the positional command interpretion is inaccurate and will usually turn the cycle too early. Now, old clients don't send the command time, so this code can't work. The lag sliding is a clear disadvantage, but the earlier turn is an advantage in some situations because it makes you cover more ground, so both the new and the old players have plenty of reason to complain if they are not treated equally. Therefore, when CYCLE_FAIR_ANTILAG is set to 1 and old clients are present, this code is deactivated.

When a cycle turns in free space, the server will try to follow the client's request by matching the turn position as closely as possible. Sometimes however there are large desyncs and clients sent silly turns halfway across the grid from their current position. So, for clients that send the command time, the server will execute turns only in a time window around that command time. The width of that window is determined by CYCLE_TIME_TOLERANCE.

I observed that old clients ( and earlier ) would be more likely to pass through walls when they received a sync from the server shortly before. So, if you set CYCLE_AVOID_OLDCLIENT_BAD_SYNC to 1, the server will not send those syncs. Whether this helps or makes matters worse by not sending enough syncs is unknown, that's why it is a setting.

The other new settings are purely local and don't have gameplay relevance on the server.