FogBot Scripting API

Complete API documentation for script authors • C# • v2.0

Introduction

FogBot scripts run inside the bot as C# code and communicate with the game through the FogBot.Objects API. This documentation contains all public methods and properties intended for script authors.

using FogBot.Objects;
public class ExternalScript { ... }
Every script must include these using statements and class.

Script Lifecycle

Scripts are compiled by CS-Script. Entry point:
public static void Main(FogBot.Objects.Client client)

The Main method is called once. For continuous operation, use a while (true) loop with Thread.Sleep(...).

⚠️ ALWAYS check client.Player.Connected before operating!
If the player disconnects while the script is running - crash.

Quick Examples

1. Auto-healing for mage
using System;
using System.Threading;
using FogBot.Objects;

public class ExternalScript {
  public static void Main(Client client) {
    Random rand = new Random();
    while (true) {
      Thread.Sleep(rand.Next(800, 1600));
      if (!client.Player.Connected) continue;
      
      if (client.Player.HealthPercent <= 70 && client.Player.Mana >= 40) {
        client.Packets.Say("exura gran");
        Thread.Sleep(rand.Next(600, 900));
      }
    }
  }
}
2. Collecting gold from ground to backpack
using System;
using System.Linq;
using System.Threading;
using FogBot.Objects;

public class ExternalScript {
  public static void Main(Client client) {
    ushort goldId = 3031;
    while (true) {
      Thread.Sleep(100);
      if (!client.Player.Connected) continue;
      
      var lootBag = client.Inventory.GetContainers()
                    .FirstOrDefault(c => c.IsOpen && !c.IsFull);
      if (lootBag == null) continue;
      
      var tiles = client.Map.GetTilesOnScreen();
      foreach (var t in tiles.GetTiles()) {
        if (!t.ContainsObject(goldId)) continue;
        var item = t.GetTopMoveItem();
        if (item == null) continue;
        
        var slot = lootBag.GetBestSlot(item.ToItemLocation());
        if (slot == null) continue;
        
        item.Move(slot);
        item.WaitForInteraction(500);
      }
    }
  }
}
3. Fishing on random water tiles
using System;
using System.Linq;
using System.Threading;
using FogBot.Objects;

public class ExternalScript {
  public static void Main(Client client) {
    Random rand = new Random();
    ushort[] waterIDs = new ushort[] { 4597, 4598, 4599, 4600 };
    
    while (true) {
      Thread.Sleep(rand.Next(600, 1200));
      if (!client.Player.Connected || client.Player.Cap <= 7) continue;
      
      Item rod = client.Inventory.GetItem(client.ItemList.Tools.FishingRod);
      if (rod == null) continue;
      
      var fishyTiles = client.Map.GetTilesWithObjects(waterIDs).GetTiles().ToList();
      if (fishyTiles.Count == 0) continue;
      
      var tile = fishyTiles[rand.Next(fishyTiles.Count)];
      rod.UseOnLocation(tile.WorldLocation);
      Thread.Sleep(rand.Next(250, 500));
    }
  }
}

FogBot.Objects.Client

Main entry point to the API. Provides access to player, map, inventory, packets, modules, and helpers.

Properties

Player Player
Player object
Map Map
Map and tiles
Inventory Inventory
Inventory and containers
BattleList BattleList
Monster/player list
PacketCollection Packets
Sending packetsIMPORTANT
ModuleCollection Modules
Cavebot, Healer, etc.
ItemList ItemList
Item IDs
Window Window
StatusBar and window
PathFinder PathFinder
Global pathfinding
LocalPathFinder LocalPathFinder
Local pathfinding
MiniMap MiniMap
Automap
Vip Vip
VIP list
AreaEffectsCollection AreaEffects
AoE patterns

Methods

static IEnumerable<Client> GetClients(string className = "TibiaClient")
Returns all open Tibia clients. Use .FirstOrDefault() to get the first one.
void LoadProperties(bool loadObjectProperties = true)
Initializes all objects and loads item properties from Tibia.dat.
ObjectProperties GetObjectProperty(ushort id)
Returns item property flags (IsContainer, IsStackable, etc.).

FogBot.Objects.Player

Represents your player. Properties reflect in-game values and can be read/set.

Properties

