Skip to content

Available APIs

These APIs are available in every Epitaph JRuby script.

Every script is a Ruby hash assigned to script. Callbacks are lambdas inside the hash — top-level def methods do not work.

script = {
name: String, # display name
description: String, # tooltip text
category: String, # e.g. "RENDER", "COMBAT", "MISC"
on_load: lambda do ... end,
on_unload: lambda do ... end,
on_enable: lambda do ... end,
on_disable: lambda do ... end,
on_render_2d: lambda do |event| ... end,
on_render_3d: lambda do |event| ... end,
on_tick: lambda do |event| ... end,
on_key: lambda do |event| ... end,
}
  • client
  • player
  • world
  • modules
  • input
  • files
  • targeting
  • combat
  • rotation
  • friends
  • teams
  • antibot
  • inventory
  • interaction
  • render
  • mod / module_self
  • script_path

See the Client & Player guide for full documentation and examples.

Quick reference:

client.get_fps, client.get_ping, client.get_username
client.message(text), client.warn(text), client.error(text)
client.send_chat(text), client.copy_to_clipboard(text)
client.do_attack, client.do_item_use
client.random_int(min, max), client.random_float(min, max)
client.now # => Integer ms timestamp
player.is_present # guard before all player calls
player.get_id, player.get_name, player.get_display_name
player.get_health, player.get_max_health, player.get_absorption
player.get_hunger, player.get_fall_distance, player.get_hurt_time
player.get_x, player.get_y, player.get_z
player.get_yaw, player.get_pitch
player.get_velocity_x, player.get_velocity_y, player.get_velocity_z
player.is_on_ground, player.is_sprinting, player.is_sneaking
player.is_in_water, player.is_in_cobweb, player.is_holding_weapon
player.can_crit, player.is_using_item
player.get_attack_cooldown([base_time]) # base_time default 0.5
player.has_status_effect(name)
player.jump, player.swing
player.set_sprinting(bool), player.set_yaw(f), player.set_pitch(f)
player.set_rotation(yaw, pitch)
player.send_chat(text)

See the World & Entities guide for full documentation and examples.

Quick reference:

world.is_present # guard before all world calls
world.get_dimension, world.get_time, world.is_raining
world.get_player_count, world.get_entity_count
world.get_players # => Array of entity objects
world.get_entities # => Array of entity objects
world.get_entity(id) # => entity or nil

Entity object fields (direct access): id, name, display_name, type, x, y, z, eye_y, last_x, last_y, last_z, yaw, pitch, width, height, alive, removed, invisible, player

Entity object methods: get_id, get_uuid, get_name, get_display_name, get_type, get_x/y/z, get_eye_y, get_last_x/y/z, get_yaw, get_pitch, get_width, get_height, get_distance, get_health, get_max_health, get_hurt_time, is_player, is_living, is_hostile, is_passive, is_alive, is_removed, is_attackable, is_invisible, is_friend, is_teammate, is_bot

Use this to query and control Epitaph features from Ruby.

Methods:

  • modules.get(name) — returns a module object or nil
  • modules.toggle(name) — returns new enabled state
  • modules.set_enabled(name, bool) — returns new enabled state
  • modules.is_enabled(name) — Boolean
  • modules.list — Array of feature name strings

Module objects expose the same methods as mod (see below), plus get_name, get_info, get_description, get_category, get_key.

mod refers to the script’s own module. Use it to register settings in on_load and read them at runtime.

Registering settings (call inside on_load)

Section titled “Registering settings (call inside on_load)”
mod.register_boolean_setting(name, default)
mod.register_integer_setting(name, default, min, max, step)
mod.register_float_setting(name, default, min, max, step)
mod.register_double_setting(name, default, min, max, step)
mod.register_range_setting(name, default_min, default_max, min, max, step)
mod.register_mode_setting(name, default, option1, option2, ...) # options are variadic args
mod.register_string_setting(name, default)
mod.register_color_setting(name, r, g, b, a)
mod.register_keybind_setting(name, default_key)
mod.register_separator(name)

