Skip to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

AI generated Native documentation

Featured Replies

I definitely wrote this all myself and didnt use AI

OSBOT API - Complete Function Reference & Use Cases

Table of Contents

  1. Players API

  2. NPCs API

  3. Objects API

  4. World & Map API

  5. Interactions API

  6. Ground Items API

  7. Walking & Movement

  8. Utilities & Helpers

  9. Display & Viewport Management

  10. Coordinate Projection System

  11. Camera System

  12. Rendering & Screen Coordinates

  13. Minimap Rendering

  14. Geometric Utilities

  15. Painting & Overlay Examples


Players API

Location: src/api/scene/players.rs

Functions for accessing and managing player entities in the game world.

Core Functions

players_get_local_player() -> Option<RSPlayer>

Returns your own player character.

Returns: Option<RSPlayer> - Your player if logged in, None otherwise

Use Cases:

  • Getting your current position to calculate distances

  • Checking your current status (health, animation, etc.)

  • Verifying game state before performing actions

  • Setting up path-finding from your location

Example:

if let Some(local_player) = players_get_local_player() {
    let my_x = local_player.get_x();
    let my_y = local_player.get_y();
    println!("I am at ({}, {})", my_x, my_y);
}

players_get_local_player_index() -> i32

Returns the index of your player in the players array.

Returns: i32 - Array index of local player

Use Cases:

  • Iterating through all players efficiently

  • Filtering your player from a list of all players

  • Internal API operations

players_get_at_index(index: i32) -> Option<RSPlayer>

Retrieves a player at a specific array index.

Returns: Option<RSPlayer> - Player at index if valid, None otherwise

Use Cases:

  • Iterating through all players in the world

  • Following up on index-based queries

players_get_all() -> impl Iterator<Item = RSPlayer>

Returns an iterator over all players currently visible.

Returns: Iterator yielding all RSPlayer instances

Use Cases:

  • Finding all players in a specific area

  • Counting players near a location

  • Checking for friends or clan members

  • Detecting multi-logging

Example:

let player_count = players_get_all().count();
println!("There are {} players visible", player_count);

// Find players near a specific position
if let Some(local_player) = players_get_local_player() {
    let nearby = players_get_all()
        .filter(|p| {
            let distance = ((p.get_x() - local_player.get_x()).pow(2) 
                          + (p.get_y() - local_player.get_y()).pow(2))
                .sqrt() as i32;
            distance < 50
        })
        .count();
}

players_get_all_in_worldview(world_view: RSWorldView) -> impl Iterator<Item = RSPlayer>

Returns players in a specific world view (instance/world).

Parameters:

  • world_view - The world view to query

Returns: Iterator yielding RSPlayer instances in that world view

Use Cases:

  • Working with instanced content (dungeons, raids)

  • Multi-world scenarios

  • Filtering players by location group


NPCs API

Location: src/api/scene/npcs.rs

Comprehensive functions for finding, filtering, and interacting with NPCs.

Finding Functions

npcs_find_closest_by_id<T: Into<IdArgs>>(args) -> Option<RSNpc>

Finds the nearest NPC matching a specific ID.

Parameters:

  • args - NPC ID(s) to search for

Returns: Option<RSNpc> - Closest matching NPC or None

Use Cases:

  • Locating a specific NPC banker or shop keeper

  • Finding the nearest vendor

  • Pathfinding to quest NPCs

Example:

// Using single ID
if let Some(banker) = npcs_find_closest_by_id(1634) {
    println!("Banker at ({}, {})", banker.get_x(), banker.get_y());
}

// Using multiple IDs (any match)
if let Some(npc) = npcs_find_closest_by_id(vec![1, 2, 3]) {
    println!("Found NPC near me");
}

npcs_find_closest_by_name<T: Into<NameArgs>>(args) -> Option<RSNpc>

Finds the nearest NPC by name.

Parameters:

  • args - NPC name(s) to search for

Returns: Option<RSNpc> - Closest matching NPC or None

Use Cases:

  • Finding specific NPCs by their display name

  • Quest NPCs by name

  • Named vendors or quest givers

Example:

if let Some(guard) = npcs_find_closest_by_name("Guard") {
    // Interact with guard
}

npcs_find_closest_conditional(predicate) -> Option<RSNpc>

Finds the nearest NPC matching a custom predicate.

Parameters:

  • predicate - Function returning true for desired NPCs

Returns: Option<RSNpc> - Closest matching NPC or None

Use Cases:

  • Complex filtering logic (level, stats, actions available)

  • Finding NPCs with specific properties

  • Advanced queries

Example:

let mage = npcs_find_closest_conditional(|npc| {
    npc.get_name().contains("Mage") 
        && npc.has_action("Talk-to")
});

npcs_find_closest_to_by_id(to: Position, args) -> Option<RSNpc>

Finds an NPC by ID closest to a specific position.

Parameters:

  • to - Target position

  • args - NPC ID(s)

Returns: Option<RSNpc> - Closest NPC to position

Use Cases:

  • Finding NPCs near specific landmarks

  • Multi-step navigation

  • Location-based logic

npcs_find_all_by_id<T: Into<IdArgs>>(args) -> impl Iterator<Item = RSNpc>

Returns all NPCs matching given ID(s).

Returns: Iterator yielding all matching RSNpc instances

Use Cases:

  • Counting NPC spawns

  • Area analysis

  • Monitoring NPC locations

npcs_get_at_index(index: i32) -> Option<RSNpc>

Gets NPC at specific array index.

Use Cases:

  • Iterator-based access

  • Indexed lookups

npcs_get_all() -> impl Iterator<Item = RSNpc>

Returns all NPCs currently visible.

Use Cases:

  • Scanning entire world for NPCs

  • Statistical analysis

  • Debug/monitoring

npcs_get_all_in_worldview(world_view: RSWorldView) -> impl Iterator<Item = RSNpc>

Returns NPCs in a specific world view/instance.

Use Cases:

  • Instance-specific logic

  • Multi-world support


Objects API

Location: src/api/scene/objects.rs

Comprehensive interface for locating and interacting with game objects.

Object Type Flags

const OBJECTS_GROUND_DECORATION_FLAG: i32 = 1 << 0;      // Ground items
const OBJECTS_WALL_DECORATION_FLAG: i32 = 1 << 1;        // Wall decorations
const OBJECTS_WALL_OBJECT_FLAG: i32 = 1 << 2;            // Doors, walls
const OBJECTS_INTERACTABLE_OBJECT_FLAG: i32 = 1 << 3;    // Climbable, usable
const OBJECTS_ALL_OBJECTS_FLAG: i32 = 0xF;               // All types

Finding Functions

objects_find_closest_by_id(flags, args) -> Option<Box<dyn Object>>

Finds nearest object by ID with type filtering.

Parameters:

  • flags - Object type filter (use macros for convenience)

  • args - Object ID(s)

Returns: Option<Box<dyn Object>> - Closest matching object

Use Cases:

  • Finding doors, ladders, or staircases

  • Locating interactive furniture

  • Navigation obstacles

Example:

// Find nearest door
if let Some(door) = objects_find_closest_by_id(
    OBJECTS_WALL_OBJECT_FLAG, 
    1234
) {
    // Interact with door
    if let Some(action_pos) = door.get_interaction_point() {
        // Navigate to and use door
    }
}

// Macro shorthand - searches all object types
if let Some(obj) = objects_find_closest_by_id!(5678) {
    println!("Found object");
}

objects_find_closest_by_name(flags, args) -> Option<Box<dyn Object>>

Finds nearest object by name.

Example:

if let Some(ladder) = objects_find_closest_by_name(
    OBJECTS_INTERACTABLE_OBJECT_FLAG,
    "Ladder"
) {
    println!("Found ladder at ({}, {})", ladder.get_x(), ladder.get_y());
}

objects_find_closest_conditional(flags, predicate) -> Option<Box<dyn Object>>

Finds object matching custom logic.

Use Cases:

  • Complex object filtering

  • Specific object states

  • Multiple criteria

Example:

let obj = objects_find_closest_conditional(
    OBJECTS_ALL_OBJECTS_FLAG,
    |obj| {
        obj.get_name().contains("Gate") 
            && obj.has_action("Open")
    }
);

objects_find_by_id(plane, flags, args) -> Option<Box<dyn Object>>

Finds first object matching criteria on specific plane.

Parameters:

  • plane - Floor level (0-3)

  • flags - Object type filter

  • args - Object ID(s)

Returns: Option<Box<dyn Object>>

Use Cases:

  • Specific floor navigation

  • Multi-level dungeon exploration

objects_find_all_by_id(plane, flags, args) -> Vec<Box<dyn Object>>

Finds all objects matching ID on specific plane.

Use Cases:

  • Finding all doors/gates

  • Counting object instances

  • Mapping obstacle locations

objects_find_at_position_conditional(position, flags, predicate) -> Option<Box<dyn Object>>

Finds object at exact tile position.

Parameters:

  • position - Target tile coordinate

  • flags - Object type filter

  • predicate - Custom filter function

Returns: Option<Box<dyn Object>>

Use Cases:

  • Checking what's at a specific tile

  • Validation before movement

  • Pre-interaction checks

objects_get_at(x, y, plane, flags) -> TileObjects

Gets all objects at a tile (returns grouped by type).

Returns: TileObjects struct containing:

  • ground_decoration: Option<RSGroundDecoration>

  • wall_decoration: Option<RSWallDecoration>

  • wall_object: Option<RSWallObject>

  • interactable_objects: Vec<RSInteractableObject>

Example:

let tile_objects = objects_get_at!(10, 20, 0);  // All object types
if let Some(wall) = tile_objects.get_wall_object() {
    println!("There's a wall here");
}

objects_get_all(plane, flags) -> impl Iterator<Item = TileObjects>

Returns all tiles with objects on specified plane.

Use Cases:

  • Mapping entire region

  • Obstacle analysis

  • Path validation


World & Map API

Location: src/api/scene/world_view.rs, src/api/scene/map.rs

World View Functions

world_view_get_world_view() -> RSWorldView

Gets the current active world view (viewport).

Returns: RSWorldView - Current visible world state

Use Cases:

  • Getting base coordinates

  • Querying visible region

  • World state verification

Example:

let world = world_view_get_world_view();
let base_x = world.get_base_x();
let base_y = world.get_base_y();
let plane = world.get_plane();
println!("Currently viewing region at ({}, {}), plane {}", base_x, base_y, plane);

world_view_get_base_x() -> i32

Gets base X coordinate of current world view.

world_view_get_base_y() -> i32

Gets base Y coordinate of current world view.

world_view_get_plane() -> i32

Gets current floor/plane (0-3).

Use Cases:

  • Floor-specific logic

  • Multi-level navigation

  • Height-based decisions

world_view_get_global_world_view() -> RSWorldView

Gets the global/main world view.

world_view_get_local_world_view() -> Option<RSWorldView>

Gets local/instanced world view if in instance.


Map Functions

map_get_hint_arrow() -> RSHintArrow

Gets the hint arrow data (if active).

Use Cases:

  • Quest tracking

  • Following game-provided guidance

  • Navigation assistance

map_get_destination() -> Option<Position>

Gets player's current walking destination (if any).

Returns: Option<Position> - Target position if walking

Example:

if let Some(dest) = map_get_destination() {
    println!("Walking to ({}, {})", dest.x, dest.y);
} else {
    println!("Not walking");
}

Reachability Functions

map_can_reach_local_position(position) -> bool

Checks if a local position is reachable.

Parameters:

  • position - Position to check

Returns: bool - True if reachable without obstacles

Use Cases:

  • Path validation before walking

  • Obstacle detection

  • Navigation planning

map_can_reach_object(object) -> bool

Checks if an object is reachable.

Use Cases:

  • Pre-interaction checks

  • Navigation validation

  • Obstacle avoidance

map_can_reach_npc(npc) -> bool

Checks if an NPC is reachable.

map_can_reach_player(player) -> bool

Checks if another player is reachable.

map_can_reach_ground_item(item) -> bool

Checks if a ground item is reachable.

Distance Functions

map_find_local_distance_to_position(position) -> i32

Calculates distance to a position.

Returns: i32 - Distance in tiles (or -1 if unreachable)

Example:

if let Some(target) = objects_find_closest_by_id!(1234) {
    let dist = map_find_local_distance_to_object(&target);
    if dist > 0 && dist < 20 {
        // Object is close and reachable
    }
}

map_find_distance_to_object(object) -> i32

Gets distance to an object.

map_find_distance_to_position(position) -> i32

Gets distance to a position.

Pathfinding Functions

map_find_local_path_to_position(position) -> Option<Vec<Position>>

Calculates a walkable path to position.

Returns: Option<Vec<Position>> - Path if found, None if blocked

Use Cases:

  • Advanced navigation

  • Multi-step movement planning

  • Obstacle navigation

map_find_path_to_object(object) -> Option<Vec<Position>>

Calculates path to an object.

map_find_local_path_position_to_position(from, to) -> Option<Vec<Position>>

Finds path between two positions.

Example:

if let Some(path) = map_find_local_path_to_position(&target_pos) {
    println!("Found path with {} steps", path.len());
}

map_get_wilderness_level() -> i32

Gets current wilderness level (0 if not in wilderness).

Use Cases:

  • PvP content detection

  • Risk assessment

  • Wilderness-specific logic


Interactions API

Location: src/api/scene/interactable.rs

Interactable Trait

Objects implementing the Interactable trait provide methods for interaction:

pub trait Interactable {
    fn contains(&self, point: (i32, i32)) -> bool;           // Point in bounds?
    fn get_central_point(&self) -> (i32, i32);              // Center position
    fn get_interaction_point(&self) -> (i32, i32);          // Click position
    fn is_visible(&self) -> bool;                            // Currently visible
}

InteractArgs Configuration

pub struct InteractArgs {
    min_camera_distance: i32,    // Minimum distance from camera
    walk_to: bool,               // Whether to walk to object
    move_camera: bool,           // Whether to adjust camera
}