bool Connected
True if logged in
uint ID
Player ID
string Name
Player name
Location Location
Player position
bool IsWalking
Whether player is walking
ushort Health
Current HP
ushort HealthMax
Maximum HP
ushort HealthPercent
HP %
ushort Mana
Current mana
ushort ManaMax
Maximum mana
ushort ManaPercent
Mana %
uint Soul
Soul points
uint Cap
Capacity
uint Stamina
Stamina
uint Experience
Experience
uint Level
Level
int LevelPercent
% to next level
uint TargetR/W
Attacked creature ID
Creature TargetCreature
Attacked creature object
uint FollowID
Followed ID
Location GoToSET
Set to start walking
FightStance FightStance
Offensive/Balanced/Defensive
FightMode FightMode
Attack/Chase/Stand
SafeMode SafeMode
Enabled/Disabled
uint LightR/W
Light intensity (0-255)
uint LightColorR/W
Light color (0-255)

Methods

void MakeRune(string spellName, ushort runeMana, bool doMakeUntilMana = false, int makeUntilMana = 0)
Automatically makes runes. Moves blank to right hand, says spell, waits for transformation.
Usage example:
// Set attack target
client.Player.Target = creatureID;

// Start walking
client.Player.GoTo = new Location(100, 200, 7);

// Make UH runes until mana > 30% max
client.Player.MakeRune("adura vita", 100, true, (ushort)(client.Player.ManaMax * 0.3));

// Set light hack (bright yellow light)
if (client.Player.Light < 8) {
  client.Player.Light = 20;
  client.Player.LightColor = 215;
}

Client.PacketCollection (client.Packets)

Wrappers for sending packets to the game. Use with caution and delays!

Communication methods

void Say(string message)
Speak in default channel. Used for spells: client.Packets.Say("exura")
void PrivateMessage(string recipient, string message)
Send private message to player.
void ChannelMessage(Enums.ChatChannel channel, string message)
Send message to channel (Help, Trade, etc.).

Action methods

void Turn(Enums.Direction direction)
Turn in direction: Up, Down, Left, Right.
void UseItem(ItemLocation itemLocation)
Use item (e.g. potions, food).
void UseItemOnLocation(ItemLocation from, Location to)
Use item on location (e.g. rope, shovel, fishing rod).
void UseItemOnBattleList(ItemLocation itemLocation, Creature c)
Use item on creature (e.g. SD rune on target).IMPORTANT
void MoveItem(ItemLocation from, ItemLocation to, ushort count = 1)
Move item between locations.
void FightSettings(FightMode fightMode, FightStance fightStance, SafeMode safeMode)
Set fight settings.
void ContainerClose(byte orderNumber)
Close container.
void OpenParentContainer(byte orderNumber)
Open parent container.
void Logout()
Logout player.
void Ping()
Send ping to server.
Example: Throw SD on target
if (client.Player.Target != 0) {
  Item sd = client.Inventory.GetItem(client.ItemList.Runes.SuddenDeath);
  if (sd != null) {
    Creature target = client.Player.TargetCreature;
    client.Packets.UseItemOnBattleList(sd.ToItemLocation(), target);
    Thread.Sleep(500);
  }
}

Client.ModuleCollection (client.Modules)

Access to bot modules: Cavebot, Healer, ScriptManager, etc.

Available modules

Cavebot Cavebot
Cavebot system
ScriptManager ScriptManager
Script managementIMPORTANT
Healer Healer
Auto-healing
CombobotServer CombobotServer
Combo server
CombobotClient CombobotClient
Combo client
ExperienceCounter ExperienceCounter
XP counter
TextToSpeech TextToSpeech
Speech synthesis
Website Website
Web module

ScriptManager - Global variables

Use client.Modules.ScriptManager.Variables to store data between script runs.

void SetValue(string name, object value)
Save global variable.
object GetValue(string name)
Read global variable. Returns null if it doesn't exist.
void RemoveValue(string name)
Remove global variable.
Example: Remember index
// Read or set 0
object obj = client.Modules.ScriptManager.Variables.GetValue("MyIndex");
int index = obj != null ? (int)obj : 0;

// Use...
index++;

// Save
client.Modules.ScriptManager.Variables.SetValue("MyIndex", index);

Cavebot

