
rs2b0t
The 2004 bot — a scriptable, direct-input bot client for 2004scape

 |
 |
 |
 |

Run bots in your browser

rs2b0t is a 2004 bot: it renders the real 2004-era game client (2004scape / Lost City)
in the browser and drives it through a typed scripting API — bots see and act on exactly what a player would.
Log in with an rs2b2t account, pick a script, and run.

|
 |
 |
 |
 |

 |
 |
 |
 |

The client


The Woodcutter script 11 hours in — 3,108 maples chopped and banked: parameters and
live status on the right, an onPaint overlay in the client.

|
 |
 |
 |
 |

 |
 |
 |
 |

Highlights

Write bots in TypeScript against @rs2b0t/api — game state, entity queries, inventory, bank, dialogs, walking, events.
A simple LoopingBot, a priority TaskBot, or a TreeBot behaviour tree — pick the shape that fits.
A* pathfinding over a baked collision map plus a door and transport graph, with stuck-recovery.
| Real client, no forged packets |
Bots drive the real client's own action dispatch, so every interaction is byte-identical to a human click.
Script library, per-script parameters, live logs, and an overlay for onPaint HUDs.
Author bots in your own repo against the API and load them by URL — no fork required. |

|
 |
 |
 |
 |

 |
 |
 |
 |

What a bot looks like

import { defineBot, Execution, Inventory, LoopingBot } from '@rs2b0t/api';
class BoneBurier extends LoopingBot {
async loop(): Promise<void> {
const bones = Inventory.first('Bones');
if (bones) {
const before = Inventory.used();
await bones.interact('Bury');
await Execution.delayUntil(() => Inventory.used() < before, 3000);
return;
}
await Execution.delayTicks(2);
}
}
export default defineBot({
name: 'BoneBurier',
description: 'Buries bones from the inventory',
create: () => new BoneBurier()
});
|
A ready-to-copy starter lives in
templates/script-template.
See the API reference for the complete surface.

|
 |
 |
 |
 |

View our non-affiliation disclaimer here.
Built on the Lost City project
— the moderated original lives at 2004.lostcity.rs.

|