Use Cases:

  • Controlling interaction behavior

  • Camera management during interactions

  • Movement prerequisites

Example:

let mut args = InteractArgs::default();
args.set_min_camera_distance(5)
    .set_walk_to(true)
    .set_move_camera(true);

Ground Items API

Location: src/api/scene/ground_items.rs

Functions for finding and managing items on the ground.

Finding Functions

ground_items_find_closest_by_id<T: Into<IdArgs>>(args) -> Option<RSGroundItem>

Finds the nearest ground item by ID.

Returns: Option<RSGroundItem> - Closest matching item

Use Cases:

  • Finding dropped valuable items

  • Looting specific items

  • Resource gathering

Example:

if let Some(item) = ground_items_find_closest_by_id(1234) {
    println!("Found item at ({}, {})", item.get_x(), item.get_y());
}

ground_items_find_closest_by_name(args) -> Option<RSGroundItem>

Finds nearest ground item by name.

ground_items_find_closest_conditional(predicate) -> Option<RSGroundItem>

Finds nearest item matching predicate.

Example:

let valuable = ground_items_find_closest_conditional(|item| {
    item.get_quantity() > 1000 && item.get_name().contains("Ore")
});

ground_items_find_closest_to_by_id(to, args) -> Option<RSGroundItem>

Finds item by ID closest to position.

ground_items_find_by_id(args) -> Option<RSGroundItem>

Finds any item matching ID (not necessarily closest).

ground_items_find_all_by_id(args) -> impl Iterator<Item = RSGroundItem>

Returns all items matching ID.

Use Cases:

  • Counting dropped items

  • Tracking item distribution

  • Mass looting operations

ground_items_get_all(plane) -> impl Iterator<Item = RSGroundItem>

Gets all ground items on a plane.

Example:

let item_count = ground_items_get_all(plane).count();
println!("There are {} items on this floor", item_count);

ground_items_get_all_at_local(local_x, local_y, plane) -> impl Iterator<Item = RSGroundItem>

Gets all items at a specific tile.

Use Cases:

  • Pile checking

  • Loot verification

  • Tile analysis


Walking & Movement

Location: src/api/walking.rs

Core Walking Functions

walking_get_run_energy() -> i32

Gets current run energy percentage.

Returns: i32 - 0-100 percentage

Use Cases:

  • Energy-aware movement decisions

  • Stamina potions usage

  • Performance optimization

walking_is_run_enabled() -> bool

Checks if running is currently enabled.

Returns: bool - True if running

walking_set_run(enabled: bool) -> bool

Toggles run mode on/off.

Parameters:

  • enabled - True to enable run, false to disable

Returns: bool - Success

Example:

if walking_get_run_energy() > 50 {
    walking_set_run(true);
} else {
    walking_set_run(false);
}

walking_walk_path(path: &Vec<Position>) -> bool

Walks along a predetermined path.

Parameters:

  • path - Vector of positions to walk

Returns: bool - Success

Use Cases:

  • Following calculated paths

  • Multi-step navigation

  • Safe route following

walking_traverse(args: &mut WalkingArgs) -> bool

Advanced walking with configuration options.

Parameters:

  • args - Configuration struct (see below)

Returns: bool - Success

WalkingArgs Configuration

pub struct WalkingArgs {
    path: Vec<Position>,
    area: Option<Area>,
    destination: Option<Position>,
    break_condition: Option<Box<dyn Fn() -> bool>>,
    min_destination_threshold: i32,
    min_minimap_threshold: i32,
    min_run_energy: i32,
    use_minimap: bool,
}

Methods:

  • new_with_path(path) - Initialize with explicit path

  • new_with_area(area) - Initialize with area to reach

  • new_with_destination(pos) - Initialize with target position

  • set_break_condition(fn) - Stop if condition becomes true

  • set_min_destination_threshold(i32) - Distance to destination

  • set_min_minimap_threshold(i32) - Minimap range threshold

  • set_min_run_energy(i32) - Minimum energy before running

  • set_use_minimap(bool) - Use minimap for movement

Example:

let mut args = WalkingArgs::new_with_destination(&target);
args.set_use_minimap(true)
    .set_min_destination_threshold(5)
    .set_min_run_energy(30)
    .set_break_condition(|| {
        // Stop walking if we're under attack
        if let Some(player) = players_get_local_player() {
            player.get_interacting_entity().is_some()
        } else {
            false
        }
    });

walking_traverse(&mut args);

Utilities & Helpers

Menu & Interaction

The API provides comprehensive menu interaction for selecting game options.

Common Functions:

  • menu_is_open() - Check if menu is visible

  • menu_get_count() - Get number of menu options

  • menu_get_items() - Get all menu items

  • menu_interact(vars, option, actions) - Click menu option

Use Cases:

  • Handling context menus

  • Selecting dialogue options

  • Confirming actions

Banking

Location: src/api/ui/bank.rs

Common Functions:

  • bank_is_open() - Check if bank is open

  • bank_deposit_by_id(id, amount) - Deposit items by ID

  • bank_withdraw_by_id(id, amount) - Withdraw items

  • bank_get_amount_by_id(id) - Check item quantity

Example:

if bank_is_open() {
    bank_withdraw_by_id(1234, 10);  // Withdraw 10 items
    bank_deposit_all_by_name("Ore");
}

Inventory

Location: src/api/ui/tab/inventory.rs

Common Functions:

  • inventory_contains_by_id(id) - Check for item

  • inventory_get_count() - Total items

  • inventory_drop_by_id(id) - Drop item

  • inventory_interact(item, action) - Use item


Complete Example: Gathering Scenario

use osbot_api::api::scene::*;
use osbot_api::api::ui::bank::*;

fn gather_and_bank() -> bool {
    // 1. Get local player position
    let Some(player) = players_get_local_player() else {
        return false;
    };

    // 2. Find nearest ore rock
    let Some(ore) = objects_find_closest_by_name(
        OBJECTS_INTERACTABLE_OBJECT_FLAG,
        "Ore"
    ) else {
        return false;
    };

    // 3. Check if reachable
    if !map_can_reach_object(&ore) {
        return false;
    }

    // 4. Calculate path and walk
    if let Some(path) = map_find_local_path_to_object(&ore) {
        walking_walk_path(&path);
    }

    // 5. Interact with ore
    menu_interact(
        &ore.get_menu_vars(),
        &Some("Mine".to_string()),
        &None,
    );

    // 6. Wait for mining
    loop {
        if inventory_is_full() {
            break;
        }
    }

    // 7. Find and open bank
    let Some(bank) = objects_find_closest_by_name(
        OBJECTS_INTERACTABLE_OBJECT_FLAG,
        "Bank"
    ) else {
        return false;
    };

    bank_open();

    // 8. Deposit ore
    bank_deposit_all_by_name("Ore");

    true
}

OSBOT API - Rendering & Paint Documentation

Overview

The rendering system in OSBOT API provides tools for visualizing game elements, converting world coordinates to screen coordinates, and managing the camera viewport. This is essential for creating overlays, debugging tools, and understanding the 3D-to-2D projection pipeline.


Display & Viewport Management