bool IsRunning
True if cavebot is enabled.
int CurrentWaypointIndex { get; set; }
Gets or sets the current waypoint index.
IEnumerable<Waypoint> GetWaypoints()
Gets list of all waypoints.
IEnumerable<Target> GetTargets()
Gets list of cavebot targets.
IEnumerable<Loot> GetLoot()
Gets list of all loot entries.
bool GotoLabel(string label)
Jumps to a waypoint with the specified label (case-insensitive). Returns true if found, false otherwise.
void Start()
Starts the cavebot.
void Stop()
Stops the cavebot.
Example: Check if cavebot needs runes
if (client.Modules.Cavebot.IsRunning && client.Player.Target != 0) {
  Creature target = client.Player.TargetCreature;
  if (target != null) {
    foreach (var t in client.Modules.Cavebot.GetTargets()) {
      if (t.Name.ToLower() == target.Name.ToLower()) {
        var setting = t.GetSettingByIndex(t.CurrentSettingIndex);
        if (setting != null && setting.UseThisSetting) {
          ushort runeID = setting.GetRuneID();
          if (runeID != 0) {
            // Target requires runes!
          }
        }
      }
    }
  }
}
Example: Jump to waypoint label
// Jump to waypoint with label "start"
if (client.Player.Mana < 100) {
  if (client.Modules.Cavebot.GotoLabel("start")) {
    client.Window.StatusBar.SetText("Jumped to start waypoint!", 3);
  } else {
    client.Window.StatusBar.SetText("Waypoint 'start' not found!", 3);
  }
}

// Get current waypoint index
int currentIndex = client.Modules.Cavebot.CurrentWaypointIndex;
client.Window.StatusBar.SetText("Current waypoint: " + currentIndex, 2);

// Start/Stop cavebot
if (client.Modules.Cavebot.IsRunning) {
  client.Modules.Cavebot.Stop();
} else {
  client.Modules.Cavebot.Start();
}

BattleList & Creature

BattleList provides quick access to nearby creatures and players.

BattleList - Methods

IEnumerable<Creature> GetCreatures(bool visibleOnly = true, bool sameFloorOnly = true)
Returns all creatures (monsters).
IEnumerable<Creature> GetPlayers(bool visibleOnly = true, bool sameFloorOnly = true)
Returns all players.
IEnumerable<Creature> GetAll(bool visibleOnly = true, bool sameFloorOnly = true)
Returns all (creatures + players).
Creature GetAny(uint id)
Get creature/player by ID.
Creature GetPlayer(uint id)
Get player by ID.
Creature GetPlayer(string name)
Get player by name.

Creature - Properties

uint ID
string Name
Location Location
bool IsVisible
bool IsWalking
byte HealthPercent
bool IsDead
byte Direction

Creature - Methods

void Attack()
Attack this creature.
void Follow()
Follow this creature.
void PrivateMessage(string message)
Send PM to this player.
bool IsReachable()
Whether player can reach it.
bool IsShootable()
Whether it can be shot (no blocking).
bool HasAttackedMeRecently(int ms)
Whether it attacked the player recently (in ms).
Example: Auto-attacker PvP with whitelist
List<string> whiteList = new List<string>() { "Friend1", "Friend2" };

while (true) {
  Thread.Sleep(1000);
  if (!client.Player.Connected || client.Player.Target != 0) continue;
  
  foreach (Creature c in client.BattleList.GetPlayers()) {
    if (whiteList.Contains(c.Name) || client.Player.Name == c.Name) continue;
    if (client.Player.SafeMode != Enums.SafeMode.Disabled) 
      client.Player.SafeMode = Enums.SafeMode.Disabled;
    c.Attack();
    break;
  }
}

Map & Tile

Access to visible tiles and map queries.

Map - Methods

Map.TileCollection GetTilesOnScreen()
Returns all visible tiles.MOST IMPORTANT
Map.Tile GetTile(Location worldLocation)
Gets tile by world coordinates.
IEnumerable<Map.Tile> GetAdjacentTiles(Location loc)
Gets 8 adjacent tiles.
Map.TileCollection GetTileCollectionWithObjects(IEnumerable<ushort> ids)
Filters tiles by object IDs.
Map.TileCollection GetTilesWithObject(ushort id)
Gets tiles containing object with ID.
Map.TileCollection GetTilesWithObjects(ushort[] ids)
Gets tiles containing any of the objects.

Tile - Properties

Location WorldLocation
Tile position in world

Tile - Methods