Setting visibility (call inside on_load, after registering)

Section titled “Setting visibility (call inside on_load, after registering)”
# Show child only when parent equals expected_value
mod.set_setting_parent_equals(child_name, parent_name, expected_value)
# Show child only when parent does NOT equal expected_value
mod.set_setting_parent_not_equals(child_name, parent_name, expected_value)
mod.get_setting_value(name) # => value or nil
mod.set_setting_value(name, value)
mod.is_enabled
mod.toggle
mod.set_enabled(bool)
mod.get_name, mod.get_info, mod.get_description, mod.get_category, mod.get_key
on_load: lambda do
mod.register_double_setting("Range", 5.0, 1.0, 20.0, 0.5)
mod.register_boolean_setting("Silent", false)
mod.register_mode_setting("Mode", "Normal", "Normal", "Strict", "Bypass")
mod.set_setting_parent_equals("Mode", "Silent", false)
end,
on_tick: lambda do |_event|
range = mod.get_setting_value("Range") || 5.0
silent = mod.get_setting_value("Silent") || false
mode = mod.get_setting_value("Mode") || "Normal"
end

mod.get_info returns the same suffix text Epitaph uses in its own arraylist HUD, so scripts can render labels like Aim Assist Legit or Velocity 0%.

feature = modules.get("Aim Assist")
if feature && feature.is_enabled
info = feature.get_info
label = info.nil? || info.empty? ? feature.get_name : "#{feature.get_name} #{info}"
render.text(label, 8, 8, render.color(255, 255, 255, 255), true)
end

Use this for keyboard and mouse state plus synthetic clicks.

Methods:

  • input.is_key_down(keycode) — Boolean (GLFW keycode)
  • input.is_mouse_down(button) — Boolean (GLFW mouse button)
  • input.is_attack_pressed, input.is_use_pressed, input.is_jump_pressed
  • input.is_forward_pressed, input.is_back_pressed, input.is_left_pressed, input.is_right_pressed, input.is_sneak_pressed
  • input.mouse_press(button), input.mouse_release(button)
  • input.mouse_click(button, [millis]) — millis defaults to 35
  • input.left_click([millis]), input.right_click([millis])

These methods check the crosshair target directly. None of them take arguments.

targeting.get # => hit result table or nil
targeting.get_type # => "entity", "block", or "miss"
targeting.is_entity # => Boolean
targeting.is_block # => Boolean
targeting.is_miss # => Boolean
targeting.get_entity # => entity object or nil
targeting.get_block # => block hit object or nil

Hit result table (from targeting.get): type, is_entity, is_block, is_miss, x, y, z, entity (when entity), entity_id (when entity), block (when block)

Block hit object: x, y, z (Integer block pos), side (String face), hit_x, hit_y, hit_z (Float exact position)

Raycasts (yaw and pitch are optional, default to player rotation):

targeting.raycast(reach)
targeting.raycast(reach, yaw, pitch)
targeting.raycast_through_walls(reach)
targeting.raycast_through_walls(reach, yaw, pitch)

Lightweight combat helpers:

  • combat.get_attack_cooldown([base_time]) — Float 0.0–1.0
  • combat.can_crit — Boolean
  • combat.is_in_water, combat.is_in_cobweb — Boolean
  • combat.is_holding_weapon — Boolean
  • combat.can_swing — Boolean

Aim assistance helpers for calculating rotations to entities and positions.