Location: src/api/display.rs

The display system manages the game window, viewport dimensions, and coordinate transformations.

Core Display Functions

display_get_display_mode() -> DisplayMode

Retrieves the current display mode setting.

Returns: DisplayMode enum

  • DisplayMode::Fixed - Fixed screen layout (1:1 pixel ratio)

  • DisplayMode::ResizableClassic - Resizable classic interface

  • DisplayMode::ResizableModern - Resizable modern interface

Use Cases:

  • Adapting UI rendering to interface style

  • Adjusting overlay positioning

  • Handling different screen layouts

Example:

match display_get_display_mode() {
    DisplayMode::Fixed => {
        // Fixed UI - known dimensions
    },
    DisplayMode::ResizableClassic | DisplayMode::ResizableModern => {
        // Resizable UI - adapt positions dynamically
    }
}

display_is_modern_mode() -> bool

Quick check if using modern resizable interface.

Returns: bool - True if in modern resizable mode

display_get_viewport() -> Viewport

Gets the current viewport information.

Returns: Viewport struct containing:

  • width: i32 - Viewport width in pixels

  • height: i32 - Viewport height in pixels

  • depth: i32 - Viewport depth (for 3D calculations)

Use Cases:

  • Calculating overlay positions

  • Centering UI elements

  • Responsive rendering

Example:

let viewport = display_get_viewport();
let center_x = viewport.get_width() / 2;
let center_y = viewport.get_height() / 2;
println!("Viewport: {}x{}", viewport.get_width(), viewport.get_height());

display_get_viewport_width() -> i32

Gets viewport width in pixels.

display_get_viewport_height() -> i32

Gets viewport height in pixels.

display_get_viewport_depth() -> i32

Gets viewport depth for 3D projection calculations.

display_get_canvas_width() -> i32

Gets the full canvas width (including UI panels).

display_get_canvas_height() -> i32

Gets the full canvas height (including UI panels).

Use Cases:

  • Full-screen overlay rendering

  • Calculating UI element positions

  • Positioning elements relative to game window

display_get_root_widget_id() -> i32

Gets the root UI widget ID for the current display mode.

Returns: i32 - Widget ID (varies by mode)

  • Fixed mode: 548

  • Resizable classic: 161

  • Resizable modern: 164

Use Cases:

  • Widget hierarchy traversal

  • UI element identification

display_get_minimap_widget() -> Option<RSWidget>

Gets the minimap widget reference.

Returns: Option<RSWidget> - Minimap widget if accessible

Use Cases:

  • Getting minimap bounds for overlay

  • Minimap-based rendering

Display Utilities

display_is_point_in_polygon(point, vertices) -> bool

Checks if a point is inside a polygon.

Parameters:

  • point: (i32, i32) - Point to check

  • vertices: &[(i32, i32)] - Polygon vertices

Returns: bool - True if inside polygon

Use Cases:

  • Click detection on complex shapes

  • Collision detection with objects

  • Boundary checking

Example:

let vertices = vec![(0, 0), (100, 0), (100, 100), (0, 100)];
let mouse_pos = (50, 50);

if display_is_point_in_polygon(mouse_pos, &vertices) {
    println!("Click is inside the rectangle");
}

Coordinate Projection System

Location: src/api/util/projection/

The projection system converts 3D world coordinates into 2D screen coordinates for rendering.

ProjectionInfo

projection_info_get() -> &'static ProjectionInfo

Gets the cached projection information for the current frame.

Returns: &ProjectionInfo - Immutable reference to projection data

Use Cases:

  • World-to-screen conversions

  • Camera state queries

  • Rendering calculations

Properties accessed via ProjectionInfo:

  • get_plane() -> i32 - Current floor level

  • get_heightmap() -> &Heightmap - Elevation data

  • get_camera() -> &CameraInfo - Camera position/angle

  • get_viewport() -> &Viewport - Screen dimensions

  • is_valid() -> bool - Check if data is current

Example:

let projection = projection_info_get();
println!("Current plane: {}", projection.get_plane());
println!("Camera at: ({}, {})", 
    projection.get_camera().get_x(), 
    projection.get_camera().get_y());

Viewport Struct

pub struct Viewport {
    width: i32,
    height: i32,
    depth: i32,
}

Methods:

  • get_width() -> i32 - Viewport width

  • get_height() -> i32 - Viewport height

  • get_depth() -> i32 - Viewport depth

Heightmap

The heightmap contains elevation data for all tiles in the visible region.

Location: src/api/scene/heightmap.rs

Heightmap Methods

pub fn get_width(&self) -> i32;
pub fn get_height(&self) -> i32;
pub fn get_tile_height(&self, x: i32, y: i32, plane: i32) -> i32;
pub fn get_tile_setting(&self, x: i32, y: i32, plane: i32) -> i8;

Use Cases:

  • Getting ground elevation for NPCs/objects

  • Water level detection

  • Slope calculations

Example:

let heightmap = projection.get_heightmap();
let ground_height = heightmap.get_tile_height(100, 100, 0);
println!("Ground elevation at (100, 100): {}", ground_height);

Camera System

Location: src/api/camera.rs

The camera system controls the 3D perspective and view orientation.

Camera Information

camera_get_camera_info() -> CameraInfo

Gets complete camera state information.

Returns: CameraInfo struct containing:

  • x: i32 - Camera X position

  • y: i32 - Camera Y position

  • z: i32 - Camera Z position (height)

  • pitch: i32 - Vertical angle (0-2047, normalized)

  • yaw: i32 - Horizontal angle (0-2047, normalized)

  • scale_z: f32 - Vertical scaling factor

Example:

let camera = camera_get_camera_info();
println!("Camera position: ({}, {}, {})", 
    camera.get_x(), camera.get_y(), camera.get_z());
println!("Camera angle: yaw={}, pitch={}", 
    camera.get_yaw(), camera.get_pitch());

Camera State Queries

camera_get_pitch() -> i32

Gets camera vertical angle (pitch).

Returns: i32 - Pitch in game units (0-2047)

Range: 22 (bottom) to 67 (top)

camera_get_yaw() -> i32

Gets camera horizontal angle (rotation).

Returns: i32 - Yaw in game units (0-2047)

Use Cases:

  • Understanding current view direction

  • Calculating relative angles to objects

  • Direction-aware rendering

camera_get_x() -> i32

Camera world X coordinate.

camera_get_y() -> i32

Camera world Y coordinate.

camera_get_z() -> i32

Camera world Z coordinate (height).

camera_get_scale_z() -> f32

Zoom level scaling factor.

Use Cases:

  • Zoom-based rendering adjustments

  • Perspective calculations

camera_get_pitch_angle() -> i32

Gets pitch angle in degrees.

camera_get_yaw_angle() -> i32

Gets yaw angle in degrees.

Use Cases:

  • Human-readable angle values

  • UI display of camera angles

Camera Angle Constants

const CAMERA_MAX_PITCH: i32 = 67;  // Maximum upward angle
const CAMERA_MIN_PITCH: i32 = 22;  // Maximum downward angle

Camera Control