IEnumerable<Map.TileObject> GetObjects()
Returns all objects on tile.
Map.TileObject GetTopUseItem(bool considerCreatures)
Gets top object to use (e.g. doors, switch).
Map.TileObject GetTopMoveItem()
Gets top item to move (loot).IMPORTANT
bool ContainsObject(ushort id)
Whether tile contains object with ID.
bool ContainsCreature()
Whether there is a creature on tile.
bool IsWalkable(bool considerPathBlockingItems = true)
Whether tile is walkable.

TileCollection - Methods

IEnumerable<Map.Tile> GetTiles()
Enumerate saved tiles.
bool IsEmpty()
Whether collection is empty.
Map.Tile GetPlayerTile()
Gets tile where player stands.
Map.Tile GetTile(ushort id = 0, uint count = 0)
Gets tile containing item with ID and count.
Map.Tile GetClosestNearbyTile(Map.Tile fromTile, Map.Tile toTile, byte range = 1)
Gets closest tile in range.
IEnumerable<Map.Tile> GetTilesWithObjects(IEnumerable<ushort> ids)
Gets tiles with specified objects.

Inventory, Container & Item

Access to player containers and items.

Inventory - Methods

IEnumerable<Container> GetContainers()
Enumerate open containers.
Container GetContainer(byte orderNumber)
Get container by order number (0-15).
Container GetFirstClosedContainer()
Get first closed container.
Item GetItem(ushort id)
Find first item with ID in inventory/containers.
Item GetItemInSlot(Enums.EquipmentSlots slot)
Get item from slot (Head, Armor, LeftHand, RightHand, etc.).
ItemLocation GetFirstEmptySlot()
Find first empty slot in containers.
ItemLocation GetFirstSuitableSlot(Item item)
Find best slot for item (stackable + existing).
void GroupItems()
Automatically groups stackable items in containers.

Container - Properties & Methods

byte OrderNumber
Order number (0-15)
bool IsOpen
Whether container is open
bool IsFull
Whether container is full
bool HasParent
Whether it has parent (nested BP)
Item GetItem(ushort id)
Find item in this container.
IEnumerable<Item> GetItems()
Get all items.
ItemLocation GetFirstEmptySlot()
First empty slot.
ItemLocation GetBestSlot(ItemLocation src)
Best slot for item (stack or empty).
void OpenParentContainer()
Open parent of this container.
void Close()
Close container.

Item - Methods

void Move(ItemLocation target, ushort count = 1)
Move item to location.IMPORTANT
void Use()
Use item (food, potion, etc.).
void UseOnLocation(Location world)
Use on location (rope, shovel, fishing rod).
bool WaitForInteraction(int timeoutMs)
Waits until item is used/moved. Returns true if success.
bool HasFlag(Enums.ObjectPropertiesFlags flags)
Check if item has flag (IsContainer, IsStackable, etc.).
Container TryOpen()
Try to open container. Returns Container or null.
void OpenInNewWindow()
Open nested container in new window.
ItemLocation ToItemLocation()
Convert to ItemLocation (used in Packets).
Example: Move all GP to first BP
ushort goldId = 3031;
var containers = client.Inventory.GetContainers().ToList();
if (containers.Count == 0) return;

var mainBp = containers[0];
var tiles = client.Map.GetTilesOnScreen();

foreach (var tile in tiles.GetTiles()) {
  if (!tile.ContainsObject(goldId)) continue;
  var gold = tile.GetTopMoveItem();
  if (gold == null) continue;
  
  var slot = mainBp.GetBestSlot(gold.ToItemLocation());
  if (slot == null) break; // BP pełny
  
  gold.Move(slot);
  gold.WaitForInteraction(500);
  Thread.Sleep(100);
}

ItemList (client.ItemList)

Catalog of common item IDs grouped by categories. You can change them in scripts!

Categories

Food (client.ItemList.Food)

ushort Fish
ushort Meat
ushort Ham
ushort DragonHam
ushort Bread
ushort Cheese
ushort BrownMushroom
ushort WhiteMushroom
List<ushort> All

Tools (client.ItemList.Tools)

ushort Rope
ushort Shovel
ushort Pick
ushort Machete
ushort FishingRod
List<ushort> All

Runes (client.ItemList.Runes)

ushort Blank
ushort SuddenDeath
ushort UltimateHealing
ushort GreatFireball
ushort Explosion
ushort HeavyMagicMissile
ushort Vial
ushort ManaPotion
ushort HealthPotion
List<ushort> All

Rings (client.ItemList.Rings)

ushort Life
ushort Energy
ushort Might
ushort Dwarven
ushort Stealth
List<ushort> All

