Coordinate Systems

Understand the different coordinate systems in RuneLite: world coordinates, local coordinates, and screen coordinates, and how to convert between them.

RuneLite uses three different coordinate systems. Understanding them is essential for drawing overlays at specific world locations.


Coordinate Systems


1. WorldPoint (World Coordinates)

Absolute game world coordinates:

- **X, Y**: World position (e.g., 3200, 3200)

- **Plane**: Floor level (0 = ground, 1 = first floor, etc.)

- **Example**: new WorldPoint(3200, 3200, 0)


2. LocalPoint (Local Coordinates)

Relative to the current region:

- Used internally by the game

- Changes when you move to a different region

- **Example**: LocalPoint.fromWorld(client, worldPoint)


3. Screen/Canvas Coordinates

Pixel positions on your screen:

- **X, Y**: Screen pixel coordinates

- Used for drawing overlays

- **Example**: Point(100, 200) means 100 pixels from left, 200 from top


Converting Between Systems


You need to convert: **WorldPoint → LocalPoint → Screen Point**


\`\`\`java

// Step 1: WorldPoint to LocalPoint

WorldPoint worldPoint = new WorldPoint(3200, 3200, 0);

LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);

if (localPoint == null) {

return; // Point not in current region

}


// Step 2: LocalPoint to Screen Point

Point screenPoint = Perspective.localToCanvas(

client, localPoint, client.getPlane());

if (screenPoint == null) {

return; // Point not visible on screen

}


// Now you can draw at screenPoint.x, screenPoint.y

\`\`\`


Drawing at World Locations


Common use case: Draw a marker at a specific world location:


\`\`\`java

WorldPoint targetLocation = new WorldPoint(3200, 3200, 0);

LocalPoint localPoint = LocalPoint.fromWorld(client, targetLocation);

if (localPoint != null) {

Point screenPoint = Perspective.localToCanvas(

client, localPoint, client.getPlane());

if (screenPoint != null) {

graphics.setColor(Color.RED);

graphics.fillOval(screenPoint.x - 5, screenPoint.y - 5, 10, 10);

}

}

\`\`\`


Minimap Coordinates


You can also convert to minimap coordinates:


\`\`\`java

LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);

if (localPoint != null) {

Point minimapPoint = Perspective.localToMinimap(client, localPoint);

if (minimapPoint != null) {

// Draw on minimap

graphics.setColor(new Color(255, 255, 0, 180)); // Semi-transparent yellow

graphics.fillOval(minimapPoint.x - 3, minimapPoint.y - 3, 6, 6);

}

}

\`\`\`


Best Practices


- Always check for null after coordinate conversions

- Points may be null if:

- Not in current region (LocalPoint)

- Not visible on screen (Screen Point)

- Outside minimap bounds (Minimap Point)

- Use the correct plane value when converting

- Cache conversions if drawing the same point every frame

Code Examples

Example 1

java
1// Convert world coordinates to screen coordinates
2WorldPoint worldPoint = npc.getWorldLocation();
3LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
4if (localPoint != null) {
5    Point screenPoint = Perspective.localToCanvas(
6        client, localPoint, client.getPlane());
7    if (screenPoint != null) {
8        // Draw marker at screen position
9        graphics.setColor(Color.RED);
10        graphics.fillOval(screenPoint.x - 5, screenPoint.y - 5, 10, 10);
11    }
12}

Example 2

java
1// Draw on minimap
2WorldPoint target = new WorldPoint(3200, 3200, 0);
3LocalPoint localPoint = LocalPoint.fromWorld(client, target);
4if (localPoint != null) {
5    Point minimapPoint = Perspective.localToMinimap(client, localPoint);
6    if (minimapPoint != null) {
7        graphics.setColor(new Color(255, 255, 0, 180)); // Semi-transparent yellow
8        graphics.fillOval(minimapPoint.x - 3, minimapPoint.y - 3, 6, 6);
9    }
10}

Example 3

java
1// Check if world point is visible
2public boolean isWorldPointVisible(WorldPoint worldPoint) {
3    LocalPoint localPoint = LocalPoint.fromWorld(client, worldPoint);
4    if (localPoint == null) {
5        return false; // Not in current region
6    }
7    
8    Point screenPoint = Perspective.localToCanvas(
9        client, localPoint, client.getPlane());
10    return screenPoint != null; // Visible if screen point exists
11}