Wsamiaw · Scripting
Scripting
Wsamiaw embeds a JavaScript engine (Rhino). Each *.js file under
config/Wsa/scripts/ runs at boot, listens to engine events, and can register its own
ClickGUI modules with settings, keybinds, Cloud/Local sync, render drawing and packets.
Trust boundary. Scripts are not fully sandboxed — they can send packets and toggle modules. Only run code you wrote or fully trust.
Folder & Cloud / Local
config/Wsa/scripts/YourScript.js
In-game: Cloud tab → Scripts → Cloud / Local toggle, or chat with .script.
| Tab | What it does |
|---|---|
| Cloud | Browse community scripts. Apply runs + saves locally. Del removes your uploads. Download counts on cards. |
| Local | Files on disk. Apply loads and runs. Del removes the file. |
Quick start
- Create
config/Wsa/scripts/hello.js(see below) - In-game:
.script reload— loads all scripts - ClickGUI → your module appears under its category → enable
hello
var m = modules.register({
name: "HelloMod",
category: "Misc",
description: "Says hi",
settings: [
{name: "Range", type: "number", value: 3.0, min: 1.0, max: 6.0}
],
onEnable: function() { chat("HelloMod on"); },
onDisable: function() { chat("HelloMod off"); },
onTick: function(e) {
var aura = client.mod("KillAura");
if (aura !== null && aura.isEnabled()) {
chat("aura is on, range " + m.settingNum("Range"));
}
}
});
Script modules
modules.register(desc) creates a real cheat module: it shows in ClickGUI, HUD/ArrayList, keybinds and configs. Returns the module object.
| Field | Type | Notes |
|---|---|---|
name | string, required | Shown in ClickGUI/HUD |
category | string | Combat / Movement / Render / Player / Misc / Settings (default Misc) |
description | string | Tooltip text |
bind | int | Keycode, 0 = none |
settings | array | See setting types below |
onEnable / onDisable | function | Toggle callbacks |
onTick / onUpdate / onPacket / onRender2D / onRender3D | function(e) | Only while the module is enabled |
Runtime: m.settingNum(name), m.settingBool(name), m.settingStr(name),
m.setSetting(name, value), m.isEnabled(), m.setEnabled(b).
modules.list() returns names, modules.get(name) returns the module.
Note: always use the typed getters (settingNum etc.) — plain setting() returns a Java wrapper. Same rule everywhere: compare Java values with == / != (or String(x)), never === / !== — plain setting() returns a Java wrapper.
Setting types
| type | Fields | Example |
|---|---|---|
bool | value | {name:"Fast", type:"bool", value:true} |
number | value, min, max | {name:"Range", type:"number", value:3.0, min:1.0, max:6.0} |
int | value, min, max | {name:"Count", type:"int", value:2, min:0, max:10} |
mode | value, options[] | {name:"Mode", type:"mode", value:0, options:["A","B"]} |
color | value (ARGB int) | {name:"Tint", type:"color", value:0xFF7C5CFF} |
text | value | {name:"Label", type:"text", value:"hi"} |
Event hooks
Global listeners (run regardless of modules): events.on(name, fn) with
update, tick, packet, render2d, render3d.
| Event | e.getType() | Useful members |
|---|---|---|
update | PRE / POST | getYaw/getPitch/getNewYaw/getNewPitch, setRotation(yaw,pitch,prio) |
tick | PRE / POST | Per-tick logic, timers |
packet | SEND / RECEIVE | getPacket(), setCancelled(true) |
render2d | — | HUD drawing via render.* |
render3d | — | World-space drawing, getPartialTicks() |
events.on("packet", function(e) {
if (e.getType().toString() === "RECEIVE") {
var p = e.getPacket();
if (p instanceof Packages.net.minecraft.network.play.server.S02PacketChat) {
chat("chat packet seen");
}
}
});
Globals
| Name | What it is |
|---|---|
mc | Minecraft instance — mc.thePlayer, mc.theWorld, mc.gameSettings, … |
chat(msg) | Send a chat message |
client.print(msg) | Print to chat (local only) |
client.mod(name) | Built-in module (isEnabled(), setEnabled(b)) or null |
client.getScriptName() | This script's file name |
modules.register(desc) / modules.get(name) / modules.list() | Script modules (see above) |
events.on(name, fn) | Global hooks: update, tick, packet, render2d, render3d |
Packages.* | Full Java access, e.g. new Packages.net.minecraft.network.play.client.C01PacketChatMessage("hi") |
render API
Call only during render2d / render3d. Colors are ARGB integers.
| Method | Notes |
|---|---|
render.rect(x1,y1,x2,y2,color) | Filled rectangle |
render.rounded(x,y,w,h,radius,color) | Rounded rectangle |
render.text(s,x,y,color) | Vanilla font with shadow |
render.textNoShadow(s,x,y,color) | Vanilla font, no shadow |
render.centerText(s,cx,y,color) | Horizontally centered text |
render.textWidth(s) | Pixel width for layout |
render.pill(x,y,w,h,bg,accent,text,textColor) | ArrayList-style pill row with accent bar |
render.image(path,x,y,w,h) | Draw classpath/resource image, e.g. assets/wsamiaw/logo.png |
render.push(x,y,scale,rotationDeg) / render.pop() | Transform stack for custom animations (scale + rotate around point) |
render.screenWidth() / render.screenHeight() | Scaled screen size for HUD layout |
render.time(), render.sin(v), render.cos(v) | Animation helpers (seconds, trig) |
Custom HUD element
var hud = modules.register({
name: "MyHud", category: "Render",
settings: [
{name: "Scale", type: "number", value: 1.0, min: 0.5, max: 2.0}
],
onRender2D: function(e) {
var s = hud.settingNum("Scale");
var w = 120 * s, h = 18 * s;
var x = render.screenWidth() - w - 6, y = 40;
var a = 0.5 + 0.5 * render.sin(render.time() * 2.0);
var bg = 0xB0101014, accent = 0xFF7C5CFF;
render.pill(x, y, w, h, bg, accent, "MyHud " + Math.round(a * 100), 0xFFFFFFFF);
}
});
Packets
Inspect/cancel via the packet event; send via mc + Packages:
events.on("packet", function(e) {
var p = e.getPacket();
if (p instanceof Packages.net.minecraft.network.play.server.S02PacketChat) {
var text = p.getChatComponent().getUnformattedText();
if (text.indexOf("Victory") !== -1) chat("gg");
}
});
var C01 = Packages.net.minecraft.network.play.client.C01PacketChatMessage;
mc.getNetHandler().addToSendQueue(new C01("hello"));
mc.getNetHandler().addToSendQueue(
new Packages.net.minecraft.network.play.client.C03PacketPlayer(true));
Serverbound: C01 chat, C02 use entity, C03 player, C07 dig, C08 place, C09 held item, C0A swing, C0B action, C0D close, C0E click, C0F transaction, C10 creative, C13 abilities, C16 status. Clientbound: S02 chat, S04 equipment, S06 health, S08 pos look, S12 velocity, S13 destroy, S14 rel move, S18 teleport, S23 block change, S27 explosion, S29 sound, S2A particles, S45 title, S48 resource pack, …
Commands
| Command | Action |
|---|---|
.script list | Loaded scripts + ON/OFF |
.script reload | Reload all scripts |
.script load <name> | Load one file |
.script unload <name> | Unload (removes its modules) |
.script eval <js...> | Run a snippet immediately |
Aliases: .scripts, .js
Security
Trust boundary. Scripts are not sandboxed — through Packages they can touch any Java/Minecraft API, send packets and toggle modules. Only run code you wrote or fully trust. A throwing script reports to chat and keeps running; unload it with .script unload.
Examples
AutoGG
events.on("packet", function(e) {
if (e.getType().toString() !== "RECEIVE") return;
var p = e.getPacket();
var S02 = Packages.net.minecraft.network.play.server.S02PacketChat;
if (p instanceof S02) {
if (p.getChatComponent().getUnformattedText().indexOf("Victory") !== -1) chat("gg");
}
});
Toggle HUD
var m = modules.register({
name: "HudToggle", category: "Render",
onEnable: function() { client.mod("HUD").setEnabled(true); },
onDisable: function() { client.mod("HUD").setEnabled(false); }
});
Aim readout
events.on("render2d", function(e) {
var p = mc.thePlayer;
if (p !== null) render.text("yaw " + p.rotationYaw.toFixed(1), 4, 4, 0xFFFFFFFF);
});
Download full reference: scripting-reference.html (markdown, copy/download)