WELCOME TO INFOCHEATS.NET

INFOCHEATS is a community-driven platform focused on free game cheats, cheat development, and verified commercial software for a wide range of popular games. We provide a large collection of free cheats shared by the community. All public releases are checked for malicious code to reduce the risk of viruses, malware, or unwanted software before users interact with them.

Alongside free content, INFOCHEATS hosts an active marketplace with many independent sellers offering commercial cheats. Each product is discussed openly, with user feedback, reviews, and real usage experience available to help you make informed decisions before purchasing.

Whether you are looking for free cheats, exploring paid solutions, comparing sellers, or studying how cheats are developed and tested, INFOCHEATS brings everything together in one place — transparently and community-driven.

Undetected [AHK] RuneScape Nom Updated — Humanized Color Point Clicker

byte_corvus

Newbie
Newbie
Newbie
Newbie
Status
Offline
Joined
Mar 3, 2026
Messages
447
Reaction score
7
If you are still using static clickers in RuneScape, you are essentially begging for a manual review. I found this updated version of the classic NOM AHK base, and it is actually worth looking at for anyone doing repetitive skilling or task-based clicking.

This isn't just a simple pixel search paste. The author (PilgrimMites) has integrated a specific anchor logic to randomize mouse paths and return points. It supports marking 4 different color categories with 28 points each—plenty for complex bank-standing or interactive tasks.

Technical Highlights:
  1. Humanized MouseMove: Uses acceleration and error thresholds instead of instant teleportation.
  2. Randomized Return: The mouse returns to its original position with a randomized offset, mimicking natural hand movement.
  3. Multi-Point Arrays: 4 color groups, 28 coordinates per group.
  4. PilgrimMites Anchor: A custom weighted randomization function to keep movement within human-like standard deviations.

Keybinds & Controls:
  1. CTRL + Numpad 1-4: Mark coordinates for the respective color group.
  2. Numpad 1-4: Execute the click sequence for the marked points.
  3. Alt + Numpad 1-4: Wipe the stored points for that group.
  4. F5: Toggle the GUI overlay visibility (handy for staying low-key).
  5. F6: Instant Killswitch.

