A passion project for Graphwar — turn what you see on the battlefield into a paste-ready mathematical function.
GraphBot watches the game field and builds Graphwar-compatible formulas. The recommended workflow is the local web UI (approximator_server.py) — Click mode (default) and Draw mode with four approximation methods. GraphBot.py still offers click mode (OpenCV overlay) and an automatic mode prototype that is not production-ready yet.
Project status: web UI (click + draw) = ready to use ·
GraphBot.pyauto mode = work in progress (see Auto mode)
How GraphBot touches Graphwar: GraphBot is an external helper — it does not modify game files, inject into the game process, read game memory, or automate gameplay. The only direct interaction with the Graphwar window is moving it to a fixed corner so screen capture aligns with the configured field region. Everything else is: screenshot → math → copy a formula to your clipboard. You paste it into Graphwar yourself.
graphbot_kroshechka_github.mp4
- What is Graphwar?
- Getting started
- Web UI (recommended)
- How GraphBot works
- Click mode
- Draw mode
- Auto mode (work in progress)
- Project layout
- Roadmap
- More to come
- Feedback & issues
- License
Graphwar is an artillery game on a Cartesian plane. You type a function; the game fires along that curve (with a vertical shift so the shot passes through your soldier). Hit enemies, avoid teammates and black obstacle circles.
GraphBot does not replace the game — it helps you derive functions faster. See GAME_RULES.md for full Graphwar rules and syntax.
Field limits (approx.): x ∈ [-25, 25], y ∈ [-15, 15].
| Requirement | Notes |
|---|---|
| Windows | Screen capture and window APIs are Win32-specific (pywin32). |
| Python 3.10+ | Tested with dependencies in requirements.txt. |
| Graphwar | Window title must be Graphwar. Keep it visible while the bot runs. |
git clone https://github.com/KroSheChKa/GraphBot.git
cd GraphBot
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txtLegacy / alternative entry point — click mode on the live game window with F-keys:
python GraphBot.py- Choose
1(click mode) or0(auto — experimental). - Press F1 to start, F2 to quit.
- In click mode: F3 start recording clicks, F4 finish.
See Click mode → GraphBot.py for how formula building differs from the web UI.
Tip: If detection looks wrong, tune capture with python tools/preview_capture.py and calibration tools under tools/.
The main tool is a local p5.js app served by Python:
python tools/approximator_server.pyOpen http://127.0.0.1:8765/ in your browser.
| Mode | What it does |
|---|---|
| 1. Click mode (default) | Place waypoints on the canvas; get a piecewise direct_line formula |
| 2. Draw mode | Sketch a curve, resample to a dataset, approximate with 4 methods |
| Action | Control |
|---|---|
| Capture Graphwar field as background | Захват поля (Graphwar must be running; window moved to corner for alignment) |
| Clear current path / stroke | C (background screenshot stays) |
| Copy formula | Копировать y |
| Reset sliders & canvas state | Сброс |
After «Захват поля»: any previous clicks or drawn curve are cleared automatically — you start fresh on the new screenshot.
| Action | Control |
|---|---|
| Place active soldier | 1st click — purple marker A |
| Place targets | 2nd, 3rd… clicks — orange markers 2, 3… |
| Undo last click | Right-click, Backspace, or Отменить последний клик |
Formula output: expression only, no y= prefix — paste into Graphwar as-is.
Switch to 2. Draw mode in the side panel, then pick an approximation method:
| Method | Idea |
|---|---|
| 2.1 Linear (segments) | Exact piecewise lines through the dataset |
| 2.2 Sigmoid network | Sum of shifted sigmoids (universal approximation) |
| 2.3 Taylor (polynomial) | Polynomial features ± MLP (beta) |
| 2.4 Fourier (harmonics) | Harmonic features ± MLP |
| Action | Control |
|---|---|
| Draw target curve | Click and drag on the canvas |
| Adjust dataset density | Шаг датасета slider |
| Retrain after parameter change | Переобучить |
Formula output: y=... (Graphwar syntax). Compare MSE in the status line before copying.
flowchart LR
GW[Graphwar window] --> CAP[Screen capture]
CAP --> DET[Player / obstacle detection]
DET --> PATH[Waypoints or drawn curve]
PATH --> FMT[Graphwar formula]
FMT --> CLIP[Clipboard]
- Capture — crop the game field via Win32 window rect + margins from
config/capture_config.json. - Detect — find allies, enemies, active player (red glow), and black obstacles (OpenCV + Hough) on the screenshot only.
- Plan — build waypoints (click mode) or freehand draw + resample (draw mode). (Auto planners in
GraphBot.py— A, polynomial search, symbolic GA — are experimental.)* - Encode — convert segments or approximations into Graphwar syntax and copy to clipboard.
GraphBot stays outside Graphwar:
| GraphBot does | GraphBot does not |
|---|---|
| Take a screenshot of the visible game field | Edit, patch, or replace any game files |
| Move the Graphwar window to a known screen position for consistent capture | Inject DLLs, hooks, or code into the game process |
| Run OpenCV on the captured image | Send keystrokes/clicks into the game to play for you |
| Copy a formula to the clipboard | Read game memory or network traffic |
There is no autopilot that fires shots or submits functions. You still aim by typing (or pasting) the formula in Graphwar’s own UI — GraphBot only helps you derive that formula faster.
The piecewise building block is shared between click mode and draw mode (linear segments):
def direct_line(p1, p2):
x1, y1 = fmt_game(p1[0]), fmt_game(p1[1])
x2, y2 = fmt_game(p2[0]), fmt_game(p2[1])
dx = x2 - x1
if abs(dx) < 1e-12:
dx = fmt_game(vertical_eps(y1, y2)) if y1 != y2 else VERTICAL_MIN_EPS
x2 = fmt_game(x1 + dx)
dist = fmt_game(-((y1 - y2) / 2) / dx)
return f"{dist}*(abs(x - {x1}) - abs(x - {x2}))"Each segment is a V-shaped absolute-value line between two points. A full path is the sum of segments.
Both click workflows build a path from direct_line segments — V-shaped absolute-value pieces between waypoints. The core formula for one segment:
For endpoints
Full path:
Vertical segments: if the next waypoint has GraphBot.py's process_clicks_to_waypoints.
- Run the web UI, optionally Захват поля.
- 1st click — your active soldier (purple A). You choose the position manually on the screenshot.
- Next clicks — targets (enemies, detour points) in click order.
- If a click lands left of the previous waypoint → vertical segment is inserted automatically.
- Копировать y — copies the expression without
y=, e.g.:
-1.2*(abs(x - -18.5) - abs(x - -5.2)) + 0.8*(abs(x - -5.2) - abs(x - 12.1))
Paste into Graphwar. In normal mode the game still adds its own vertical shift (+c) so the shot passes through your soldier.
- Start
GraphBot.py, choose mode1, press F1. - F3 — start recording clicks on the live game field; F4 — done.
- Click targets only on the field (clicks outside the capture region are ignored).
- GraphBot auto-detects the active soldier (red glow + OpenCV), sorts targets by
x, buildssoldier → target₁ → target₂ → …. - Formula copied to clipboard — no
y=prefix.
If active-player detection fails, tune tools/calibrate_active.py.
| Web UI click mode | GraphBot.py click mode |
|
|---|---|---|
| Where you click | Canvas (after screenshot) | Live Graphwar window |
| Active soldier | Manual 1st click (A) | Auto-detected from screenshot |
| Target order | Click order + vertical-left rule | Sorted by x |
| Formula prefix | none | none |
Draw mode lives in the web UI only. Sketch a curve, sample it into a dataset, and approximate with one of four methods.
Screenshot placeholder: save your best draw-mode UI capture as
docs/images/draw-mode-overview.png.
flowchart TD
A[Mouse draw on canvas] --> B[Merge points with same x]
B --> C[Uniform resample with sample step]
C --> D[Training dataset blue points]
D --> E{Approximation method}
E --> L[Linear segments]
E --> S[Sigmoid network]
E --> T[Taylor MLP]
E --> F[Fourier MLP]
- Draw — freehand stroke in game coordinates (
x: -25…25,y: -15…15). - Merge — points with nearly equal
xare averaged (stable vertical strokes). - Resample — uniform steps along
xcontrolled by dataset step (sampleStep). More points → more linear segments; smoother target for neural approximators. - Approximate — pick a method; compare MSE in the panel; copy the winning formula.
The red curve is your intent; blue dots are the dataset; green is the approximation.
Connect consecutive dataset points with the same direct_line formula as click mode. Segment count ≈ dataset points − 1.
When to use: You want an exact piecewise path through the samples — same math as click mode, but waypoints come from drawing instead of clicking.
A shallow network of shifted sigmoids — inspired by the universal approximation theorem: a sum of sigmoids can approximate wide classes of curves.
Model:
Graphwar export uses the logistic form:
| Parameter | Role |
|---|---|
numNeurons |
Number of sigmoid steps |
sigmoidK |
Sharpness of each step |
stepHeights |
Initialize |
freezeX0 |
Keep uniform neuron positions while training weights |
Polynomial features around a scaled origin — related to a Taylor expansion mindset: local behavior encoded by powers of
Features:
With hidden layers:
With 0 hidden layers: pure polynomial in
| Parameter | Role |
|---|---|
taylorOrder |
Highest power |
taylorHiddenLayers |
0 = pure polynomial; >0 = MLP on features |
taylorHiddenSize |
Width of hidden layers |
Trigonometric basis — same spirit as a Fourier series on a normalized interval:
With 0 hidden layers: linear combination of harmonics (Fourier-like sum).
With hidden layers: richer expressivity via MLP on
| Parameter | Role |
|---|---|
fourierHarmonics |
Number of harmonic pairs |
fourierHiddenLayers |
0 = pure harmonic sum |
fourierHiddenSize |
Hidden layer width when MLP is used |
Status: in development. Auto mode is not the main focus of the project yet. Core pieces exist (screen capture, player detection, preview overlay, prototype planners), but gameplay-critical behavior is still missing or unreliable — teammate filtering, accurate enemy radius, black-circle avoidance, and stable active-player detection are all on the roadmap.
Automatic mode (0 at startup) tries to detect enemies and build formulas without manual input. Treat it as a preview of what's coming, not a finished autopilot.
| Area | Current state |
|---|---|
| Teammates | Left/right split only — may route through allies |
| Enemies | Aims at circle centers, not full hit radius |
| Black obstacles | Detection exists but auto routing is not fully wired |
| Active player | Fallback heuristics; red-glow detection still being tuned |
| UX | Busy-wait on F-keys; formula loop is rough around the edges |
| Planner | Description | Maturity |
|---|---|---|
| A chain* | Path through enemy centers; obstacle avoidance partially implemented | Prototype |
| Polynomial search | Sample and mutate polynomials anchored at your soldier; score by hits and penalties | Experimental |
| Symbolic GA | Evolve Graphwar-like expressions on live scene data | Experimental |
Polynomial candidate form:
Updates roughly every second while Graphwar is visible. Press F2 to quit.
For reliable results right now, use the web UI or GraphBot.py click mode.
GraphBot/
├── GraphBot.py # Main bot (auto + click modes)
├── core/ # Capture, detection, pathfinding, planners
├── config/ # JSON configs (capture, players, obstacles)
├── tools/
│ ├── approximator_server.py # Web UI server (click + draw modes)
│ ├── preview_capture.py # Debug capture region
│ └── calibrate_*.py # Tune detection parameters
├── Visuals in p5.js/
│ └── universal-approximator/ # Web UI (p5.js + in-browser training)
├── docs/images/ # README screenshots (add yours here)
├── GAME_RULES.md # Graphwar rules reference
├── TODO.md # Detailed dev notes (Russian)
└── outputs/ # Local logs / temp artifacts (gitignored)
High-level checklist distilled from TODO.md. Detailed notes stay in that file.
Focus: most open items below are auto mode blockers. Click mode and draw mode are usable today; auto mode should not be expected to play rounds reliably until these land.
- Teammate avoidance (auto) — distinguish allies from enemies beyond left/right split; never route through teammates.
- Enemy as a circle — use radius from Hough, not just center; one segment may hit multiple nearby enemies.
- Black obstacle avoidance (auto) — enable
detect_black_circles()in auto mode; pathfind around lethal circles. - Active player detection — prioritize red glow outline over “largest circle” heuristic.
- Keyboard UX — replace F1/F3/F4 busy-wait with OpenCV
waitKey; stay alive after click-mode formula instead of exiting. - Calibration suite — sliders for Hough thresholds, glow mask, field margins; export JSON for
GraphBot.py. - Dynamic field bounds — derive capture rect from window size instead of hard-coded margins.
- Web UI with Click mode (default) + Draw mode (4 approximation methods)
- Click mode: manual soldier (A), vertical segments on left-click, formula without
y= - Field capture resets previous clicks / strokes in the web UI
- Graceful handling when no players are detected (
GraphBot.py) - Click-mode vertical segments in
GraphBot.py(process_clicks_to_waypoints) - Win32 field capture +
capture_config.json - Partial calibration tools (
preview_capture,calibrate_active,calibrate_players)
This repo is actively evolving — a pet project built for fun and learning, not a finished product.
The biggest active effort is auto mode — obstacle routing, teammate logic, and trustworthy detection. Draw mode and click mode will keep improving too. If you have ideas (especially for auto planners), I'd love to hear them.
Something broken? Open an Issue with steps to reproduce, your Windows version, and a screenshot if possible.
Have a feature idea or math trick worth adding? Same place — Issues or a PR. All constructive feedback welcome.
MIT — see LICENSE.
Built with curiosity for Graphwar, OpenCV, and a bit of approximation theory.