camera_move_pitch_angle(pitch: i32) -> bool

Adjusts camera vertical angle.

Parameters:

  • pitch: i32 - Change in pitch (positive = up, negative = down)

Returns: bool - Success

Example:

// Rotate camera upward
camera_move_pitch_angle(10);

// Rotate camera downward
camera_move_pitch_angle(-10);

camera_move_yaw_angle(yaw: i32) -> bool

Rotates camera horizontally.

Parameters:

  • yaw: i32 - Change in yaw (positive = right, negative = left)

camera_to_top() -> bool

Moves camera to maximum height angle.

camera_to_bottom() -> bool

Moves camera to minimum height angle.

camera_move_to_entity<T: Entity>(entity: &T) -> bool

Orients camera to look at an entity.

Parameters:

  • entity - Target entity to look at

Returns: bool - Success

Use Cases:

  • Focus on NPCs during interaction

  • Looking at players

  • Combat monitoring

Example:

if let Some(npc) = npcs_find_closest_by_id(1234) {
    camera_move_to_entity(&npc);
}

camera_move_to_position(position: &Position) -> bool

Orients camera toward a position.

Parameters:

  • position - Target world position

camera_move_to_angle(yaw: i32, pitch: i32) -> bool

Sets camera to specific angles.

Parameters:

  • yaw - Target yaw angle

  • pitch - Target pitch angle

camera_can_use_mouse_control() -> bool

Checks if middle-mouse camera control is enabled.

Use Cases:

  • Detecting player-controlled camera

  • Preventing automation conflicts

camera_get_yaw_to(origin: &Position, position: &Position) -> i32

Calculates yaw angle from one position to another.

Returns: i32 - Required yaw to face target

Use Cases:

  • Calculating relative angles

  • Predictive camera positioning

camera_get_pitch_to(origin: &Position, position: &Position, height: i32) -> i32

Calculates pitch angle from position to target.

Parameters:

  • origin - Starting position

  • position - Target position

  • height - Height difference

Returns: i32 - Required pitch to face target


Rendering & Screen Coordinates

Location: src/api/display.rs

Converting world coordinates to screen coordinates is essential for all overlay rendering.

Screen Coordinate Conversion

display_get_screen_coordinates(grid_x, grid_y, plane, elevation, projection_info) -> (i32, i32)

Converts world coordinates to screen coordinates.

Parameters:

  • grid_x: i32 - World X coordinate

  • grid_y: i32 - World Y coordinate

  • plane: i32 - Floor level (0-3)

  • elevation: i32 - Z height above ground

  • projection_info: &ProjectionInfo - Camera/viewport data

Returns: (i32, i32) - Screen X and Y coordinates

Use Cases:

  • Placing overlays on entities

  • Drawing lines to targets

  • Rendering visual indicators

Example:

let projection = projection_info_get();
let screen_coords = display_get_screen_coordinates(
    100,  // world X
    100,  // world Y
    0,    // ground plane
    64,   // elevation (entity height)
    projection
);

println!("Entity appears at screen: {:?}", screen_coords);

display_get_model_screen_coordinates(model, grid_x, grid_y, plane, elevation, projection_info) -> Vec<(i32, i32)>

Converts model vertices to screen coordinates.

Parameters:

  • model: &Model - 3D model data

  • grid_x, grid_y, plane, elevation - World position

  • projection_info - Camera/viewport data

Returns: Vec<(i32, i32)> - Screen coordinates for all vertices

Use Cases:

  • Drawing bounding boxes around models

  • Rendering detailed object overlays

  • Complex shape rendering

Interaction Point Calculation

display_get_interaction_point(bounds: (i32, i32, i32, i32)) -> (i32, i32)

Calculates interaction point from screen bounds.

Parameters:

  • bounds - (x, y, width, height) screen rectangle

Returns: (i32, i32) - Interaction point within bounds

Use Cases:

  • Finding click target within object bounds

  • Randomizing click positions

Geometric Utilities

display_calculate_triangle_area(p1, p2, p3) -> f32

Calculates area of a triangle.

Parameters:

  • p1, p2, p3: (i32, i32) - Triangle vertices

Returns: f32 - Triangle area

Use Cases:

  • Weighted random point selection

  • Area-based calculations

display_point_in_triangle(point, a, b, c) -> bool

Checks if point is inside triangle.

Parameters:

  • point - Test point

  • a, b, c - Triangle vertices

Returns: bool - True if inside

Use Cases:

  • Click detection on triangular areas

  • Complex shape testing

display_get_random_point_in_triangle(p1, p2, p3) -> (i32, i32)

Generates random point within triangle.

Returns: (i32, i32) - Random point inside triangle

Use Cases:

  • Randomized click positions on objects

  • Area-based mouse movement

Example:

let triangle_vertices = [(0, 0), (100, 0), (50, 100)];
let random_click = display_get_random_point_in_triangle(
    triangle_vertices[0],
    triangle_vertices[1],
    triangle_vertices[2]
);

Polygon Utilities

display_is_inside_convex_polygon(polygon, point) -> bool

Checks if point is inside convex polygon.

Parameters:

  • polygon: &[(i32, i32)] - Polygon vertices

  • point: (i32, i32) - Point to test

Returns: bool - True if inside

display_calculate_convex_hull(points: Vec<(i32, i32)>) -> ConvexHull

Calculates convex hull from points.

Returns: ConvexHull - Resulting convex hull structure

Use Cases:

  • Generating object bounding shapes

  • Click region optimization

Clipping Space

display_get_world_screen_area() -> ClippingSpace

Gets the screen area containing world view.

Returns: ClippingSpace - Screen clipping region

Methods:

  • contains(x: i32, y: i32) -> bool - Check if point is visible

Use Cases:

  • Clipping rendering to viewport

  • Visibility culling


Minimap Rendering

Location: src/api/ui/minimap.rs

The minimap is a bird's-eye view of the game world. Converting between world and minimap coordinates is essential.

Minimap State

minimap_get_pitch() -> i32

Gets minimap vertical rotation.

minimap_get_yaw() -> i32

Gets minimap horizontal rotation.

Returns: i32 - Angle (0-2047)

minimap_get_zoom() -> i32

Gets minimap zoom level.

Returns: i32 - Zoom factor

minimap_get_angle() -> i32

Gets effective minimap angle (accounting for rotation).

Returns: i32 - Combined angle

Use Cases:

  • Calculating minimap point positions

  • Adjusting rendering for map rotation

Minimap Coordinate Conversion

display_get_minimap_coordinates(local_x, local_y) -> (i32, i32)

Converts world coordinates to minimap coordinates.

Parameters:

  • local_x: i32 - Local X coordinate

  • local_y: i32 - Local Y coordinate

Returns: (i32, i32) - Minimap screen coordinates

Use Cases:

  • Drawing indicators on minimap

  • Minimap-based overlays

Example:

if let Some(player) = players_get_local_player() {
    let local_x = player.get_local_x();
    let local_y = player.get_local_y();
    let minimap_pos = display_get_minimap_coordinates(local_x, local_y);
    println!("Player on minimap: {:?}", minimap_pos);
}

