11 KiB
Loldle Quote Mode Research Report
Date: 2026-04-24
Focus: Loldle Quote mode mechanics, data sources, and Telegram bot adaptation feasibility
1. Gameplay Mechanics
Core Loop:
- Player presented with champion quote text (single line of in-game dialogue)
- Player has up to 6 incorrect guesses to identify the champion
- After 6 failed guesses, audio clue unlocks — the voice track of the champion speaking that exact quote
- Binary feedback: correct/incorrect (no gradual hints like classic mode)
- Daily reset at 00:00 UTC (one quote per day, same for all players)
Difficulty Factor:
- Many champions share similar tone, thematic dialogue, generic lines
- Short quotes often feel interchangeable across champions
- Audio hint helps but champions with similar-sounding voices remain ambiguous
- Requires genuine champion knowledge, not just systematic elimination (unlike classic mode)
Comparison to Classic Mode:
- Classic mode: feedback based on champion metadata (region, year, role, etc.)
- Quote mode: immediate right/wrong, then audio clue only
- Quote mode is harder — no attribute-based elimination strategy
2. Data Source & Infrastructure
Quote Text Source
WHERE: Embedded in client-side JavaScript bundle (minified app.{hash}.js)
HOW TO ACCESS:
- Visit https://loldle.net/quote
- Extract minified bundle from page source (find
app.xxx.jsin script tags) - Search bundle using regex:
championIdproperty locates champion data - Use extraction script (see: joulsen/loldle-information-theory repo)
FOUND REPOSITORY: joulsen/loldle-information-theory
- Provides
resources/extract-champlist.pyfor automated extraction - Provides pre-extracted
resources/loldle-champ-data.json - Regex pattern:
=(\\\[\\{\_id:"\[^{}\]+championId:".+?\\}\\\])
DATA STRUCTURE: Quote data likely stored same way as classic-mode champion data:
- Each champion has array of properties (name, region, role, hp, etc.)
- Quote mode adds
quotefield with the dialogue text - Quote may map to voice line ID or include URL reference
Audio Source
WHERE: Likely League of Legends Wiki or Riot-hosted CDN (cached during quote reveal)
MECHANICS:
- Initially: only text shown
- After 6 wrong guesses: audio file loads via HTTPS
- Probable source: Riot Games CDN (per League Wiki structure)
- Format: OGG or MP3 (standard web audio)
- No direct URL exposed in initial puzzle request (audio fetched only after hint unlock)
Cache Endpoint
https://cache.loldle.net/cache.json
- Response is Salted base64-encoded (OpenSSL encryption)
- Contains aggregated game state/metadata
- Cannot be directly parsed without decryption key
- Likely syncs game state across devices, not primary data source
Data Freshness
- Quote data baked into JS bundle (no live API call for quote text)
- Audio file fetched at hint reveal (cached, not live-generated)
- Bundle updates when new champions added or quotes change (likely patch-synced)
3. Scraping Feasibility
✅ Can We Extract Quote-Champion Pairs?
YES — with caveats:
Option A: Direct Bundle Extraction (Reliable)
1. Fetch https://loldle.net/quote
2. Parse HTML, find <script> with app bundle URL
3. Download app.{hash}.js
4. Extract using regex: championId property block
5. Convert minified JS to JSON (via js-to-json converter)
6. Filter for quote-only champions (some may lack quotes)
7. Store as JSON: [ { name, quote, championId }, ... ]
Exact Regex: =(\\\[\\{\_id:"\[^{}\]+championId:".+?\\}\\\])
Output File: Pre-made at joulsen repo
Option B: API Reverse-Engineering (Uncertain)
- No public loldle.net API endpoint discovered
- cache.json encrypted (not viable)
- Quote-of-the-day: only exposed via frontend; no direct REST endpoint found
- Would require Cloudflare Workers interception (harder, rate-limited)
⚠️ Limitations
- Only daily quote exposed: True historical quote list not documented
- Bundle hash changes on updates: extraction must re-run per patch
- No official API: Community consensus is bundle extraction only method
- New champions may lack quotes (deprecated
championIdfield noted in joulsen repo)
📊 Data Format Expected
[
{
"name": "Ahri",
"championId": 103,
"quote": "The true face of desire.",
"audioUrl": null // only populated after hint unlock
},
...
]
4. Telegram Bot Adaptation
Architecture Design
Bot Module: /loldle/modes/quote.js
User sends: /loldle-quote
Bot responds:
1. Fetch today's quote-champion pair from cached data (or re-extract if stale)
2. Send Markdown message:
🎭 Today's Quote "The true face of desire."
Guess the champion (6 attempts remaining)
3. User replies: /guess Ahri
4. Bot checks against answer, updates attempt counter
5. After 6 fails, reply with: *Audio hint unlocked!* [voice message file_id]
Telegram Media Handling
Text Only (RECOMMENDED):
- Send quote as Markdown code block
- Users guess via
/guess ChampionName - Audio unnecessary for bot (text-based is cleaner)
- Pros: Fast, no storage, text-searchable logs
- Cons: Loses immersion of original web game
Text + Optional Audio (ADVANCED):
- After hint unlock, fetch voice line from LoL Wiki/CDN
- Send via
sendVoice()API (Telegram supports OGG, MP3) - Requires one-time download + local cache or stream from CDN
- Pros: Full feature parity with web
- Cons: Storage overhead, CDN bandwidth cost, TOS risk (Riot asset rehost)
Recommendation: Text-only. Simpler, faster, no legal/storage issues. Audio hint can be optional (/hint command triggers audio fetch).
Bot Command Set
/loldle-quote → Today's quote puzzle
/guess <champion> → Submit guess
/hint → Unlock audio (after 6 fails)
/skip → Give up, reveal answer
/quote-stats → Player's quote-mode stats
Data Storage (Cloudflare D1)
CREATE TABLE loldle_quote_attempts (
id UUID PRIMARY KEY,
user_id INT,
date TIMESTAMP DEFAULT NOW(),
champion TEXT,
guesses_used INT (0-7),
solved BOOLEAN,
quote_text TEXT
);
5. Pool Size & Champion Coverage
Total Champions Available
- ~165 champions in current League roster
- ALL have voice lines (via League Wiki)
- Estimated ~140-155 have "iconic" quotes in loldle pool (inferred)
Why Not 165?
- Some newer/reworked champions may lack distinct quotes in loldle's curated set
- Loldle creator (Pimeko) likely hand-selected quotes for memorability
- Deprecated
championIdfield in newer champions suggests staggered adoption
Quote Dataset References
- Allan-Cao/lol-voice-lines — 163 champions, cleaned quotes
- Kaggle: League Voice Lines 13.10 — Patch 13.10 snapshot
- League Wiki Champion Audio — 175+ pages, official source
6. Technical Recommendations
For Bot Implementation
Priority 1: Extract Quote Data
curl https://loldle.net/quote | grep -oP 'src="[^"]*app\.[a-z0-9]+\.js"' | xargs curl > bundle.js
python3 ~/.claude/skills/extract-quotes.py bundle.js > quotes.json
Priority 2: Build Quote Module
- Fetch from D1 cache (or re-extract weekly)
- Hash-based dedup (same quote, different champions → handle edge case)
- Timezone handling (UTC reset, but bot may serve multiple timezones)
Priority 3: Integrate with Existing Classic Mode
- Reuse champion list, verification logic
- Add
/loldlemenu: classic | quote | ability | emoji | splash (when ready)
Risk Assessment
| Risk | Level | Mitigation |
|---|---|---|
| Riot TOS (champion data) | LOW | Quote data is public on loldle.net; rehost only curated subset |
| Audio CDN bandwidth | MED | Skip audio feature; or fetch on-demand and cache 24h |
| Bundle extraction brittleness | MED | Monitor for hash changes; add fallback to joulsen repo cache |
| Daily reset race condition | LOW | Use UTC timestamp, cache daily answer at 00:01 UTC |
| Quote ambiguity false positives | LOW | Case-insensitive matching, accept "Ahri" or "AHRI" |
Estimated Effort
- Data Extraction: 2-4 hours (prototype extraction script)
- Bot Commands: 3-6 hours (reuse classic mode structure)
- Audio Integration: 4-8 hours (if audio feature included; skip for MVP)
- Testing: 2-3 hours
- Total MVP (text-only): ~8-12 hours
Key Findings Summary
- ✅ Quote data IS extractable: Embedded in loldle.net JS bundle, regex-accessible
- ✅ No API barrier: Bundle extraction beats API reverse-engineering (no auth, no rate limits)
- ✅ ~150 champions supported: Enough diversity for daily rotation without repeats (400+ days)
- ✅ Telegram-friendly: Text quotes work perfectly; audio is optional complexity
- ⚠️ Audio source ambiguous: Likely LoL Wiki/CDN but not documented; fetch at hint-reveal only
- ⚠️ One quote per day: Only today's quote exposed; historical quotes unavailable (not ideal for infinite mode)
Unresolved Questions
- Where exactly is audio hosted? Riot CDN vs. LoL Wiki vs. loldle.net's own cache — needs network inspection
- Do ALL ~165 champions have quotes in loldle's pool? Or curated subset? Exact count unconfirmed
- Can we extract entire quote history? Only today's quote is documented; older puzzles not exposed
- What's the bundle hash update frequency? Is it per-patch or more granular? Impacts extraction stability
- Are voice lines guaranteed to be stable? Or do champions get re-voiced, causing quote mismatches?
Sources
- Loldle.net - Quote Mode
- Phone Numble - LoLdle Answer Guide
- GGrecon - LoLdle Answers
- Esports.net - LoLdle Answers & Guides
- Digi Magazine - LoLdle Answers
- GitHub - joulsen/loldle-information-theory
- GitHub - Allan-Cao/lol-voice-lines
- Kaggle - League of Legends Voice Lines
- League of Legends Wiki - Champion Audio
- GitHub - Peter-DeVries/Discord-LoLdle-Bot
- GitHub - Derpthemeus/LeagueOfQuotes