Amulets (client.ItemList.Amulets)

ushort Elven
ushort Platinum
ushort Stoneskin
List<ushort> All

Valuables (client.ItemList.Valuables)

ushort GoldCoin
ushort PlatinumCoin
ushort SmallAmethyst
List<ushort> All
Example: Change IDs for different server
public static void Main(Client client) {
  // Change IDs for your server
  client.ItemList.Food.Ham = 3582;
  client.ItemList.Food.Fish = 3578;
  client.ItemList.Tools.FishingRod = 3483;
  client.ItemList.Runes.UltimateHealing = 3160;
  client.ItemList.Runes.Blank = 3147;
  client.ItemList.Rings.Life = 3052;
  
  // Now you can use
  Item rod = client.Inventory.GetItem(client.ItemList.Tools.FishingRod);
}

Location

3D position in world (X, Y, Z) with helpers.

Constructors

Location() // 0,0,0
Location(ushort x, ushort y, byte z)

Properties

ushort X
ushort Y
byte Z

Methods

bool IsOnScreen(Location other)
Whether other location is on screen.
Location Offset(int x = 0, int y = 0, int z = 0)
Returns new location offset by amount.IMPORTANT
double DistanceTo(Location other)
Returns distance to other location.
bool IsAdjacentTo(Location other)
Whether locations are adjacent.
byte[] ToByteArray()
Converts to byte array (X, Y, Z).
ItemLocation ToItemLocation()
Converts to ItemLocation (used in Packets).
Usage example
Location playerLoc = client.Player.Location;
Location targetLoc = new Location(100, 200, 7);

// Check distance
double dist = playerLoc.DistanceTo(targetLoc);
if (dist > 10) {
  client.Player.GoTo = targetLoc;
}

// Use tool on tile next to player (north)
Location north = playerLoc.Offset(0, -1, 0);
Item rope = client.Inventory.GetItem(client.ItemList.Tools.Rope);
if (rope != null) {
  rope.UseOnLocation(north);
}

Window & StatusBar

Access to game window and StatusBar.

Window - Properties

StatusBar StatusBar
Access to StatusBar
GameWindow GameWindow
Access to GameWindow (messages)

Window - Methods

string GetCurrentDialogTitle()
Get title of currently open dialog. Returns empty string if no dialog.
Size GetWindowSize()
Get game window size (width, height).

StatusBar - Methods

void SetText(string text, int seconds)
Display text on StatusBar for X seconds.
string GetText()
Get current text from StatusBar.

GameWindow - Methods

IEnumerable<Message> GetMessages()
Get all visible messages from game window. Returns cached messages.

Message - Properties

string Text
Message text
string Sender
Sender name (for Say/Whisper/Yell/PM)
Location Location
Message location (if applicable)
Message.Types Type
Message type (Say, Whisper, Yell, PM, etc.)
bool IsVisible
Whether message is visible
int Time
Time remaining (in milliseconds)
Example: Display info on StatusBar
client.Window.StatusBar.SetText("Fishing started!", 5);
Thread.Sleep(5000);
client.Window.StatusBar.SetText("Collecting loot...", 3);
Example: Check game messages
// Check for GM messages
foreach (var msg in client.Window.GameWindow.GetMessages()) {
  if (msg.Type == GameWindow.Message.Types.WhiteMessage && 
      msg.Text.ToLower().Contains("gamemaster")) {
    // GM message detected!
    client.Window.StatusBar.SetText("GM message: " + msg.Text, 5);
    break;
  }
}

// Check for PMs
foreach (var msg in client.Window.GameWindow.GetMessages()) {
  if (msg.Type == GameWindow.Message.Types.PrivateMessage) {
    client.Window.StatusBar.SetText("PM from " + msg.Sender + ": " + msg.Text, 5);
    break;
  }
}

// Get window size
var windowSize = client.Window.GetWindowSize();
client.Window.StatusBar.SetText("Window: " + windowSize.Width + "x" + windowSize.Height, 3);

PathFinder & LocalPathFinder

Pathfinding systems. Usually used internally, but available for scripts.

PathFinder (Global)

IEnumerable<PathFinder.Node> GetPath(Location from, Location to)
Returns path between two locations (uses minimap).

LocalPathFinder (Local - visible tiles)

IEnumerable<PathFinder.Node> GetPath(Map.TileCollection tiles, Location from, Location to)
Returns path within visible tiles.

