Skip to content

GGotha/tibiaeye

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

2 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿค– TibiaEye

A full-featured bot for the MMORPG Tibia, built in Python using computer vision, a hardware-level anti-detection layer, and real-time telemetry. Originally a study project to deeply learn systems programming, computer vision, and game automation.

Dashboard


โš ๏ธ Disclaimer โ€” Read Before Using

This bot was used in production on a global server character. The character was banned after ~30 consecutive hours of hunting.

Even with hardware-level anti-detection (Arduino Leonardo as a USB HID device + capture card), BattleEye can detect non-human behavioral patterns. Running a bot for 30 straight hours is obviously not human. My recommendation: if you use this, use it in short, controlled sessions and add stamina-based breaks.

๐Ÿ”ด Use at your own risk. Botting violates Tibia's Terms of Service.


๐ŸŽฏ What I Learned

This project started as a way to learn things I'd been curious about for a long time โ€” things you can't just read about, you have to build.

๐Ÿ‘๏ธ Computer Vision

Technique What I learned
Template Matching Sliding window search comparing saved templates pixel-by-pixel against a screenshot. Grayscale images significantly speed this up โ€” less color data = fewer comparisons.
Image Hashing (FarmHash64) O(1) creature lookup by hashing the name strip from the BattleList. Way faster than template matching for known creatures.
OCR via pixel analysis Reading numbers (HP, level, staminaโ€ฆ) by matching digit templates against regions of the screen.
HSV color filtering Detecting HP/Mana bar percentages by analyzing specific pixel colors in known positions.
Grayscale optimization Template matching compares pixel by pixel โ€” reducing 3 channels to 1 gives ~3x speedup.

โšก Performance Engineering

  • Numba @njit โ€” JIT-compiled Python to machine code for hot paths (BFS pathfinding, bar detection, slot counting). Achieved 2โ€“10x speedups on bottleneck functions.
  • Adaptive tick rate โ€” 80ms during combat, 100ms normally, 150ms idle, 500ms paused.
  • Middleware frequencies โ€” not every system runs every tick. HP every tick, creatures every 2 ticks, radar every 3, skills every 10.

๐Ÿ—บ๏ธ Pathfinding

  • A* for high-level navigation between waypoints (via tcod).
  • BFS flood fill (@njit) for walkable grid analysis inside the game window.

Key concepts I internalized:

  • G cost = distance from start
  • H cost (heuristic) = estimated distance to goal
  • F cost = G + H โ€” what A* minimizes

๐Ÿ”ง Systems Engineering

  • Cross-platform capture pipeline (macOS native vs. Windows capture card โ€” different pixel pipelines, same interface)
  • Hardware abstraction layer โ€” transparent switching between pyautogui, Arduino HID, and capture card with zero changes to game logic
  • Module reload tricks for runtime platform switching in tests
  • How __init__.py works as a facade: controls exports and runs setup code on import

โš™๏ธ The Hard Part: Performance vs. Effectiveness

The goal was a lightweight bot โ€” something that could run in the background without hammering the machine. That turned out to be one of the hardest problems to get right.

Computer vision is inherently heavy. Template matching, BFS pathfinding, OCR over multiple screen regions โ€” all of this runs every tick, multiple times per second. My CPU and memory usage were way higher than I wanted, and the tricky part was that every optimization risked breaking detection accuracy. Lower the confidence threshold to run faster โ†’ more false positives. Skip a frame to save cycles โ†’ miss a creature. It required a lot of careful tuning to find a balance that was both fast enough and reliable enough.

Things I tried that didn't work as expected:

  • Rewriting in Rust โ€” I spent some time exploring a Rust rewrite hoping for better memory management and lower overhead. The result was actually worse โ€” higher CPU and memory than the Python version. I didn't invest much time here (rewriting the entire detection pipeline would've taken months), and I may have made mistakes due to inexperience with Rust. But at least for my tests, Python + Numba outperformed my Rust attempt.

  • GPU parallelization โ€” I explored offloading some of the CPU-bound work to the GPU to parallelize the heavier detection functions. I didn't go deep enough to make it really work โ€” I managed some small gains but nothing meaningful for the overall loop. This is probably worth revisiting properly, but it would require a more fundamental rethink of the pipeline.