Code:
#NoEnv
SetWorkingDir %A_ScriptDir%
SendMode Input
#SingleInstance Force
#WinActivateForce
CoordMode, mouse, Screen
 
 
SetTimer, RemoveToolTip, -10000
ToolTip, Script Created by Nom`nUpdated By PilgrimMites`nCtrl+Numpad1-4 Add point`nAlt+Numpad1-4 Clear points`nNumpad1-4 Click points`nF6 to exit`nF5 toggle display,0,0
class JSON
{
class Load extends JSON.Functor
{
Call(self, ByRef text, reviver:="")
{
this.rev := IsObject(reviver) ? reviver : false
this.keys := this.rev ? {} : false
static quot := Chr(34), bashq := "\" . quot
, json_value := quot . "{[01234567890-tfn"
, json_value_or_array_closing := quot . "{[]01234567890-tfn"
, object_key_or_object_closing := quot . "}"
key := ""
is_key := false
root := {}
stack := [root]
next := json_value
pos := 0
while ((ch := SubStr(text, ++pos, 1)) != "") {
if InStr(" `t`r`n", ch)
continue
if !InStr(next, ch, 1)
this.ParseError(next, text, pos)
holder := stack[1]
is_array := holder.IsArray
if InStr(",:", ch) {
next := (is_key := !is_array && ch == ",") ? quot : json_value
} else if InStr("}]", ch) {
ObjRemoveAt(stack, 1)
next := stack[1]==root ? "" : stack[1].IsArray ? ",]" : ",}"
} else {
if InStr("{[", ch) {
static json_array := Func("Array").IsBuiltIn || ![].IsArray ? {IsArray: true} : 0
(ch == "{")
? ( is_key := true
, value := {}
, next := object_key_or_object_closing )
: ( value := json_array ? new json_array : []
, next := json_value_or_array_closing )
ObjInsertAt(stack, 1, value)
if (this.keys)
this.keys[value] := []
} else {
if (ch == quot) {
i := pos
while (i := InStr(text, quot,, i+1)) {
value := StrReplace(SubStr(text, pos+1, i-pos-1), "\\", "\u005c")
static tail := A_AhkVersion<"2" ? 0 : -1
if (SubStr(value, tail) != "\")
break
}
if (!i)
this.ParseError("'", text, pos)
value := StrReplace(value,  "\/",  "/")
, value := StrReplace(value, bashq, quot)
, value := StrReplace(value,  "\b", "`b")
, value := StrReplace(value,  "\f", "`f")
, value := StrReplace(value,  "\n", "`n")
, value := StrReplace(value,  "\r", "`r")
, value := StrReplace(value,  "\t", "`t")
pos := i
i := 0
while (i := InStr(value, "\",, i+1)) {
if !(SubStr(value, i+1, 1) == "u")
this.ParseError("\", text, pos - StrLen(SubStr(value, i+1)))
uffff := Abs("0x" . SubStr(value, i+2, 4))
if (A_IsUnicode || uffff < 0x100)
value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6)
}
if (is_key) {
key := value, next := ":"
continue
}
} else {
value := SubStr(text, pos, i := RegExMatch(text, "[\]\},\s]|$",, pos)-pos)
static number := "number", integer :="integer"
if value is %number%
{
if value is %integer%
value += 0
}
else if (value == "true" || value == "false")
value := %value% + 0
else if (value == "null")
value := ""
else
this.ParseError(next, text, pos, i)
pos += i-1
}
next := holder==root ? "" : is_array ? ",]" : ",}"
}
is_array? key := ObjPush(holder, value) : holder[key] := value
if (this.keys && this.keys.HasKey(holder))
this.keys[holder].Push(key)
}
}
return this.rev ? this.Walk(root, "") : root[""]
}
ParseError(expect, ByRef text, pos, len:=1)
{
static quot := Chr(34), qurly := quot . "}"
line := StrSplit(SubStr(text, 1, pos), "`n", "`r").Length()
col := pos - InStr(text, "`n",, -(StrLen(text)-pos+1))
msg := Format("{1}`n`nLine:`t{2}`nCol:`t{3}`nChar:`t{4}"
,     (expect == "")     ? "Extra data"
: (expect == "'")    ? "Unterminated string starting at"
: (expect == "\")    ? "Invalid \escape"
: (expect == ":")    ? "Expecting ':' delimiter"
: (expect == quot)   ? "Expecting object key enclosed in double quotes"
: (expect == qurly)  ? "Expecting object key enclosed in double quotes or object closing '}'"
: (expect == ",}")   ? "Expecting ',' delimiter or object closing '}'"
: (expect == ",]")   ? "Expecting ',' delimiter or array closing ']'"
: InStr(expect, "]") ? "Expecting JSON value or array closing ']'"
:                      "Expecting JSON value(string, number, true, false, null, object or array)"
, line, col, pos)
static offset := A_AhkVersion<"2" ? -3 : -4
throw Exception(msg, offset, SubStr(text, pos, len))
}
Walk(holder, key)
{
value := holder[key]
if IsObject(value) {
for i, k in this.keys[value] {
v := this.Walk(value, k)
if (v != JSON.Undefined)
value[k] := v
else
ObjDelete(value, k)
}
}
return this.rev.Call(holder, key, value)
}
}
class Dump extends JSON.Functor
{
Call(self, value, replacer:="", space:="")
{
this.rep := IsObject(replacer) ? replacer : ""
this.gap := ""
if (space) {
static integer := "integer"
if space is %integer%
Loop, % ((n := Abs(space))>10 ? 10 : n)
this.gap .= " "
else
this.gap := SubStr(space, 1, 10)
this.indent := "`n"
}
return this.Str({"": value}, "")
}
Str(holder, key)
{
value := holder[key]
if (this.rep)
value := this.rep.Call(holder, key, ObjHasKey(holder, key) ? value : JSON.Undefined)
if IsObject(value) {
static type := A_AhkVersion<"2" ? "" : Func("Type")
if (type ? type.Call(value) == "Object" : ObjGetCapacity(value) != "") {
if (this.gap) {
stepback := this.indent
this.indent .= this.gap
}
is_array := value.IsArray
if (!is_array) {
for i in value
is_array := i == A_Index
until !is_array
}
str := ""
if (is_array) {
Loop, % value.Length() {
if (this.gap)
str .= this.indent
v := this.Str(value, A_Index)
str .= (v != "") ? v . "," : "null,"
}
} else {
colon := this.gap ? ": " : ":"
for k in value {
v := this.Str(value, k)
if (v != "") {
if (this.gap)
str .= this.indent
str .= this.Quote(k) . colon . v . ","
}
}
}
if (str != "") {
str := RTrim(str, ",")
if (this.gap)
str .= stepback
}
if (this.gap)
this.indent := stepback
return is_array ? "[" . str . "]" : "{" . str . "}"
}
} else
return ObjGetCapacity([value], 1)=="" ? value : this.Quote(value)
}
Quote(string)
{
static quot := Chr(34), bashq := "\" . quot
if (string != "") {
string := StrReplace(string,  "\",  "\\")
, string := StrReplace(string, quot, bashq)
, string := StrReplace(string, "`b",  "\b")
, string := StrReplace(string, "`f",  "\f")
, string := StrReplace(string, "`n",  "\n")
, string := StrReplace(string, "`r",  "\r")
, string := StrReplace(string, "`t",  "\t")
static rx_escapable := A_AhkVersion<"2" ? "O)[^\x20-\x7e]" : "[^\x20-\x7e]"
while RegExMatch(string, rx_escapable, m)
string := StrReplace(string, m.Value, Format("\u{1:04x}", Ord(m.Value)))
}
return quot . string . quot
}
}
Undefined[]
{
get {
static empty := {}, vt_empty := ComObject(0, &empty, 1)
return vt_empty
}
}
class Functor
{
__Call(method, ByRef arg, args*)
{
if IsObject(method)
return (new this).Call(method, arg, args*)
else if (method == "")
return (new this).Call(arg, args*)
}
}
}
Class JSONFile {
static Instances := []
__New(File) {
FileExist := FileExist(File)
JSONFile.Instances[this] := {File: File, Object: {}}
ObjRelease(&this)
FileObj := FileOpen(File, "rw")
if !IsObject(FileObj)
throw Exception("Can't access file for JSONFile instance: " File, -1)
if FileExist {
try
JSONFile.Instances[this].Object := JSON.Load(FileObj.Read())
catch e {
this.__Delete()
throw e
} if (JSONFile.Instances[this].Object = "")
JSONFile.Instances[this].Object := {}
} else
JSONFile.Instances[this].IsNew := true
return this
}
 
__Delete() {
if JSONFile.Instances.HasKey(this) {
ObjAddRef(&this)
JSONFile.Instances.Delete(this)
}
}
 
__Call(Func, Param*) {
if JSONFile.Instances[this].HasKey(Func)
return JSONFile.Instances[this][Func]
if (Func = "JSON")
return StrReplace(JSON.Dump(this.Object(),, Param.1 ? A_Tab : ""), "`n", "`r`n")
if (Func = "Save") {
try
New := this.JSON(Param.1)
catch e
return false
FileObj := FileOpen(this.File(), "w")
FileObj.Length := 0
FileObj.Write(New)
FileObj.__Handle
return true
}
if (Func = "Fill") {
if !IsObject(Param.2)
Param.2 := []
for Key, Val in Param.1 {
if (A_Index > 1)
Param.2.Pop()
HasKey := Param.2.MaxIndex()
? this.Object()[Param.2*].HasKey(Key)
: this.Object().HasKey(Key)
Param.2.Push(Key)
if IsObject(Val) && HasKey
this.Fill(Val, Param.2), Param.2.Pop()
else if !HasKey
this.Object()[Param.2*] := Val
} return
}
return Obj%Func%(this.Object(), Param*)
}
 
 
__Set(Key, Val) {
return this.Object()[Key] := Val
}
__Get(Key) {
return this.Object()[Key]
}
}
guiCount:=1
width:=30
height:=30
display := True
hoverColor := "Red"
points1:= []
points2:= []
points3:= []
points4:= []
init_points(points1,"Red")
init_points(points2,"Blue")
init_points(points3,"Green")
init_points(points4,"Teal")
SetTimer, hover, 1
return
 
 
Numpad1::
click_points(points1)
return
Numpad2::
click_points(points2)
return
Numpad3::
click_points(points3)
return
Numpad4::
click_points(points4)
return
 
 
^Numpad1::
hoverColor := "Red"
add_point(points1, "Red")
return
^Numpad2::
hoverColor := "Blue"
add_point(points2, "Blue")
return
^Numpad3::
hoverColor := "Green"
add_point(points3, "Green")
return
^Numpad4::
hoverColor := "Teal"
add_point(points4, "Teal")
return
 
 
!Numpad1::
clear_points(points1)
return
!Numpad2::
clear_points(points2)
return
!Numpad3::
clear_points(points3)
return
!Numpad4::
clear_points(points4)
return
 
F5::
display := !display
if (!display) {
    hide_gui()
} else {
    display_gui()
}
return
 
hover:
if (display) {
MouseGetPos, currx, curry
overlay_rect(currx, curry, width, height, 3, hoverColor, False)
}
return
 
init_points(ByRef points,color) {
global width, height, guiCount, js
tempPoints := []
For index, p In points
{
num := overlay_rect(p.currx, p.curry, width, height, 3, color, True)
tempPoints.push({"currx":p.currx,"curry":p.curry,"x1":p.x1,"y1":p.y1,"x2":p.x2,"y2":p.y2,"gui":p.num})
}
points := tempPoints
}
 
clear_points(ByRef points) {
For index, p In points
{
num := p.gui
Gui %num%: Destroy
}
points := []
}
 
add_point(ByRef points, color) {
global width, height, guiCount, js
if (points.MaxIndex() > 28) {
return
}
 
MouseGetPos, currx, curry
num := overlay_rect(currx, curry, width, height, 3, color)
x1 := currx - width/2
x2 := currx + width/2
y1 := curry - height/2
y2 := curry + height/2
points.push({"currx":currx,"curry":curry,"x1":x1,"y1":y1,"x2":x2,"y2":y2,"gui":num})
js.save()
}
 
click_points(ByRef points) {
MouseGetPos, currx, curry
For index, p In points
{
click_box(p.x1, p.y1, p.x2, p.y2)
Sleep, RandomDelay(40,60)
}
X1 := currx + Rand(10), Y1 := curry + Rand(10)
MouseMove(X1, Y1)
}
 
overlay_rect(X:=0, Y:=0, W:=0, H:=0, T:=3, cc:="Red", incr:=True) {
global guiCount
X -= W/2
Y -= H/2
w2:=W-T
h2:=H-T
txt := abs(mod(guiCount,99)+1)
Gui %txt%: +LastFound +AlwaysOnTop -Caption +ToolWindow +E0x08000000 +E0x80020
Gui %txt%: Color, %cc%
Gui %txt%: Show, w%W% h%H% x%X% y%Y% NA
WinSet, Transparent, 150
WinSet, Region, 0-0 %W%-0 %W%-%H% 0-%H% 0-0 %T%-%T% %w2%-%T% %w2%-%h2% %T%-%h2% %T%-%T%
if (incr) {
    guiCount += 1
    }
return txt
}
 
hide_gui() {
loop, 99 {
    Gui %A_Index%: Hide
    }
}
 
display_gui() {
loop, 99 {
    Gui %A_Index%: +LastFound +AlwaysOnTop -Caption +ToolWindow +E0x08000000 +E0x80020
    Gui %A_Index%: Show
    }
}
 
click_box(x1, y1, x2, y2) {
ToolTip
x += PilgrimMites(x1,x2)
y += PilgrimMites(y1,y2)
MouseMove(x,y)
Click()
}
 
MouseMove(xTarget, yTarget, ErrorThreshold := 5, MinRandomDelay := 6, MaxRandomDelay := 8, PreMoveDelayMin := 20, PreMoveDelayMax := 30) {
    Speed := PilgrimMites(.80,2.35)
    MouseGetPos, xCurrent, yCurrent
    xOffset := xTarget - xCurrent, yOffset := yTarget - yCurrent
    distance := Sqrt(xOffset * xOffset + yOffset * yOffset) / Speed
    xStep := xOffset / distance, yStep := yOffset / distance
    Loop, % distance {
        MouseMove, xCurrent += xStep, yCurrent += yStep, % RandomDelay(MinRandomDelay, MaxRandomDelay)
        MouseGetPos, xNew, yNew
        xError := xTarget - xNew, yError := yTarget - yNew
        if (Sqrt(xError * xError + yError * yError) < ErrorThreshold) {
            Sleep, 1
        }
    }
    Sleep, PilgrimMites(PreMoveDelayMin, PreMoveDelayMax)
}
 
Rand(range=30) {
    Random, r, -%range%, +%range%
    Return R
}
 
RandRange(min, max) {
    if (min > max) {
        MsgBox, RandRange %ErrorLevel%
        return -1
    }
    Random, rand, %min%, %max%
    return rand
}
 
RandomDelay(min, max) {
    return RandRange(min, max)
}
 
 
Click(Delay_Min:=35.0, Delay_Max:=60.0,SpamPrevent_Min:=35.0,SpamPrevent_Max:=60.0) {
DllCall("user32.dll\mouse_event", uint, 0x0002, int, 0, int, 0, uint, 0, int, 0)
 
    Sleep, PilgrimMites(Delay_Min, Delay_Max)
 
DllCall("user32.dll\mouse_event", uint, 0x0004, int, 0, int, 0, uint, 0, int, 0)
 
    Sleep, PilgrimMites(SpamPrevent_Min, SpamPrevent_Max)
 
return
}
 
PilgrimMites(M, H) {
Middle := ( M + H ) / 2
    Random, r1, 0, Middle - M, %A_Now% . %A_IsCritical% . %A_TickCount%
    Random, r2, 0, H - Middle, %A_Now% . %A_IsCritical% . %A_TickCount%
    Anchor := M + r1 + r2
    if (Anchor < M || Anchor > H) {
        MsgBox, 49, Anchor Error, % "Invalid anchor: " . Anchor . "`nRestarting`nPlease contact PilgrimMites if this message appears."
        Reload
    } else {
        Return Anchor
    }
}
 
 
RemoveToolTip:
ToolTip
return
 
F6::ExitApp

Safety & Execution:
Even with the humanization layers, AHK is still an external script interacting with the OS mouse buffer. Jagex can flag high-frequency repetition if your delays are too tight. I recommend adjusting the MinRandomDelay and MaxRandomDelay in the script to match your actual clicking speed. Disable Secure Boot if you're running more aggressive overlays, though this script is purely user-mode.

anyone tweaked the randomization weights for higher intensity tasks?
 
Top