Tip: Usually easier to set client.Player.GoTo = targetLocation than manually using PathFinder.

MiniMap

Access to automap. Advanced usage for large maps.

Methods

MiniMap.Chunk GetChunk(Location loc)
Gets minimap chunk for location.
MiniMap.Chunk GetMergedChunk(Location from, Location to)
Merges chunks into rectangle.

Note: MiniMap is mainly used by PathFinder. Most scripts don't need direct access.

AreaEffects

Predefined AoE patterns for spells and runes.

Available effects

AreaEffect Explosion
AreaEffect GreatFireball
AreaEffect EnergyWave
AreaEffect IceWave
AreaEffect AvalonWave

AreaEffect - Methods

IEnumerable<byte[]> GetArea()
Returns AoE pattern as offset arrays.
EffectType Type
Effect type

Usage: Mainly for Cavebot and advanced scripts checking AoE coverage.

Enums & Constants

Common enumerators used in API.

Enums.FightStance

Offensive, Balanced, Defensive

Enums.FightMode

Attack, Chase, Stand

Enums.SafeMode

Enabled, Disabled

Enums.Direction

Up, Down, Left, Right

Enums.EquipmentSlots

Head, Necklace, Backpack, Armor, RightHand, LeftHand, Legs, Feet, Ring, Ammo

Enums.ObjectPropertiesFlags

IsContainer, IsStackable, IsFluidContainer, IsUseable, IsRune, IsWriteable, IsBlocking, IsImmovable, BlocksProjectile, IsPickupable, IsHangable, IsRotateable, IsReadable, HasLight, HasHeight
Usage example
// Set fight settings
client.Packets.FightSettings(
  Enums.FightMode.Attack, 
  Enums.FightStance.Offensive, 
  Enums.SafeMode.Disabled
);

// Check if item is container
if (item.HasFlag(Enums.ObjectPropertiesFlags.IsContainer)) {
  var container = item.TryOpen();
}

// Turn south
client.Packets.Turn(Enums.Direction.Down);

Full script examples

1. Runemaker - UH at home
using System;
using System.Linq;
using System.Threading;
using FogBot.Objects;

public class Test {
  public static void Main(Client client) {
    string spellName = "adura vita";
    ushort spellMana = 100;
    Random rand = new Random();
    
    while (true) {
      Thread.Sleep(rand.Next(10000, 15000));
      
      if (client.Player.IsWalking) continue;
      
      if (client.Player.Mana >= spellMana && client.Player.ManaPercent >= 80) {
        client.Player.MakeRune(spellName, spellMana, true, 
                               (ushort)(client.Player.ManaMax * 0.3));
        Thread.Sleep(rand.Next(2000, 5000));
      }
      
      // Eat food
      foreach (ushort id in client.ItemList.Food.All) {
        Item food = client.Inventory.GetItem(id);
        if (food != null) {
          food.Use();
          Thread.Sleep(rand.Next(2000, 6000));
          break;
        }
      }
    }
  }
}
2. Loot Grabber - Collecting specific items
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using FogBot.Objects;

public class ExternalScript {
  public static void Main(Client client) {
    // List of items to collect (ID)
    ushort[] lootIDs = new ushort[] { 3031, 2689, 3007 }; // gold, bread, bag
    
    // Open main BP (first)
    var containers = client.Inventory.GetContainers().ToList();
    if (containers.Count == 0) {
      client.Window.StatusBar.SetText("Open a backpack first!", 3);
      return;
    }
    var mainBP = containers[0];
    
    Random rand = new Random();
    while (true) {
      Thread.Sleep(rand.Next(300, 600));
      if (!client.Player.Connected) continue;
      if (client.Player.Cap <= 10) break; // End when no cap
      
      var tiles = client.Map.GetTilesOnScreen();
      bool foundLoot = false;
      
      foreach (var tile in tiles.GetTiles()) {
        bool hasLoot = false;
        foreach (ushort lootID in lootIDs) {
          if (tile.ContainsObject(lootID)) {
            hasLoot = true;
            break;
          }
        }
        if (!hasLoot) continue;
        
        var item = tile.GetTopMoveItem();
        if (item == null) continue;
        
        var slot = mainBP.GetBestSlot(item.ToItemLocation());
        if (slot == null) break; // BP full
        
        item.Move(slot);
        item.WaitForInteraction(500);
        foundLoot = true;
        break;
      }
      
      if (!foundLoot) break; // No more loot
    }
    
    client.Window.StatusBar.SetText("Loot grabber finished!", 3);
  }
}
3. Auto-walker with fisher
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using FogBot.Objects;