What ended up actually helping: middleware frequency tuning (not every module runs every tick), Numba JIT on the hottest paths, grayscale everywhere, and caching results that don't change frame-to-frame. Small wins that added up.


โœจ Features

๐Ÿ–ฅ๏ธ GUI Tabs

Tab Description
Dashboard Real-time bot health โ€” ticks, creatures, HP/MP, active pipeline modules, battle list, recent events
Settings Start/Pause/Stop controls, tick rate, window target, module toggles (healing, cavebot, loot, overlay), server save config
Cavebot Load/loop routes, waypoint list, refill thresholds, deposit options
Healing Configure HP/Mana thresholds for potions and spells
Targeting Whitelist or blacklist mode, creature list
Spell Attack AoE vs single-target spell groups, mana reserve protection
Hardware Choose input mode (Software / Capture Card / Arduino / Full Hardware), serial port detection
Recorder Record waypoints live while walking โ€” Walk, Ladder, Rope, Shovel, Stairs โ€” exports to JSON route
Status Live character stats: CPU/RAM, HP/MP bars, capacity, food, speed, stamina, coordinates, creatures in range
Diagnostics Subsystem health dots, Arduino/Telemetry connection status, stuck/reconnect/safe-mode flags, recent errors

๐ŸŽฎ Bot Automation

Feature Description
Cavebot Route-based navigation with looping, depot return, holes/ropes/stairs/ladders
Auto-healing Observer pattern โ€” reacts to HP/Mana drops. Spells + potions with configurable thresholds
Targeting Whitelist or blacklist. Attacks nearest creature in range
Spell attack Configurable AoE and single-target spell groups with mana reserve
Loot system Opens corpses, collects selected items
Auto-refill Goes to NPC when potions run low, buys stock, deposits gold/loot, returns to hunt
Stuck detection Detects movement freeze and triggers audio alert
Anti-trap Detects when surrounded and attempts escape
Server save Detects save time, gracefully disconnects, reconnects after
Auto-reconnect Logs back in automatically after disconnection
Food auto-eat Keeps character fed

๐Ÿ‘๏ธ Visual Detection Pipeline

Module What it detects
BattleList Creature names โ€” FarmHash64 O(1) lookup + template matching fallback for hash collisions
GameWindow Creature positions, HP bars, walkable tiles
StatusBar HP and Mana percentages (pixel color analysis)
Skills Panel Level, experience, HP, mana, capacity, speed, food, stamina (OCR)
Radar Current coordinate (X, Y, Z) from minimap
Inventory Container/backpack slot detection
ActionBar Cooldown state
Connection Login screen and character selection detection

๐Ÿ”ฉ Hardware Anti-Detection

The GUI exposes four input modes:

Mode Description
Software pyautogui + mss. Works on macOS/Linux. Detectable on Windows.
Capture Card pyautogui input + capture card for screenshots. Bypasses Tibia's screenshot block on Windows.
Arduino HID + mss Arduino Leonardo acts as a real USB keyboard/mouse. Tibia never sees Python โ€” it sees a HID device.
Full Hardware Arduino HID + capture card. Completely external to the PC.

The Arduino Leonardo is flashed with custom HID firmware (firmware/) and communicates over serial at 115200 baud โ€” one text command per line.

Despite all of this โ€” my character got banned. BattleEye doesn't need to see your keyboard driver. It watches behavior. No human hunts for 30 hours straight.


๐Ÿ“Š Telemetry & Real-time Dashboard