display_get_minimap_coordinates_from_args(bounds, zoom, angle, player_x, player_y, target_x, target_y) -> (i32, i32)

Advanced minimap coordinate calculation with explicit parameters.

Parameters:

  • minimap_bounds: (i32, i32, i32, i32) - Minimap screen area

  • minimap_zoom: i32 - Zoom level

  • minimap_angle: i32 - Rotation angle

  • player_local_x, player_local_y - Player position

  • position_local_x, position_local_y - Target position

Returns: (i32, i32) - Minimap screen coordinates

Minimap Range Queries

minimap_is_position_in_minimap_range(player_position, position) -> bool

Checks if position is visible on minimap.

Parameters:

  • player_position - Player's position

  • position - Position to check

Returns: bool - True if within minimap render distance

Use Cases:

  • Determining if entities are map-visible

  • Minimap icon rendering decisions

minimap_get_max_range() -> i32

Gets maximum minimap visibility range.

Returns: i32 - Range in tiles

minimap_is_position_on_map(position) -> bool

Checks if position appears on minimap currently.

Returns: bool - True if on visible map area

Minimap Interaction

minimap_click_position(position: &Position) -> bool

Clicks a position via minimap (fast travel).

Parameters:

  • position - Position to click

Returns: bool - Success

Use Cases:

  • Quick navigation using minimap

  • Long-distance movement

Example:

let target = Position::new(100, 100, 0);
if minimap_is_position_in_minimap_range(&player_pos, &target) {
    minimap_click_position(&target);
}

minimap_hover_position(position: &Position) -> bool

Hovers mouse over a minimap position.

Returns: bool - Success

Use Cases:

  • Previewing positions before clicking

  • Hover-based interactions


Painting & Overlay Examples

ConvexHull Rendering

Location: src/api/scene/convex_hull.rs

The ConvexHull structure represents a 2D object outline projected to screen coordinates and can be rendered.

pub struct ConvexHull {
    points: Vec<(i32, i32)>  // Screen coordinates
}

impl ConvexHull {
    pub fn render(&self, painter: &Painter, color: Color32);
    pub fn render_offset(&self, painter: &Painter, offset: (i32, i32), color: Color32);
}

Methods:

  • contains(point) -> bool - Check if point inside hull

  • get_central_point() -> (i32, i32) - Center of hull

  • get_interaction_point() -> (i32, i32) - Interaction target

  • is_visible() -> bool - Currently on screen

Example: Drawing Object Overlays

use eframe::egui::{Color32, Painter};

fn render_entity_overlay(
    painter: &Painter,
    entity: &impl Entity,
    color: Color32
) {
    let projection = projection_info_get();

    // Get screen coordinates
    let screen_pos = display_get_screen_coordinates(
        entity.get_x(),
        entity.get_y(),
        projection.get_plane(),
        entity.get_height(),
        projection
    );

    // Draw circle at position
    painter.circle(
        Pos2::new(screen_pos.0 as f32, screen_pos.1 as f32),
        10.0,
        color,
        Stroke::new(2.0, Color32::WHITE)
    );
}

Example: Rendering a Path

fn render_walking_path(
    painter: &Painter,
    path: &Vec<Position>,
    color: Color32
) {
    let projection = projection_info_get();

    let mut screen_points = Vec::new();

    for position in path {
        let screen = display_get_screen_coordinates(
            position.x,
            position.y,
            projection.get_plane(),
            0,
            projection
        );
        screen_points.push(Pos2::new(screen.0 as f32, screen.1 as f32));
    }

    // Draw line connecting all points
    for i in 0..screen_points.len() - 1 {
        painter.line_segment(
            [screen_points[i], screen_points[i + 1]],
            Stroke::new(2.0, color)
        );
    }
}

Example: Minimap Indicators

fn render_minimap_targets(
    painter: &Painter,
    targets: &Vec<Position>,
    color: Color32
) {
    for target in targets {
        if minimap_is_position_in_minimap_range(
            &players_get_local_player().unwrap().get_position(),
            target
        ) {
            let minimap_pos = display_get_minimap_coordinates(
                target.x,
                target.y
            );

            painter.circle(
                Pos2::new(minimap_pos.0 as f32, minimap_pos.1 as f32),
                4.0,
                color,
                Stroke::new(1.0, Color32::WHITE)
            );
        }
    }
}

Display Mode Handling

Fixed vs Resizable Layout

The display system supports three different UI layouts that affect coordinate calculations:

match display_get_display_mode() {
    DisplayMode::Fixed => {
        // Coordinates are fixed (640x480 viewport)
        // UI elements have fixed positions
        // No scaling needed
    },
    DisplayMode::ResizableClassic => {
        // Classic tabbed interface that can be resized
        // Use display_get_root_widget_id() = 161
        // Calculate positions relative to viewport
    },
    DisplayMode::ResizableModern => {
        // Modern side-panel interface (2015+ style)
        // Use display_get_root_widget_id() = 164
        // More complex layout with docked widgets
    }
}

Performance Considerations

Projection Caching

The ProjectionInfo is cached and updated per frame:

// Cached internally - cheap to call
let projection = projection_info_get();

// Reuse for multiple conversions
for entity in entities {
    let screen = display_get_screen_coordinates(
        entity.get_x(),
        entity.get_y(),
        projection.get_plane(),
        entity.get_height(),
        projection  // Reuse cached projection
    );
}

Viewport Queries

Viewport information is queried frequently:

// Cache these values if using multiple times
let viewport_width = display_get_viewport_width();
let viewport_height = display_get_viewport_height();

// Use cached values for calculations
let center_x = viewport_width / 2;
let center_y = viewport_height / 2;

Clipping and Culling

Always check visibility before rendering:

let clipping = display_get_world_screen_area();

if clipping.contains(screen_x, screen_y) {
    // Only render if within visible area
    painter.circle(...);
}

Common Rendering Patterns

Pattern 1: Draw NPC at Position

let npc = npcs_find_closest_by_id(1234).unwrap();
let projection = projection_info_get();
let screen = display_get_screen_coordinates(
    npc.get_x(), npc.get_y(), projection.get_plane(),
    64, projection  // NPC height
);
painter.circle(Pos2::new(screen.0 as f32, screen.1 as f32), 5.0, Color32::RED, Stroke::new(1.0, Color32::WHITE));

Pattern 2: Minimap Marker

if minimap_is_position_in_minimap_range(&player_pos, &target) {
    let minimap = display_get_minimap_coordinates(target.x, target.y);
    painter.circle(Pos2::new(minimap.0 as f32, minimap.1 as f32), 3.0, Color32::BLUE, Stroke::new(1.0, Color32::WHITE));
}

Pattern 3: Distance-Based Coloring

fn get_distance_color(distance: i32) -> Color32 {
    match distance {
        0..=10 => Color32::RED,
        11..=20 => Color32::YELLOW,
        21..=50 => Color32::GREEN,
        _ => Color32::GRAY,
    }
}

OSBOT API - Text & Image Rendering Guide

Overview

The rendering documentation I provided covers geometric rendering (circles, lines, shapes) using the egui framework, but does not explicitly cover text and image rendering for overlays.