rotation.get_rotation_to(entity) # => {yaw, pitch, x, y, z}
rotation.get_rotation_to(block) # block hit / block-pos table with x,y,z
rotation.get_rotation_to(x, y, z) # exact world position
rotation.get_rotation_to_entity(entity) # alias with explicit naming
rotation.get_rotation_to_entity(entity, "Head")
rotation.get_rotation_to_entity(entity, "Body", 50.0) # multipoint accuracy 0-100
rotation.get_rotation_to_block(block)
rotation.get_rotation_to_block(x, y, z)
rotation.get_to_entity(entity) # legacy alias
rotation.get_to_entity(entity, "Head")
rotation.get_to_entity(entity, "Body", 50.0)
rotation.get_to_position(x, y, z)
rotation.get_to_block(block)
rotation.get_to_block(x, y, z)

Rotation result tables include yaw, pitch, x, y, and z.

rotation.get_angle_diff(entity) # => {yaw, pitch, total} degrees
rotation.get_yaw_diff(entity) # => Float yaw diff (-180 to 180)
rotation.get_pitch_diff(entity) # => Float pitch diff in degrees
rotation.get_abs_angle_diff(entity) # => Float combined Euclidean diff
rotation.apply_gcd(current, target) # => Float target snapped to Minecraft mouse GCD
rotation.get_distance_to(entity) # => Float distance in blocks

Use rotation.apply_gcd(current, target) when you want script-driven yaw or pitch changes to respect the same mouse-step snapping used by the client’s rotation features.

friends.is_friend(name_or_entity) # => Boolean
friends.list # => Array of String names
teams.is_enabled # => Boolean
teams.is_teammate(entity) # => Boolean
antibot.is_enabled # => Boolean
antibot.is_bot(entity) # => Boolean
inventory.get_selected_slot # => Integer 0–8
inventory.can_change_held_slot # => Boolean
inventory.set_selected_slot(slot, [silent])
inventory.try_set_selected_slot(slot, [silent]) # => Boolean success
inventory.get_slot(index) # => slot object or nil
inventory.get_hotbar # => Array of slot objects (0–8)
inventory.find_hotbar_slot(query) # => Integer or -1 (matches item_name or display_name)
inventory.click_slot(slot, [button], [action_type])

Slot object fields: slot, container_slot, empty, count, item_name, display_name, is_hotbar

action_type string values: "pickup" (default), "quick_move", "swap", "clone", "throw", "quick_craft", "pickup_all"

interaction.attack_entity(entity_or_id)
interaction.interact_entity(entity_or_id, [hand]) # hand: "main" or "off", default "main"
interaction.interact_item([hand])
interaction.stop_using_item
interaction.attack_block(x, y, z, [face]) # face: "up","down","north","south","east","west"
interaction.interact_block(x, y, z, [face], [hand])

See the Rendering guide for full documentation and examples.

Key signatures:

render.color(r, g, b, a) # all four 0–255 required
render.fill(x1, y1, x2, y2, color) # absolute max coords
render.border(x, y, width, height, color) # origin + dimensions
render.text(text, x, y, color, [shadow]) # x,y are Integer; shadow default false
render.measure_text(text) # => Integer width
render.font_text(font, text, x, y, size, color, [shadow])
render.measure_font_text(font, text, size) # => Float
render.font_height(font, size) # => Float
render.list_fonts # => Array of String
render.entity_screen_box(entity_or_id, [padding]) # => box or nil
render.world_to_screen(x, y, z) # => {x, y, depth, on_screen} or nil
render.is_2d_context, render.is_3d_context
render.line_3d(x1,y1,z1, x2,y2,z2, color, [through_blocks], [line_width])
render.box_3d(x1,y1,z1, x2,y2,z2, color, [through_blocks], [line_width])
render.filled_box_3d(x1,y1,z1, x2,y2,z2, color, [through_blocks])
render.circle_3d(x,y,z, radius, color, [through_blocks], [line_width])

Scoped to the Epitaph scripts directory. Paths outside it are rejected.

files.root # => String absolute path to scripts dir
files.exists(path) # => Boolean
files.read(path) # => String or nil
files.write(path, content)
files.append(path, content)
files.mkdirs(path)
files.list([path]) # => Array of relative path strings; defaults to root