The bot streams data to a companion platform โ€” tibiaeye-monorepo โ€” via HTTP + WebSocket:

  • Kill events, loot, XP โ€” batched HTTP
  • Live character position โ€” WebSocket (every tick)
  • Livemap โ€” real-time map of where your character is walking
  • XP/h charts, kill counts, session history, browser notifications (death, low HP, stuck)

๐Ÿ—‚๏ธ Architecture

src/
โ”œโ”€โ”€ repositories/     # Visual data extraction (pure functions + thin facade)
โ”‚   โ”œโ”€โ”€ battlelist/   # FarmHash64 + template matching
โ”‚   โ”œโ”€โ”€ gamewindow/   # BFS pathfinding, creature bar detection
โ”‚   โ”œโ”€โ”€ statusbar/    # HP/Mana % from pixel colors
โ”‚   โ”œโ”€โ”€ skills/       # OCR digit recognition
โ”‚   โ”œโ”€โ”€ radar/        # Minimap coordinate extraction
โ”‚   โ””โ”€โ”€ inventory/    # Container slot detection
โ”œโ”€โ”€ gameplay/         # Bot logic (functional pipeline)
โ”‚   โ”œโ”€โ”€ gameloop.py   # Middleware pipeline (Context โ†’ Context)
โ”‚   โ”œโ”€โ”€ cavebot/      # Navigation + combat decisions
โ”‚   โ””โ”€โ”€ core/tasks/   # Stateful task system (the only OOP layer)
โ”œโ”€โ”€ healing/          # Auto-heal observers
โ”œโ”€โ”€ hardware/         # Abstraction: software / Arduino / capture card
โ”œโ”€โ”€ telemetry/        # HTTP + WebSocket data streaming
โ”œโ”€โ”€ gui/              # CustomTkinter interface
โ””โ”€โ”€ wiki/             # Static game data (creatures, spells, cities)

The game loop is a pure functional middleware pipeline โ€” each step is Context โ†’ Context, inspired by PyTibia:

Screenshot โ†’ StatusBar โ†’ BattleList โ†’ GameWindow โ†’ Radar โ†’ Skills
                                                            โ†“
                                                    handle_cavebot()
                                                            โ†“
                                                    orchestrator.do()
                                                            โ†“
                                                    Healing observers

๐Ÿงช E2E Visual Testing Framework

As the detection modules grew โ€” BattleList, GameWindow, StatusBar, Skills panel, Radar, ActionBar, Pathfinding โ€” manually verifying each one after every change became painful and slow. I'd tweak the HP bar detection, run the bot, stare at the screen, and still not be sure if the skills OCR had regressed.

The real challenge wasn't testing a single module in isolation. It was the combinatorial explosion of scenarios that all needed to work correctly at the same time:

  • BattleList with 1 monster, 2, 4, 9 โ€” and with zero monsters
  • BattleList while actively attacking vs. not attacking
  • GameWindow with a monster visible and a clear HP bar
  • GameWindow with multiple monsters overlapping, or a monster at low HP
  • GameWindow while running away from a monster vs. engaging it
  • StatusBar at 100% HP, at 30% (healing threshold), at critical levels
  • Skills panel with different stamina values, different capacity amounts
  • Radar identifying the correct floor and coordinate
  • The full gameplay decision: given this exact screenshot, does the bot choose to attack, walk, or refill?

Every time I changed something in creature detection, I had to mentally replay all these scenarios and manually confirm nothing broke. It was slow, error-prone, and I kept catching regressions too late.

So I built a custom E2E framework (e2e/) that runs the full detection pipeline against a library of real game screenshots captured on both macOS and Windows.

The problem it solved: instead of launching the bot and eyeballing results, I could run a single command and immediately know which modules were working, which had regressed, and exactly what each one was returning โ€” with visual annotated output images to inspect.

