rage
Tune the ragebot while you play: hit chance, minimum damage, the fire gate, which enemies it aims at, double precision and the stops.
On this page
rage lets a script improve the ragebot for the situation it sees. Lower the hit chance in the air, raise the minimum damage when the enemy is far away, hold a shot back until the player has slowed down, skip an enemy, switch double precision off for one tick, pick the stop style. The ragebot keeps doing the aiming and the shooting. The script gives it better numbers and better timing.
Everything a script sets through rage is a live value. It lasts 500 ms after the script's last call, then the ragebot is back on the user's own settings. Nothing is written into the config and the menu rows do not move.
What you can tune
| call | what it changes |
|---|---|
| rage.override_hitchance | the hit chance the ragebot asks for, 1 to 100 |
| rage.override_min_damage | the minimum damage, 1 to 110 |
| rage.hold_fire | holds the ragebot's shot back while you keep calling |
| rage.exclude | takes one enemy off the ragebot's target list |
| rage.override_double_precision | switches double precision off, or caps its chain |
| rage.override_auto_stop | switches the auto stop off, picks its style and its in-air condition |
| rage.override_quick_stop | skips the quick stop for a tick |
| rage.override_air_stop | skips the standalone air stop for a tick |
The resolver, which feeds the ragebot a yaw hint for an enemy and reads the shot results, has its own page: resolver.
How the calls behave
Return values. Every function answers true when the call was taken and false when the value was refused. A refused call changes nothing and does not refresh an earlier value. The functions never return a value of the ragebot: the script knows what it asked for, not what the ragebot did with it.
Errors. A missing argument is an ordinary Lua error with a fixed text. A wrong value, such as a string where a number is expected, NaN, infinity or an option name that does not exist, is answered with false.
Lifetime. Call the function every frame, in events.on_paint, for as long as you want the value. Repeating the same value costs nothing. A value goes back to the user's settings when the script stops calling, is unloaded, stops with an error, when the level changes, and, for rage.exclude, when the enemy dies or leaves.
Change numbers with intent. A number that changes every frame makes the auto stop start its plan again every tick. Use whole steps, for example 5 or 10, and change them at a moment that matters, such as the player leaving the ground.
The menu. The user's switches stay the user's. The hit chance number applies while the hit chance is switched on in the menu, and double precision and the stops are the ones the user has enabled. The minimum damage number switches the minimum damage on while the script asks for it. A key the user holds, a bind on the hit chance, the minimum damage, the stop style or the stop conditions, wins over the script's number for as long as it is held. Holds and off calls always apply while the script calls them.
Several scripts. For numbers (hit chance, minimum damage, stop style, in-air condition) the script that changed the value last wins, and a script that only repeats its value does not take over. Holds and off calls add up, so one script is enough. The double precision chain cap is the smallest of all. Excluded enemies are the union of every script. nil and false release only what the calling script set.
Cost. 20 instructions per call, 30 for rage.override_double_precision and rage.override_auto_stop. A script may make 128 rage calls per frame, accepted or not.
Functions
rage.override_hitchance
rage.override_hitchance(v) -> boolean
| argument | type | meaning |
|---|---|---|
v | number or nil | the hit chance to ask for. It is rounded to a whole number and kept between 1 and 100. nil gives the user's number back. |
Returns true when taken, false for a value that is not a number or not finite. The number applies while the hit chance is switched on in the menu.
events.on_paint(function()
local me = game.local_player()
if me and me.alive and math.abs(me.vz) > 10 then
rage.override_hitchance(40)
end
end)
rage.override_min_damage
rage.override_min_damage(v) -> boolean
| argument | type | meaning |
|---|---|---|
v | number or nil | the minimum damage, rounded and kept between 1 and 110. The values 101 to 110 mean the target's health plus 1 to 10. nil gives the user's number back. |
Returns true when taken, false for a value that is not a finite number.
events.on_paint(function()
rage.override_min_damage(90)
end)
rage.hold_fire
rage.hold_fire(b) -> boolean
| argument | type | meaning |
|---|---|---|
b | boolean | true holds the ragebot's shot back for as long as you keep calling. false releases the hold. |
The fire gate. While the hold is on, the ragebot does not take its shot. The player's own click is not touched, so a shot you fire by hand still goes out.
local gate = ui.keybind("hold fire", "hold")
events.on_paint(function()
if gate:get() then rage.hold_fire(true) end
end)
rage.exclude
rage.exclude(slot, b) -> boolean
| argument | type | meaning |
|---|---|---|
slot | integer | the enemy's slot, 1 to 64. It is the index of an entry of game.players(), and ent:index() gives the same number. |
b | boolean | true takes the enemy off the target list, false puts the enemy back. |
Returns true when taken. It returns false when the slot is not an enemy that is alive in this frame. The exclusion ends by itself when the enemy dies, leaves or changes sides.
events.on_paint(function()
local me = entity.local_player()
if not me then return end
local mx, my, mz = me:origin()
for _, ent in ipairs(entity.players(true)) do
local x, y, z = ent:origin()
if x and mx then
local far = math.sqrt((x - mx) ^ 2 + (y - my) ^ 2 + (z - mz) ^ 2) > 1500
rage.exclude(ent:index(), far)
end
end
end)
rage.override_double_precision
rage.override_double_precision(off [, chain_cap]) -> boolean
| argument | type | meaning |
|---|---|---|
off | boolean | true: no held commands this tick. false: no change from the script. |
chain_cap | integer 1 to 3 | at most this many commands are held in a row. Leave it out to give the cap back. |
One call sets both parts. The value only matters while the user has double precision switched on. A cap lowered in the middle of a chain simply ends the chain.
events.on_paint(function()
local me = game.local_player()
rage.override_double_precision(me ~= nil and me.alive and math.abs(me.vz) > 10)
end)
rage.override_auto_stop
rage.override_auto_stop(off [, mode [, in_air]]) -> boolean
| argument | type | meaning |
|---|---|---|
off | boolean | true: no auto stop this tick. |
mode | "full", "slide" or nil | the stop style. nil or a missing argument gives the part back. |
in_air | "on", "off" or nil | the auto stop's in-air condition. nil or a missing argument gives the part back. |
One call sets all three parts. A string that is not exactly one of the listed names is answered with false. A key the user holds on the stop style or the stop conditions wins for as long as it is held.
events.on_paint(function()
-- stop by sliding, and let the auto stop work in the air
rage.override_auto_stop(false, "slide", "on")
end)
rage.override_quick_stop
rage.override_quick_stop(off) -> boolean
off = true skips the quick stop for this tick. false and nil leave it to the user's setting. The quick stop runs only when the user has it enabled.
rage.override_air_stop
rage.override_air_stop(off) -> boolean
off = true skips the standalone air stop for this tick. false and nil leave it to the user's setting.
Example: air peek helper
Relax the hit chance in the air, stop by sliding, and drop the held commands of double precision while the player is airborne.
local relaxed = ui.slider("Hit chance in the air", 1, 100, 40)
events.on_paint(function()
local me = game.local_player()
if not me or not me.alive then return end
local airborne = math.abs(me.vz) > 10
rage.override_hitchance(airborne and relaxed:get() or nil)
rage.override_auto_stop(false, "slide", airborne and "on" or nil)
rage.override_double_precision(airborne)
end)
Example: fire gate on speed
Hold the ragebot's shot while the player is faster than a speed you choose. The player's own click is not held. The slider is in units per second.
local grp = ui.group("fire gate")
local on = grp:checkbox("hold fire while moving", true)
local limit = grp:slider("speed limit", 5, 250, 40)
events.on_paint(function()
if not on:get() then return end
local me = entity.local_player()
if not me or not me:is_alive() then return end
if (me:get("speed") or 0) > limit:get() then
rage.hold_fire(true)
end
end)