However, the API provides the foundation through two key mechanisms:

  1. egui UI Framework - For text, images, and UI elements

  2. Script Rendering Hooks - Where you can draw custom overlays


Text & Image Rendering Architecture

The Rendering Pipeline

The API uses egui (from the eframe crate) as its rendering backend. You get access to rendering through the Script trait's rendering callbacks.

Script Trait Rendering Methods

Location: src/api/script/script.rs

The Script trait provides two rendering entry points:

pub trait Script {
    // ... other methods ...

    /// Called every frame to render custom UI
    fn on_render(&self, ui: &mut egui::Ui) {
        // Your overlay rendering goes here
    }

    /// Called every frame to render debug overlays
    fn on_debug_render(&self, ui: &mut egui::Ui) {
        // Debug-specific rendering
    }
}

These methods receive a mutable reference to egui::Ui, which is the primary interface for rendering text, images, and UI elements.


Text Rendering

Basic Text Rendering

Using egui::Ui:

impl Script for MyScript {
    fn on_render(&self, ui: &mut egui::Ui) {
        // Display simple text label
        ui.label("Simple text overlay");

        // Display colored text
        ui.colored_label(egui::Color32::RED, "Red text");

        // Display text with custom font size
        ui.label(egui::RichText::new("Large text").size(20.0));
    }
}

Text with Colors

use eframe::egui::{Color32, RichText};

fn on_render(&self, ui: &mut egui::Ui) {
    // Red text
    ui.label(RichText::new("Health: Low").color(Color32::RED));

    // Green text
    ui.label(RichText::new("Status: Safe").color(Color32::GREEN));

    // Yellow text with larger font
    ui.label(RichText::new("Warning!").color(Color32::YELLOW).size(18.0));
}

Monospace/Code Text

fn on_render(&self, ui: &mut egui::Ui) {
    // Monospace font (good for coordinates, numbers)
    ui.label(RichText::new("X: 100, Y: 200").monospace());

    // Combine styles
    ui.label(RichText::new("Position: 100, 200")
        .monospace()
        .color(Color32::CYAN)
        .size(14.0)
    );
}

Heading Styles

fn on_render(&self, ui: &mut egui::Ui) {
    ui.heading("Main Title");        // Large heading
    ui.subheading("Subtitle");        // Medium heading
}

Text Layout & Positioning

use eframe::egui::{Rect, Vec2, Align2};

fn on_render(&self, ui: &mut egui::Ui) {
    // Position text at specific screen location
    let screen_rect = ui.available_rect_before_wrap();

    // Top-left corner
    ui.painter().text(
        egui::Pos2::new(10.0, 10.0),
        Align2::LEFT_TOP,
        "Text at top-left",
        egui::FontId::default(),
        Color32::WHITE
    );

    // Top-right corner
    ui.painter().text(
        egui::Pos2::new(screen_rect.right() - 10.0, 10.0),
        Align2::RIGHT_TOP,
        "Text at top-right",
        egui::FontId::default(),
        Color32::WHITE
    );
}

Text Alignment Options

use eframe::egui::Align2;

// Align2(horizontal, vertical) options:
// LEFT_TOP, CENTER_TOP, RIGHT_TOP
// LEFT_CENTER, CENTER, RIGHT_CENTER
// LEFT_BOTTOM, CENTER_BOTTOM, RIGHT_BOTTOM

Dynamic Text with Variables

fn on_render(&self, ui: &mut egui::Ui) {
    if let Some(player) = players_get_local_player() {
        let name = player.get_name();
        let x = player.get_x();
        let y = player.get_y();

        ui.label(format!("Player: {}", name));
        ui.label(format!("Position: ({}, {})", x, y));
    }
}

Multi-line Text

fn on_render(&self, ui: &mut egui::Ui) {
    let text = "Line 1\nLine 2\nLine 3";
    ui.label(text);
}

Image Rendering

Screen Capture as Texture

The API provides a screen capture function that converts game frames to textures:

Location: src/api/util/screen_capture.rs

pub fn screen_capture_capture_game_image(title: String, ui: &egui::Ui) -> Option<TextureHandle>
pub fn screen_capture_capture_game() -> Option<(i32, i32, Vec<u8>)>

screen_capture_capture_game_image(title, ui) -> Option<TextureHandle>

Captures the game screen and returns as an egui texture.

Parameters:

  • title: String - Label for the captured texture

  • ui: &egui::Ui - UI context for texture registration

Returns: Option<TextureHandle> - Handle to rendered texture, or None if capture failed

Use Cases:

  • Displaying game state snapshots

  • Debug visualization of game frames

  • Recording/replay features

screen_capture_capture_game() -> Option<(i32, i32, Vec<u8>)>

Captures raw game frame data.

Returns: Option<(width, height, pixel_data)> - Image dimensions and RGBA pixel data

Use Cases:

  • Processing game frames programmatically

  • Converting to custom image formats

  • Analysis and debugging

Rendering Captured Images

use eframe::egui::TextureHandle;

fn on_render(&self, ui: &mut egui::Ui) {
    // Capture the game screen
    if let Some(texture) = screen_capture_capture_game_image("game_view".to_string(), ui) {
        // Display as image
        ui.image(&texture, egui::Vec2::new(640.0, 480.0));
    }
}

Using External Image Files

use eframe::egui::{ColorImage, TextureHandle, TextureOptions};
use image::ImageReader;
use std::io::Cursor;

fn on_render(&self, ui: &mut egui::Ui) {
    // Load image from file
    if let Ok(img) = ImageReader::open("path/to/image.png") {
        if let Ok(rgba) = img.decode().map(|i| i.to_rgba8()) {
            let size = [rgba.width() as usize, rgba.height() as usize];
            let pixels = rgba.into_raw();

            // Convert to egui ColorImage
            let color_image = ColorImage::from_rgba_unmultiplied(
                size,
                &pixels
            );

            // Register texture
            let texture = ui.ctx().load_texture(
                "my_image",
                color_image,
                TextureOptions::LINEAR
            );

            // Display
            ui.image(&texture, egui::Vec2::new(200.0, 200.0));
        }
    }
}

Advanced Rendering Patterns

Pattern 1: HUD Overlay with Text

fn on_render(&self, ui: &mut egui::Ui) {
    // Top-left corner HUD
    egui::Window::new("HUD")
        .fixed_pos(egui::Pos2::new(10.0, 10.0))
        .show(ui.ctx(), |ui| {
            if let Some(player) = players_get_local_player() {
                ui.label(format!("Position: ({}, {})", 
                    player.get_x(), player.get_y()));
                ui.label(format!("Health: {}", 64)); // Placeholder
            }
        });
}

Pattern 2: Debug Overlay

fn on_debug_render(&self, ui: &mut egui::Ui) {
    egui::Window::new("Debug")
        .resizable(true)
        .show(ui.ctx(), |ui| {
            ui.label(format!("FPS: {}", 60)); // Would be dynamic
            ui.label(format!("Entities: {}", players_get_all().count()));

            if let Some(player) = players_get_local_player() {
                ui.group(|ui| {
                    ui.label("Player Info:");
                    ui.label(format!("  Position: ({}, {})", 
                        player.get_x(), player.get_y()));
                    ui.label(format!("  Combat Level: {}", 
                        player.get_combat_level()));
                });
            }
        });
}