How it works:

  1. Each screenshot has a companion .expected.json describing what the bot should detect in that scene (creature count, names, HP range, skills values, pathfinding decision, etc.)
  2. The runner imports directly from src/repositories/ โ€” zero reimplementation, tests the real code
  3. Results are compared against expectations and any mismatch is flagged as a regression
  4. Annotated images are generated with overlays showing detected bars, creature bounding boxes, BFS walkable grid, path to target, and skills values โ€” making it visual and fast to diagnose
# Run all scenarios
python e2e/main.py

# Filter by OS, image, or module
python e2e/main.py --os macos
python e2e/main.py --image rotworm
python e2e/main.py --module battlelist

# Visual output with annotated overlays
python e2e/main.py --image rotworm --side-by-side

# Update expected values after an intentional change
python e2e/main.py --update-expected

# Capture a new screenshot into the suite
python e2e/capture.py --os macos --name new_scenario

What each module validates:

Module Checks
battlelist Exact creature count, names (set equality), attack target
gamewindow Creature count, false positives, HP bar noise, attack state
statusbar HP and Mana within expected range
skills Exact values โ€” level, XP, HP, mana, capacity, speed, stamina
radar Coordinate found
pathfinding Walkable tile count, path exists, path length
gameplay Correct decision (attack/walk/refill), correct target, task sequence

Screenshots are split by OS (macos/, windows/) because the capture method changes pixel values โ€” macOS uses the native screen capture API, Windows goes through a capture card.

The framework works well for this use case. There's definitely room to improve it โ€” better diff output, coverage tracking per creature, parallel execution โ€” but it already saved a lot of manual testing time and caught several regressions during development.


๐Ÿš€ Setup

git clone https://github.com/GGotha/tibiaeye.git
cd tibiaeye

python -m venv venv
source venv/bin/activate       # macOS/Linux
# venv\Scripts\activate        # Windows

pip install -r requirements.txt

python gui.py                  # GUI mode
python main.py --help          # CLI mode

Arduino setup

  1. Flash firmware/tibiaeye_hid/tibiaeye_hid.ino to an Arduino Leonardo via Arduino IDE.
  2. Connect via USB.
  3. In the GUI โ†’ Hardware tab, select the mode and serial port.

โธ๏ธ Project Status

I genuinely enjoyed building this โ€” the computer vision pipeline, hardware abstraction, pathfinding, Numba JIT, a real visual testing framework. There's still a lot I wanted to explore: stamina-aware character rotation, smarter anti-detection heuristics, deeper pathfinding algorithms.

But other priorities in life got in the way and I had to step back. I intend to return to this project and the broader study of bot engineering and algorithmic performance in the future.


๐Ÿ’ก Planned Features (not implemented)

  • Stamina-based auto-logout โ€” detect when stamina drops below X โ†’ walk to depot โ†’ logout โ†’ switch to alt character. This would've avoided the ban.
  • Death detection + recovery flow
  • Player detection (log out if another player enters the hunt area)
  • Combo spell sequencing

๐Ÿ› ๏ธ Tech Stack

Layer Technology
Computer vision OpenCV, NumPy
Performance Numba JIT (@njit)
Hashing FarmHash64 (pyfarmhash)
Pathfinding tcod (A*), custom BFS (Numba)
GUI CustomTkinter
Screen capture mss (macOS/Linux), OpenCV capture card (Windows)
Hardware Arduino Leonardo, pyserial
Telemetry requests, websocket-client
Testing pytest, custom E2E visual framework

๐Ÿ”— Related Projects

Project Description
tibiaeye-monorepo Node.js monorepo โ€” NestJS API + React dashboard + livemap
PyTibia The original open-source bot this project was inspired by

๐Ÿ“– References


๐Ÿ–ผ๏ธ Screenshots


Settings

Live Status

Cavebot & Routes

Route Recorder

Diagnostics

Hardware Modes

Built for learning. Used in production. Got banned.

About

๐Ÿค– Computer vision bot for Tibia โ€” Python, OpenCV, Numba JIT, A* pathfinding, Arduino HID anti-detection

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors