ItzYumeii dc7feed03e
CI/CD / Build (push) Successful in 55s
CI/CD / Frontend Build (push) Successful in 24s
CI/CD / Unit Tests (push) Successful in 55s
CI/CD / Frontend Docker (push) Successful in 2m1s
CI/CD / Docker (push) Successful in 4m8s
feat(DRW-001) example docker-compose
2026-09-14 01:25:13 +03:00
2026-09-13 20:37:48 +03:00
2026-09-13 20:37:48 +03:00
2026-09-13 20:37:48 +03:00
2026-09-13 21:11:29 +03:00
2026-09-13 20:55:01 +03:00
2026-09-13 20:37:48 +03:00
2026-09-13 20:37:48 +03:00
2026-09-13 20:37:48 +03:00
2026-09-13 20:55:01 +03:00

🎲 Dota Random 🌸

"I-it's not like I made a whole randomizer just so YOU could have chaotic fun in your games or anything... b-baka." 💢

Fine, FINE. Since you're making me explain it: this is a Dota 2 hero + item build randomizer. You pick how much chaos you want — scope it to melee heroes, lock item tags, disable half the randomness if you're a coward — and it rolls you a hero, a full item build (slot 1 is always boots, don't argue with me about it), neutral item candidates per stage, enchantments, and tells you when you're allowed to buy your Aghanim's. Not that I care if you actually use it properly. 🎀

It's not a toy. ...Okay it's kind of a toy. Shut up. ✨

🌷 What it actually does

  • Hero scope — filter by attack type and/or primary attribute, or leave it wide open if you're feeling brave
  • Item scope — restrict rolls to items carrying specific purpose tags (Physical Damage, Disable, Sustain, etc.)
  • Slot 1 is always boots 👢 — every existing boots item in the game is eligible, including separate grades like Boots of Travel / Boots of Travel 2 and Dagon's five levels, each rolled as its own distinct outcome
  • Neutral items, honestly modeled — each active tier suggests 2 real candidates, because the app can't actually control what drops in your match. You click whichever one you got, or browse the full tier if neither matches
  • Enchantments, guaranteed ⭐ — no RNG-within-RNG nonsense here. If enchantment rolling is on, you get one, scoped correctly to your hero's primary attribute (including the "works on literally any hero" ones — yes, those exist, no I didn't forget about them)
  • Aghanim's Scepter & Shard roll as normal items now — no special-cased fake probability. You also get to say whether you're "allowed" to buy them mid-build or only after your 6 slots are full, for whenever they don't get rolled naturally
  • Reroll anything 🔁 — hero, a single item slot, a specific neutral tier, a specific enchantment tier. Rerolling your hero also refreshes your neutral items and enchantments, since a new hero deserves a fresh itemization pass, o-obviously
  • Manual override, always available — disable randomness for any slot/dimension and pick it yourself instead

💐 Stack

Not that you need to know this to use it, but since you're being nosy:

Layer Tech
Backend Rust, axum, sqlx (Postgres)
Frontend React, TypeScript, Vite, Tailwind CSS
Database PostgreSQL
Data source Scraped live from Liquipedia via Python scripts (no hardcoded/stale game data, thank you very much)
Deployment Docker Compose + a Gitea Actions CI/CD pipeline

🌼 Getting it running (pay attention, I'm not repeating myself)

1. Database

Spin up a Postgres instance however you like — there's a docker-compose.yml in here that already knows how to do it. Then fill in .env at the project root:

DATABASE_URL=postgres://user:password@host:port/dbname
NEUTRAL_TIER_GATE_CHANCE=0.5   # optional, defaults to 0.5 -- the odds of the "can I even change my neutral item this tier" gate

Migrations run automatically on startup (sqlx::migrate!() — it's embedded in the binary, you don't need to run anything by hand). But the tables start empty — the actual hero/item/enchantment data isn't hardcoded anywhere, it's scraped:

pip install requests beautifulsoup4

# edit USER_AGENT at the top of each script first -- Liquipedia's API
# terms require a real, identifying User-Agent, not a generic one
python scripts/scrape_heroes.py
python scripts/scrape_items.py

sqlx migrate run

Yes, this means the roster stays current with whatever patch Liquipedia reflects. Rerun the scripts whenever you want fresh data. I'm not doing that part for you. 🌱

2. Backend

cargo run

Serves the API on :8080.

3. Frontend

cd frontend
npm install
npm run dev

Runs on :5173 with a dev proxy to the backend, so it just works. You're welcome. 💗

4. Or just use Docker Compose

docker compose up

...if the images are actually built and pushed, which they will be, because there's a whole CI pipeline for it. I didn't half-ass this. ✨

🎀 Project layout, since you'll get lost otherwise

src/            Rust backend (axum handlers, roll logic, models)
migrations/     sqlx migrations (schema + scraped seed data)
scripts/        Python scrapers (Liquipedia -> migration files)
frontend/       React + TypeScript SPA
.gitea/         CI/CD workflow

🌸 A note on the data

Heroes, items, and enchantments are scraped from Liquipedia's Dota 2 wiki, not hand-typed or pulled from memory — patches change too fast for that to stay accurate, and I refuse to ship stale data. The scrapers check each item's actual current status (active / removed / unreleased / hidden) rather than trusting whatever list happens to mention it, because apparently even wikis get this wrong sometimes. 🧐

📎 Disclaimer

Part of this project — the whole frontend, a chunk of the Rust backend, the data scrapers, the CI/CD setup — was written with AI assistance. It's not like every line was hand-crafted by a lone genius at 3am. Mostly. I just don't like writing boilerplate code or code I already know how to write! Baka! 💢

🌷 Author

ItzYumeii

...I guess if you actually enjoy using this, that's... fine. Not that it matters to me or anything. 🩷

S
Description
Dota Random Web Application
Readme
136 KiB
Languages
Rust 35.3%
TypeScript 32.9%
Python 30.4%
Dockerfile 0.7%
CSS 0.4%
Other 0.3%