Pattern 3: Info Panel with Formatting

fn on_render(&self, ui: &mut egui::Ui) {
    egui::Frame::dark_canvas(ui.style())
        .margin(egui::Vec2::splat(10.0))
        .show(ui, |ui| {
            ui.heading("Bot Status");
            ui.separator();

            ui.horizontal(|ui| {
                ui.label("Status:");
                ui.colored_label(Color32::GREEN, "Running");
            });

            ui.horizontal(|ui| {
                ui.label("Progress:");
                ui.colored_label(Color32::YELLOW, "50%");
            });
        });
}

Pattern 4: Coordinate Display at World Position

fn on_render(&self, ui: &mut egui::Ui) {
    if let Some(player) = players_get_local_player() {
        let projection = projection_info_get();

        // Convert world to screen coordinates
        let screen = display_get_screen_coordinates(
            player.get_x(),
            player.get_y(),
            projection.get_plane(),
            64,
            projection
        );

        // Draw text at that screen position
        ui.painter().text(
            egui::Pos2::new(screen.0 as f32, screen.1 as f32),
            egui::Align2::CENTER_CENTER,
            format!("{}, {}", player.get_x(), player.get_y()),
            egui::FontId::default(),
            Color32::WHITE
        );
    }
}

Complete Example: Full-Featured Overlay

use osbot_api::prelude::*;
use eframe::egui::{Color32, RichText, Pos2, Align2};

struct MyScript {
    // Script state
}

impl Script for MyScript {
    fn new() -> Self {
        MyScript {}
    }

    fn on_start(&mut self, params: Option<String>) {
        println!("Script started!");
    }

    fn on_loop(&mut self) -> i32 {
        // Main loop logic here
        100 // Sleep for 100ms
    }

    fn on_render(&self, ui: &mut egui::Ui) {
        // Main HUD window
        egui::Window::new("Overlay")
            .fixed_pos(Pos2::new(20.0, 20.0))
            .default_width(300.0)
            .show(ui.ctx(), |ui| {
                ui.heading("Bot Control Panel");
                ui.separator();

                // Player info section
                if let Some(player) = players_get_local_player() {
                    ui.group(|ui| {
                        ui.label(RichText::new("Player Information")
                            .color(Color32::CYAN).underline());
                        ui.label(format!("Name: {}", player.get_name()));
                        ui.label(format!("Level: {}", player.get_combat_level()));
                        ui.label(format!("Position: ({}, {})", 
                            player.get_x(), player.get_y()));
                    });
                }

                ui.separator();

                // World info section
                let projection = projection_info_get();
                ui.group(|ui| {
                    ui.label(RichText::new("World Information")
                        .color(Color32::CYAN).underline());
                    ui.label(format!("Plane: {}", projection.get_plane()));
                    ui.label(format!("Viewport: {}x{}", 
                        display_get_viewport_width(),
                        display_get_viewport_height()
                    ));
                });

                ui.separator();

                // Entity counts
                ui.group(|ui| {
                    ui.label(RichText::new("Entities")
                        .color(Color32::CYAN).underline());
                    ui.label(format!("Players: {}", players_get_all().count()));
                    ui.label(format!("NPCs: {}", npcs_get_all().count()));
                });
            });

        // Draw coordinates at specific screen positions
        if let Some(player) = players_get_local_player() {
            let projection = projection_info_get();
            let screen = display_get_screen_coordinates(
                player.get_x(), player.get_y(),
                projection.get_plane(), 64, projection
            );

            ui.painter().text(
                Pos2::new(screen.0 as f32, (screen.1 - 20) as f32),
                Align2::CENTER_TOP,
                player.get_name(),
                egui::FontId::default(),
                Color32::WHITE
            );
        }
    }

    fn on_debug_render(&self, ui: &mut egui::Ui) {
        egui::Window::new("Debug Info")
            .fixed_pos(Pos2::new(20.0, 400.0))
            .show(ui.ctx(), |ui| {
                ui.label("Camera Info:");
                let camera = camera_get_camera_info();
                ui.label(format!("Position: ({}, {}, {})", 
                    camera.get_x(), camera.get_y(), camera.get_z()));
                ui.label(format!("Pitch: {}, Yaw: {}", 
                    camera.get_pitch(), camera.get_yaw()));
            });
    }

    fn can_start(&self) -> bool {
        true
    }

    fn is_running(&self) -> bool {
        true
    }

    fn is_alive(&self) -> bool {
        true
    }
}

Available egui Components

The egui framework provides many components you can use in rendering:

Text Components

  • ui.label() - Simple text

  • ui.heading() - Large heading

  • ui.subheading() - Medium heading

  • ui.monospace_multiline_text() - Code/data display

  • RichText - Styled text (colors, sizes, fonts)

Layout Components

  • ui.horizontal() - Side-by-side layout

  • ui.vertical() - Top-to-bottom layout

  • ui.group() - Grouped content with background

  • egui::Window - Floating window

  • egui::Frame - Bordered frame

  • ui.separator() - Visual divider

Input Components

  • ui.button() - Clickable button

  • ui.checkbox() - Toggle checkbox

  • ui.slider() - Value slider

  • ui.text_edit_singleline() - Text input

Visual Elements

  • ui.painter().circle() - Draw circle

  • ui.painter().line_segment() - Draw line

  • ui.painter().rect() - Draw rectangle

  • ui.painter().text() - Positioned text

  • ui.image() - Display image/texture


Color32 Predefined Colors

use eframe::egui::Color32;

// Common colors
Color32::WHITE
Color32::BLACK
Color32::RED
Color32::GREEN
Color32::BLUE
Color32::CYAN
Color32::MAGENTA
Color32::YELLOW
Color32::GRAY
Color32::DARK_GRAY
Color32::LIGHT_GRAY

// Custom color (RGBA)
Color32::from_rgba_unmultiplied(r, g, b, a)

Painter & Advanced Drawing

For more complex rendering, use the Painter directly:

fn on_render(&self, ui: &mut egui::Ui) {
    let painter = ui.painter();

    // Draw shapes
    painter.circle_filled(
        egui::Pos2::new(100.0, 100.0),
        10.0,
        Color32::RED
    );

    // Draw text at arbitrary position
    painter.text(
        Pos2::new(50.0, 50.0),
        Align2::CENTER_CENTER,
        "Custom text",
        egui::FontId::default(),
        Color32::WHITE
    );

    // Draw rectangle
    painter.rect_filled(
        egui::Rect::from_two_pos(
            Pos2::new(0.0, 0.0),
            Pos2::new(100.0, 100.0)
        ),
        0.0,
        Color32::BLUE
    );
}

  • Tom changed the title to Some native documentation
  • Khaleesi changed the title to AI generated Native documentation

Create an account or sign in to comment

Recently Browsing 0

  • No registered users viewing this page.

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.