public class DepoFish {
  public static void Main(Client client) {
    const ushort ROD = 3483;
    const int MIN_CAP = 50;
    ushort[] waterIDs = new ushort[] { 4597, 4598, 4599, 4600, 4601, 4602 };
    
    // Waypoint path
    var path = new List<Location>() {
      new Location(100, 100, 7),
      new Location(105, 100, 7),
      new Location(105, 105, 7),
      new Location(110, 105, 7)
    };
    
    int i = 0;
    client.Player.GoTo = path[i];
    Random rand = new Random();
    
    while (true) {
      Thread.Sleep(300);
      if (!client.Player.Connected) continue;
      
      var me = client.Player.Location;
      var tgt = path[i];
      
      // Check if we reached waypoint
      if (me.IsOnScreen(tgt) && me.DistanceTo(tgt) <= 1) {
        i = Math.Min(i + 1, path.Count - 1);
        client.Player.GoTo = path[i];
      }
      
      // If low cap - continue without fishing
      if (client.Player.Cap <= MIN_CAP) continue;
      
      // Fish
      var rod = client.Inventory.GetItem(ROD);
      if (rod == null) continue;
      
      var waters = client.Map.GetTilesWithObjects(waterIDs).GetTiles().ToList();
      foreach (var w in waters) {
        if (!me.IsOnScreen(w.WorldLocation)) continue;
        rod.UseOnLocation(w.WorldLocation);
        Thread.Sleep(rand.Next(800, 1500));
        break;
      }
    }
  }
}
4. Combobot - Use SD on target for all clients
using FogBot.Objects;
using System;

public class ComboNow {
  public static void Main(Client client) {
    var id = client.Player.Target;
    if (id == 0) return;
    
    // Broadcast to all clients through Combobot server
    client.Modules.CombobotServer.Combo(id);
  }
}
5. Ring Switcher - Automatic life ring change on low HP
using System;
using System.Threading;
using FogBot.Objects;

public class ExternalScript {
  public static void Main(Client client) {
    ushort lifeRingID = client.ItemList.Rings.Life;
    int switchHP = 300; // Change when HP < 300
    
    Random rand = new Random();
    while (true) {
      Thread.Sleep(rand.Next(500, 1000));
      if (!client.Player.Connected) continue;
      
      if (client.Player.Health < switchHP) {
        // Check if we already have ring
        var currentRing = client.Inventory.GetItemInSlot(Enums.EquipmentSlots.Ring);
        if (currentRing != null && currentRing.ID == lifeRingID) continue;
        
        // Find life ring in BP
        var lifeRing = client.Inventory.GetItem(lifeRingID);
        if (lifeRing == null) continue;
        
        // Move to ring slot
        lifeRing.Move(new Location(0, 0, 9).ToItemLocation()); // 9 = Ring slot
        lifeRing.WaitForInteraction(800);
        
        client.Window.StatusBar.SetText("Life ring equipped!", 2);
      }
    }
  }
}
6. Waypoint Label Jumper - Jump to labeled waypoints based on conditions
using System;
using System.Threading;
using FogBot.Objects;

public class ExternalScript {
  public static void Main(Client client) {
    Random rand = new Random();
    while (true) {
      Thread.Sleep(rand.Next(500, 1000));
      if (!client.Player.Connected) continue;
      
      // If low mana, jump to start waypoint
      if (client.Player.Mana < 100) {
        if (client.Modules.Cavebot.GotoLabel("start")) {
          client.Window.StatusBar.SetText("Low mana - jumped to start!", 3);
        }
        continue;
      }
      
      // If low health, jump to safe waypoint
      if (client.Player.HealthPercent < 30) {
        if (client.Modules.Cavebot.GotoLabel("safe")) {
          client.Window.StatusBar.SetText("Low HP - jumped to safe spot!", 3);
        }
        continue;
      }
      
      // If low cap, jump to depot waypoint
      if (client.Player.Cap < 50) {
        if (client.Modules.Cavebot.GotoLabel("depot")) {
          client.Window.StatusBar.SetText("Low cap - going to depot!", 3);
        }
        continue;
      }
    }
  }
}