diff --git a/.atl/skill-registry.md b/.atl/skill-registry.md deleted file mode 100644 index 52c5f7a01..000000000 --- a/.atl/skill-registry.md +++ /dev/null @@ -1,67 +0,0 @@ -# Skill Registry - -**Delegator use only.** Any agent that launches sub-agents reads this registry to resolve compact rules, then injects them directly into sub-agent prompts. Sub-agents do NOT read this registry or individual SKILL.md files. - -See `_shared/skill-resolver.md` for the full resolution protocol. - -## User Skills - -| Trigger | Skill | Path | -|---------|-------|------| -| When creating a pull request, opening a PR, or preparing changes for review. | branch-pr | /home/aalonso/.config/opencode/skills/branch-pr/SKILL.md | -| When creating a GitHub issue, reporting a bug, or requesting a feature. | issue-creation | /home/aalonso/.config/opencode/skills/issue-creation/SKILL.md | -| When writing Go tests, using teatest, or adding test coverage. | go-testing | /home/aalonso/.config/opencode/skills/go-testing/SKILL.md | -| When user says "judgment day", "judgment-day", "review adversarial", "dual review", "doble review", "juzgar", "que lo juzguen". | judgment-day | /home/aalonso/.config/opencode/skills/judgment-day/SKILL.md | -| When user asks to create a new skill, add agent instructions, or document patterns for AI. | skill-creator | /home/aalonso/.config/opencode/skills/skill-creator/SKILL.md | - -## Compact Rules - -Pre-digested rules per skill. Delegators copy matching blocks into sub-agent prompts as `## Project Standards (auto-resolved)`. - -### branch-pr -- Every PR MUST link an approved issue; blank PRs without issue linkage are blocked. -- Verify the linked issue has `status:approved` before opening the PR. -- Create branches as `type/description` matching `feat|fix|chore|docs|style|refactor|perf|test|build|ci|revert` plus lowercase slug. -- Use conventional commits; never include AI attribution. -- Open PR with the repository template and add exactly one `type:*` label. -- Ensure automated checks pass before merge. - -### issue-creation -- Use GitHub issue templates only; blank issues are disabled. -- Search existing issues for duplicates before creating a new one. -- Bug reports and feature requests must fill all required fields and pre-flight checkboxes. -- Newly created issues receive `status:needs-review`; maintainer approval adds `status:approved`. -- Do not open PRs until the linked issue is approved. -- Questions belong in Discussions, not issues. - -### go-testing -- Prefer table-driven tests with named cases and `t.Run`. -- Test Bubbletea model state transitions directly by sending messages to `Update`. -- Use `teatest` for full TUI integration when terminal behavior matters. -- Keep assertions precise; check both returned values and error presence. -- Use golden files for stable complex output snapshots. -- Separate unit tests from integration tests when external resources or long-running setup is involved. - -### judgment-day -- Before launching judges, resolve the skill registry and inject matching compact rules into every judge/fix prompt. -- Launch TWO independent blind judge sub-agents in parallel with identical target and criteria. -- Judges must not know about each other; synthesize verdicts only after both complete. -- Classify findings as confirmed, suspect from one judge, or contradiction. -- Apply fixes, then re-judge until both pass or escalate after two iterations. -- Never perform the review inline when acting as orchestrator. - -### skill-creator -- Create skills only for repeated patterns, project-specific conventions, or complex workflows. -- Do not create a skill for trivial one-off guidance or when documentation already solves the problem. -- Use `skills/{skill-name}/SKILL.md` with frontmatter: name, description with Trigger, license, metadata. -- Keep skill instructions actionable: critical patterns, rules, gotchas, and examples where needed. -- Add optional assets/references only when they materially help execution. -- Validate triggers are specific enough to auto-load at the right time. - -## Project Conventions - -| File | Path | Notes | -|------|------|-------| -| — | — | No project-level convention files found in the project root. | - -Read the convention files listed above for project-specific patterns and rules. All referenced paths have been extracted — no need to read index files to discover more. diff --git a/.gitignore b/.gitignore index a1d8e14f3..d1711f1d3 100644 --- a/.gitignore +++ b/.gitignore @@ -63,3 +63,13 @@ pnpm-debug.log* # ========================= .DS_Store Thumbs.db + +# ========================= +# Tauri mobile generated files (optional, Tauri v2) +# ========================= +src-tauri/gen/ + +# ========================= +# SDD artifacts (openspec) +# ========================= +openspec/ diff --git a/data/lec/draft/MoreFA_Players.json b/data/lec/draft/MoreFA_Players.json deleted file mode 100644 index e6bc4423f..000000000 --- a/data/lec/draft/MoreFA_Players.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "schema_version": "1.0", - "kind": "players", - "data": { - "rostered_seeds": [], - "free_agent_seeds": [ - { - "ign": "Skain", - "firstName": "David", - "lastName": "Carbó Ferrer", - "dob": "1997-03-10", - "nationality": "ES", - "residency": "EMEA", - "role": "Support", - "teamId": "fa", - "rating": 66, - "potential": 69, - "salary": 70000, - "contractEnd": "2026-11-18", - "marketValue": 105000, - "reputation": 62, - "personality": "quiet", - "champions": [ - [ - "Rakan", - 100 - ], - [ - "Thresh", - 100 - ], - [ - "Soraka", - 100 - ], - [ - "Alistar", - 85 - ], - [ - "Lulu", - 70 - ], - [ - "Nami", - 70 - ] - ], - "photo": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/08/Skain_g2v.jpeg/revision/latest?cb=20170802132525", - "found": true - } - ] - } -} diff --git a/data/lec/draft/ai-config.json b/data/lec/draft/ai-config.json deleted file mode 100644 index ffe4e1170..000000000 --- a/data/lec/draft/ai-config.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "schema_version": "1.0", - "kind": "draft_ai_config", - "data": { - "pick": { - "masteryWeight": 1.15, - "metaWeight": 1.1, - "counterAdvantageWeight": 4, - "counterRiskWeight": 3 - }, - "ban": { - "enemyMasteryWeight": 1.15, - "metaWeight": 0.9 - }, - "score": { - "counterAdvantageWeight": 2, - "counterRiskWeight": 2 - }, - "timing": { - "userTurnSeconds": 30, - "aiMinSeconds": 3, - "aiMaxSeconds": 10 - } - } -} diff --git a/data/lec/draft/champion-timings.json b/data/lec/draft/champion-timings.json deleted file mode 100644 index e34eb97aa..000000000 --- a/data/lec/draft/champion-timings.json +++ /dev/null @@ -1,177 +0,0 @@ -{ - "schema_version": "1.0", - "kind": "champion_timings", - "updated_at": "2026-04-19", - "data": { - "Aatrox": "Mid", - "Ahri": "Mid", - "Akali": "Mid", - "Akshan": "Mid", - "Alistar": "Mid", - "Ambessa": "Early", - "Amumu": "Mid", - "Anivia": "Late", - "Annie": "Mid", - "Aphelios": "Late", - "Ashe": "Mid", - "AurelionSol": "Late", - "Aurora": "Mid", - "Azir": "Late", - "Bard": "Mid", - "Belveth": "Late", - "Blitzcrank": "Early", - "Brand": "Mid", - "Braum": "Early", - "Briar": "Mid", - "Caitlyn": "Early", - "Camille": "Late", - "Cassiopeia": "Late", - "Chogath": "Mid", - "Corki": "Late", - "Darius": "Early", - "Diana": "Mid", - "DrMundo": "Late", - "Draven": "Early", - "Ekko": "Mid", - "Elise": "Early", - "Evelynn": "Mid", - "Ezreal": "Mid", - "Fiddlesticks": "Mid", - "Fiora": "Late", - "Fizz": "Mid", - "Galio": "Mid", - "Gangplank": "Late", - "Garen": "Mid", - "Gnar": "Mid", - "Gragas": "Mid", - "Graves": "Mid", - "Gwen": "Late", - "Hecarim": "Mid", - "Hwei": "Late", - "Illaoi": "Mid", - "Irelia": "Mid", - "Ivern": "Mid", - "Janna": "Late", - "JarvanIV": "Early", - "Jax": "Late", - "Jayce": "Early", - "Jhin": "Mid", - "Jinx": "Late", - "KSante": "Mid", - "Kaisa": "Late", - "Kalista": "Early", - "Karma": "Early", - "Karthus": "Late", - "Kassadin": "Late", - "Katarina": "Mid", - "Kayle": "Late", - "Kayn": "Late", - "Kennen": "Mid", - "Khazix": "Mid", - "Kindred": "Mid", - "Kled": "Early", - "KogMaw": "Late", - "Leblanc": "Early", - "LeeSin": "Early", - "Leona": "Early", - "Lillia": "Late", - "Lissandra": "Mid", - "Lucian": "Early", - "Lulu": "Late", - "Lux": "Mid", - "Malphite": "Mid", - "Malzahar": "Mid", - "Maokai": "Mid", - "MasterYi": "Late", - "Mel": "Late", - "Milio": "Late", - "MissFortune": "Mid", - "MonkeyKing": "Mid", - "Mordekaiser": "Mid", - "Morgana": "Mid", - "Naafiri": "Mid", - "Nami": "Mid", - "Nasus": "Late", - "Nautilus": "Early", - "Neeko": "Mid", - "Nidalee": "Early", - "Nilah": "Late", - "Nocturne": "Mid", - "Nunu": "Early", - "Olaf": "Early", - "Orianna": "Late", - "Ornn": "Late", - "Pantheon": "Early", - "Poppy": "Early", - "Pyke": "Early", - "Qiyana": "Mid", - "Rakan": "Mid", - "Rammus": "Early", - "RekSai": "Early", - "Rell": "Mid", - "Renata": "Late", - "Renekton": "Early", - "Rengar": "Mid", - "Riven": "Early", - "Rumble": "Mid", - "Ryze": "Late", - "Samira": "Mid", - "Sejuani": "Mid", - "Senna": "Late", - "Seraphine": "Late", - "Sett": "Mid", - "Shaco": "Mid", - "Shen": "Mid", - "Shyvana": "Late", - "Singed": "Mid", - "Sion": "Late", - "Sivir": "Late", - "Skarner": "Mid", - "Smolder": "Late", - "Sona": "Late", - "Soraka": "Mid", - "Swain": "Late", - "Sylas": "Mid", - "Syndra": "Late", - "TahmKench": "Mid", - "Taliyah": "Mid", - "Talon": "Early", - "Taric": "Late", - "Teemo": "Mid", - "Thresh": "Early", - "Tristana": "Late", - "Trundle": "Early", - "Tryndamere": "Late", - "TwistedFate": "Mid", - "Twitch": "Late", - "Udyr": "Early", - "Urgot": "Mid", - "Varus": "Mid", - "Vayne": "Late", - "Veigar": "Late", - "Velkoz": "Late", - "Vex": "Mid", - "Vi": "Early", - "Viego": "Late", - "Viktor": "Late", - "Vladimir": "Late", - "Volibear": "Early", - "Warwick": "Early", - "Xayah": "Late", - "Xerath": "Late", - "XinZhao": "Early", - "Yasuo": "Late", - "Yone": "Late", - "Yorick": "Late", - "Yunara": "Late", - "Yuumi": "Late", - "Zaahen": "Mid", - "Zac": "Mid", - "Zed": "Mid", - "Zeri": "Late", - "Ziggs": "Late", - "Zilean": "Late", - "Zoe": "Mid", - "Zyra": "Mid" - } -} diff --git a/data/lec/images/players/100238780551262852.png b/data/lec/images/players/100238780551262852.png deleted file mode 100644 index 8e5c40af1..000000000 Binary files a/data/lec/images/players/100238780551262852.png and /dev/null differ diff --git a/data/lec/images/players/100356590519370319.png b/data/lec/images/players/100356590519370319.png deleted file mode 100644 index bfe207fc8..000000000 Binary files a/data/lec/images/players/100356590519370319.png and /dev/null differ diff --git a/data/lec/images/players/100482247959137902.png b/data/lec/images/players/100482247959137902.png deleted file mode 100644 index 2d7d17833..000000000 Binary files a/data/lec/images/players/100482247959137902.png and /dev/null differ diff --git a/data/lec/images/players/101389808348806587.png b/data/lec/images/players/101389808348806587.png deleted file mode 100644 index 0ec94522e..000000000 Binary files a/data/lec/images/players/101389808348806587.png and /dev/null differ diff --git a/data/lec/images/players/102174699705191142.png b/data/lec/images/players/102174699705191142.png deleted file mode 100644 index 751ed3a77..000000000 Binary files a/data/lec/images/players/102174699705191142.png and /dev/null differ diff --git a/data/lec/images/players/102181528883745160.png b/data/lec/images/players/102181528883745160.png deleted file mode 100644 index 48b2ad09b..000000000 Binary files a/data/lec/images/players/102181528883745160.png and /dev/null differ diff --git a/data/lec/images/players/102787200044335760.png b/data/lec/images/players/102787200044335760.png deleted file mode 100644 index 1389d823a..000000000 Binary files a/data/lec/images/players/102787200044335760.png and /dev/null differ diff --git a/data/lec/images/players/102787200059605684.png b/data/lec/images/players/102787200059605684.png deleted file mode 100644 index dbfddcedb..000000000 Binary files a/data/lec/images/players/102787200059605684.png and /dev/null differ diff --git a/data/lec/images/players/103495716738607011.png b/data/lec/images/players/103495716738607011.png deleted file mode 100644 index 19987dce4..000000000 Binary files a/data/lec/images/players/103495716738607011.png and /dev/null differ diff --git a/data/lec/images/players/103495716771322725.png b/data/lec/images/players/103495716771322725.png deleted file mode 100644 index a3dddf716..000000000 Binary files a/data/lec/images/players/103495716771322725.png and /dev/null differ diff --git a/data/lec/images/players/103536968833612789.png b/data/lec/images/players/103536968833612789.png deleted file mode 100644 index ebf8f425c..000000000 Binary files a/data/lec/images/players/103536968833612789.png and /dev/null differ diff --git a/data/lec/images/players/103805069759346933.png b/data/lec/images/players/103805069759346933.png deleted file mode 100644 index 3be567776..000000000 Binary files a/data/lec/images/players/103805069759346933.png and /dev/null differ diff --git a/data/lec/images/players/103877629120745120.png b/data/lec/images/players/103877629120745120.png deleted file mode 100644 index e44f4ec4f..000000000 Binary files a/data/lec/images/players/103877629120745120.png and /dev/null differ diff --git a/data/lec/images/players/103889902476986558.png b/data/lec/images/players/103889902476986558.png deleted file mode 100644 index eb04d9152..000000000 Binary files a/data/lec/images/players/103889902476986558.png and /dev/null differ diff --git a/data/lec/images/players/103935359525547325.png b/data/lec/images/players/103935359525547325.png deleted file mode 100644 index 5414b9313..000000000 Binary files a/data/lec/images/players/103935359525547325.png and /dev/null differ diff --git a/data/lec/images/players/104287359934240404.png b/data/lec/images/players/104287359934240404.png deleted file mode 100644 index 487f55469..000000000 Binary files a/data/lec/images/players/104287359934240404.png and /dev/null differ diff --git a/data/lec/images/players/105501717406803640.png b/data/lec/images/players/105501717406803640.png deleted file mode 100644 index 7dcf54d15..000000000 Binary files a/data/lec/images/players/105501717406803640.png and /dev/null differ diff --git a/data/lec/images/players/105501802535116331.png b/data/lec/images/players/105501802535116331.png deleted file mode 100644 index 3c8ee3cb3..000000000 Binary files a/data/lec/images/players/105501802535116331.png and /dev/null differ diff --git a/data/lec/images/players/105501834624360050.png b/data/lec/images/players/105501834624360050.png deleted file mode 100644 index 42406df56..000000000 Binary files a/data/lec/images/players/105501834624360050.png and /dev/null differ diff --git a/data/lec/images/players/105503548109547493.png b/data/lec/images/players/105503548109547493.png deleted file mode 100644 index ff8a7cd79..000000000 Binary files a/data/lec/images/players/105503548109547493.png and /dev/null differ diff --git a/data/lec/images/players/105504920899018806.png b/data/lec/images/players/105504920899018806.png deleted file mode 100644 index da856ae04..000000000 Binary files a/data/lec/images/players/105504920899018806.png and /dev/null differ diff --git a/data/lec/images/players/105515296576479523.png b/data/lec/images/players/105515296576479523.png deleted file mode 100644 index 9c3371b27..000000000 Binary files a/data/lec/images/players/105515296576479523.png and /dev/null differ diff --git a/data/lec/images/players/105537190986692036.png b/data/lec/images/players/105537190986692036.png deleted file mode 100644 index 63efc47b0..000000000 Binary files a/data/lec/images/players/105537190986692036.png and /dev/null differ diff --git a/data/lec/images/players/105548731617719496.png b/data/lec/images/players/105548731617719496.png deleted file mode 100644 index bd6a98efb..000000000 Binary files a/data/lec/images/players/105548731617719496.png and /dev/null differ diff --git a/data/lec/images/players/105553696718837337.png b/data/lec/images/players/105553696718837337.png deleted file mode 100644 index 065c65da2..000000000 Binary files a/data/lec/images/players/105553696718837337.png and /dev/null differ diff --git a/data/lec/images/players/105554437688383476.png b/data/lec/images/players/105554437688383476.png deleted file mode 100644 index f97baf762..000000000 Binary files a/data/lec/images/players/105554437688383476.png and /dev/null differ diff --git a/data/lec/images/players/105554439426664062.png b/data/lec/images/players/105554439426664062.png deleted file mode 100644 index 5414b9313..000000000 Binary files a/data/lec/images/players/105554439426664062.png and /dev/null differ diff --git a/data/lec/images/players/105647947016264573.png b/data/lec/images/players/105647947016264573.png deleted file mode 100644 index 105d8c503..000000000 Binary files a/data/lec/images/players/105647947016264573.png and /dev/null differ diff --git a/data/lec/images/players/105700869624784693.png b/data/lec/images/players/105700869624784693.png deleted file mode 100644 index 76616d2dd..000000000 Binary files a/data/lec/images/players/105700869624784693.png and /dev/null differ diff --git a/data/lec/images/players/105830645287286396.png b/data/lec/images/players/105830645287286396.png deleted file mode 100644 index 7bc40861a..000000000 Binary files a/data/lec/images/players/105830645287286396.png and /dev/null differ diff --git a/data/lec/images/players/106625308523122120.png b/data/lec/images/players/106625308523122120.png deleted file mode 100644 index 9c9353581..000000000 Binary files a/data/lec/images/players/106625308523122120.png and /dev/null differ diff --git a/data/lec/images/players/107045034481599547.png b/data/lec/images/players/107045034481599547.png deleted file mode 100644 index ca7316d14..000000000 Binary files a/data/lec/images/players/107045034481599547.png and /dev/null differ diff --git a/data/lec/images/players/107128052280762804.png b/data/lec/images/players/107128052280762804.png deleted file mode 100644 index 4f03c0670..000000000 Binary files a/data/lec/images/players/107128052280762804.png and /dev/null differ diff --git a/data/lec/images/players/107156544177574787.png b/data/lec/images/players/107156544177574787.png deleted file mode 100644 index 018186c4b..000000000 Binary files a/data/lec/images/players/107156544177574787.png and /dev/null differ diff --git a/data/lec/images/players/107455908655055017.png b/data/lec/images/players/107455908655055017.png deleted file mode 100644 index 948ab3cd1..000000000 Binary files a/data/lec/images/players/107455908655055017.png and /dev/null differ diff --git a/data/lec/images/players/107464179845128878.png b/data/lec/images/players/107464179845128878.png deleted file mode 100644 index 1f9cc1077..000000000 Binary files a/data/lec/images/players/107464179845128878.png and /dev/null differ diff --git a/data/lec/images/players/107492067202132417.png b/data/lec/images/players/107492067202132417.png deleted file mode 100644 index 3d6c642d8..000000000 Binary files a/data/lec/images/players/107492067202132417.png and /dev/null differ diff --git a/data/lec/images/players/107492114500277895.png b/data/lec/images/players/107492114500277895.png deleted file mode 100644 index 2d90b3278..000000000 Binary files a/data/lec/images/players/107492114500277895.png and /dev/null differ diff --git a/data/lec/images/players/107492119089043087.png b/data/lec/images/players/107492119089043087.png deleted file mode 100644 index 1ed9502e7..000000000 Binary files a/data/lec/images/players/107492119089043087.png and /dev/null differ diff --git a/data/lec/images/players/107564404490889053.png b/data/lec/images/players/107564404490889053.png deleted file mode 100644 index 7c5801c8a..000000000 Binary files a/data/lec/images/players/107564404490889053.png and /dev/null differ diff --git a/data/lec/images/players/107605411481021064.png b/data/lec/images/players/107605411481021064.png deleted file mode 100644 index a35ea29f8..000000000 Binary files a/data/lec/images/players/107605411481021064.png and /dev/null differ diff --git a/data/lec/images/players/107605583684952312.png b/data/lec/images/players/107605583684952312.png deleted file mode 100644 index 1a7cfd725..000000000 Binary files a/data/lec/images/players/107605583684952312.png and /dev/null differ diff --git a/data/lec/images/players/107621095379170267.png b/data/lec/images/players/107621095379170267.png deleted file mode 100644 index d02dc9b09..000000000 Binary files a/data/lec/images/players/107621095379170267.png and /dev/null differ diff --git a/data/lec/images/players/107767810249714879.png b/data/lec/images/players/107767810249714879.png deleted file mode 100644 index cd8fda623..000000000 Binary files a/data/lec/images/players/107767810249714879.png and /dev/null differ diff --git a/data/lec/images/players/107840393299826151.png b/data/lec/images/players/107840393299826151.png deleted file mode 100644 index 91a73e7f6..000000000 Binary files a/data/lec/images/players/107840393299826151.png and /dev/null differ diff --git a/data/lec/images/players/108205130709313212.png b/data/lec/images/players/108205130709313212.png deleted file mode 100644 index d557dde20..000000000 Binary files a/data/lec/images/players/108205130709313212.png and /dev/null differ diff --git a/data/lec/images/players/109461265532592848.png b/data/lec/images/players/109461265532592848.png deleted file mode 100644 index be5053381..000000000 Binary files a/data/lec/images/players/109461265532592848.png and /dev/null differ diff --git a/data/lec/images/players/109705412728201213.png b/data/lec/images/players/109705412728201213.png deleted file mode 100644 index 3cc29e5dd..000000000 Binary files a/data/lec/images/players/109705412728201213.png and /dev/null differ diff --git a/data/lec/images/players/110350224593953686.png b/data/lec/images/players/110350224593953686.png deleted file mode 100644 index 62340d92d..000000000 Binary files a/data/lec/images/players/110350224593953686.png and /dev/null differ diff --git a/data/lec/images/players/98767975961872793.png b/data/lec/images/players/98767975961872793.png deleted file mode 100644 index 1debfa2c3..000000000 Binary files a/data/lec/images/players/98767975961872793.png and /dev/null differ diff --git a/data/lec/images/players/98767975968177297.png b/data/lec/images/players/98767975968177297.png deleted file mode 100644 index 51706a3ce..000000000 Binary files a/data/lec/images/players/98767975968177297.png and /dev/null differ diff --git a/data/lec/images/players/99322214618656216.png b/data/lec/images/players/99322214618656216.png deleted file mode 100644 index 565286e87..000000000 Binary files a/data/lec/images/players/99322214618656216.png and /dev/null differ diff --git a/data/lec/images/players/99322214629661297.png b/data/lec/images/players/99322214629661297.png deleted file mode 100644 index 017924f76..000000000 Binary files a/data/lec/images/players/99322214629661297.png and /dev/null differ diff --git a/data/lec/images/players/99322214653265200.png b/data/lec/images/players/99322214653265200.png deleted file mode 100644 index ec5de60b7..000000000 Binary files a/data/lec/images/players/99322214653265200.png and /dev/null differ diff --git a/data/lec/images/players/99566406047571736.png b/data/lec/images/players/99566406047571736.png deleted file mode 100644 index 1f31c6ab7..000000000 Binary files a/data/lec/images/players/99566406047571736.png and /dev/null differ diff --git a/data/lec/images/teams/fnatic.png b/data/lec/images/teams/fnatic.png deleted file mode 100644 index 9aa22a980..000000000 Binary files a/data/lec/images/teams/fnatic.png and /dev/null differ diff --git a/data/lec/images/teams/g2-esports.png b/data/lec/images/teams/g2-esports.png deleted file mode 100644 index a1a5fec67..000000000 Binary files a/data/lec/images/teams/g2-esports.png and /dev/null differ diff --git a/data/lec/images/teams/giantx-lec.png b/data/lec/images/teams/giantx-lec.png deleted file mode 100644 index 51a1ce980..000000000 Binary files a/data/lec/images/teams/giantx-lec.png and /dev/null differ diff --git a/data/lec/images/teams/karmine-corp.png b/data/lec/images/teams/karmine-corp.png deleted file mode 100644 index ab9d12c32..000000000 Binary files a/data/lec/images/teams/karmine-corp.png and /dev/null differ diff --git a/data/lec/images/teams/mad-lions.png b/data/lec/images/teams/mad-lions.png deleted file mode 100644 index 413f18346..000000000 Binary files a/data/lec/images/teams/mad-lions.png and /dev/null differ diff --git a/data/lec/images/teams/natus-vincere.png b/data/lec/images/teams/natus-vincere.png deleted file mode 100644 index d00fb4373..000000000 Binary files a/data/lec/images/teams/natus-vincere.png and /dev/null differ diff --git a/data/lec/images/teams/sk-gaming.png b/data/lec/images/teams/sk-gaming.png deleted file mode 100644 index 1439ebba1..000000000 Binary files a/data/lec/images/teams/sk-gaming.png and /dev/null differ diff --git a/data/lec/images/teams/team-bds.png b/data/lec/images/teams/team-bds.png deleted file mode 100644 index 8c8e65785..000000000 Binary files a/data/lec/images/teams/team-bds.png and /dev/null differ diff --git a/data/lec/images/teams/team-heretics-lec.png b/data/lec/images/teams/team-heretics-lec.png deleted file mode 100644 index 74dd9d923..000000000 Binary files a/data/lec/images/teams/team-heretics-lec.png and /dev/null differ diff --git a/data/lec/images/teams/team-vitality.png b/data/lec/images/teams/team-vitality.png deleted file mode 100644 index 48d91ec74..000000000 Binary files a/data/lec/images/teams/team-vitality.png and /dev/null differ diff --git a/data/lec/seed.teams-players.json b/data/lec/seed.teams-players.json deleted file mode 100644 index 51cf743e9..000000000 --- a/data/lec/seed.teams-players.json +++ /dev/null @@ -1,570 +0,0 @@ -{ - "source": "lolesports-api", - "fetchedAt": "2026-04-17T14:51:49.3617167-03:00", - "league": "LEC", - "leagueId": "98767991302996019", - "tournamentId": "115548681802226458", - "teamCount": 10, - "teams": [ - { - "id": "98767991866488695", - "slug": "fnatic", - "name": "Fnatic", - "code": "FNC", - "image": "http://static.lolesports.com/teams/1631819669150_fnc-2021-worlds.png", - "alternativeImage": "http://static.lolesports.com/teams/1592591295310_FnaticFNC-03-FullonLight.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "99322214653265200", - "summonerName": "Upset", - "firstName": "Elias", - "lastName": "Lipp", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652671712_upset.png" - }, - { - "id": "100238780551262852", - "summonerName": "Razork", - "firstName": "Ivǭn", - "lastName": "Mart��n", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652486277_razork.png" - }, - { - "id": "109705412728201213", - "summonerName": "Empyros", - "firstName": "Panagiotis", - "lastName": "Tantis", - "role": "top", - "image": "http://static.lolesports.com/players/1774651449505_empyros.png" - }, - { - "id": "107045034481599547", - "summonerName": "Vladi", - "firstName": "Vladimiros", - "lastName": "Kourtidis", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652694212_vladi.png" - }, - { - "id": "107492067202132417", - "summonerName": "Lospa", - "firstName": "Joon Hyung", - "lastName": "Park", - "role": "support", - "image": "http://static.lolesports.com/players/1774652050575_lospa.png" - } - ] - }, - { - "id": "98767991926151025", - "slug": "g2-esports", - "name": "G2 Esports", - "code": "G2", - "image": "http://static.lolesports.com/teams/G2-FullonDark.png", - "alternativeImage": "http://static.lolesports.com/teams/G2-FullonLight.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "98767975968177297", - "summonerName": "Caps", - "firstName": "Rasmus", - "lastName": "Borregaard Winther", - "role": "mid", - "image": "http://static.lolesports.com/players/1768549998426_Caps-01.png" - }, - { - "id": "99566406047571736", - "summonerName": "BrokenBlade", - "firstName": "Sergen", - "lastName": "�?elik", - "role": "top", - "image": "http://static.lolesports.com/players/1768550002850_BrokenBlade-01.png" - }, - { - "id": "98767975961872793", - "summonerName": "Hans Sama", - "firstName": "Steven", - "lastName": "Liv", - "role": "bottom", - "image": "http://static.lolesports.com/players/1768549994123_HansSama-01.png" - }, - { - "id": "105554439426664062", - "summonerName": "Rodrigo", - "firstName": "Rodrigo", - "lastName": "Domingues Oliveira", - "role": "none", - "image": "http://static.lolesports.com/players/default-headshot.png" - }, - { - "id": "107128052280762804", - "summonerName": "SkewMond", - "firstName": "Rudy", - "lastName": "Semaan", - "role": "jungle", - "image": "http://static.lolesports.com/players/1768549980779_Skewmond-01.png" - }, - { - "id": "102787200059605684", - "summonerName": "Labrov", - "firstName": "Labros", - "lastName": "Papoutsakis", - "role": "support", - "image": "http://static.lolesports.com/players/1768549989298_Labrov-01.png" - } - ] - }, - { - "id": "101383793572656373", - "slug": "giantx-lec", - "name": "GIANTX", - "code": "GX", - "image": "http://static.lolesports.com/teams/1765897105091_GIANTX-logotype-white.png", - "alternativeImage": "http://static.lolesports.com/teams/1765897105092_GIANTX-logotype-white.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "107464179845128878", - "summonerName": "ISMA", - "firstName": "Isma��l", - "lastName": "Boualem", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774651596907_isma.png" - }, - { - "id": "103495716738607011", - "summonerName": "Lot", - "firstName": "Eren", - "lastName": "Y��ld��z", - "role": "top", - "image": "http://static.lolesports.com/players/1774652144804_lot.png" - }, - { - "id": "105501717406803640", - "summonerName": "Noah", - "firstName": "Hyuntaek", - "lastName": "O", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652391494_noah.png" - }, - { - "id": "105501802535116331", - "summonerName": "Jun", - "firstName": "Sejun", - "lastName": "Yoon", - "role": "support", - "image": "http://static.lolesports.com/players/1774651978347_jun.png" - }, - { - "id": "105647947016264573", - "summonerName": "Jackies", - "firstName": "Adam", - "lastName": "Je�?ǭbek", - "role": "mid", - "image": "http://static.lolesports.com/players/1774651628897_jackies.png" - } - ] - }, - { - "id": "111692118851466302", - "slug": "karmine-corp", - "name": "Karmine Corp", - "code": "KC", - "image": "http://static.lolesports.com/teams/1704714951336_KC.png", - "alternativeImage": "http://static.lolesports.com/teams/1704714951337_KC.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "103495716771322725", - "summonerName": "Canna", - "firstName": "Changdong", - "lastName": "Kim", - "role": "top", - "image": "http://static.lolesports.com/players/1774651372836_canna.png" - }, - { - "id": "108205130709313212", - "summonerName": "kyeahoo", - "firstName": "Yeahoo", - "lastName": "Kang", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652002153_kyeahoo.png" - }, - { - "id": "106625308523122120", - "summonerName": "Busio", - "firstName": "Alan", - "lastName": "Cwalina", - "role": "support", - "image": "http://static.lolesports.com/players/1774651329556_busio.png" - }, - { - "id": "105537190986692036", - "summonerName": "Yike", - "firstName": "Martin", - "lastName": "Sundelin", - "role": "jungle", - "image": "http://static.lolesports.com/players/1768550195190_Yike-01.png" - }, - { - "id": "109461265532592848", - "summonerName": "Caliste", - "firstName": "Caliste", - "lastName": "Henry-Hennebert", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651348279_caliste.png" - } - ] - }, - { - "id": "103461966965149786", - "slug": "mad-lions", - "name": "Movistar KOI", - "code": "MKOI", - "image": "http://static.lolesports.com/teams/1734012609283_MKOI_FullColor_Blue.png", - "alternativeImage": "http://static.lolesports.com/teams/1734012609284_MKOI_FullColor_Blue.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "103877629120745120", - "summonerName": "Elyoya", - "firstName": "Javier", - "lastName": "Prades", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774651428253_elyoya.png" - }, - { - "id": "110350224593953686", - "summonerName": "Myrwn", - "firstName": "�?lex", - "lastName": "Villarejo Pastor", - "role": "top", - "image": "http://static.lolesports.com/players/1774652336923_myrwn.png" - }, - { - "id": "103536968833612789", - "summonerName": "Supa", - "firstName": "David", - "lastName": "Mart��nez Garc��a", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652617630_supa.png" - }, - { - "id": "107564404490889053", - "summonerName": "Alvaro", - "firstName": "Alvaro", - "lastName": "Fernǭndez del Amo", - "role": "support", - "image": "http://static.lolesports.com/players/1774651304778_alvaro.png" - }, - { - "id": "105504920899018806", - "summonerName": "Jojopyun", - "firstName": "Joseph Joon", - "lastName": "Pyun", - "role": "mid", - "image": "http://static.lolesports.com/players/1774651666226_jojopyun.png" - } - ] - }, - { - "id": "114868016111590239", - "slug": "natus-vincere", - "name": "Natus Vincere", - "code": "NAVI", - "image": "http://static.lolesports.com/teams/1752746833620_NAVI_FullColor.png", - "alternativeImage": "http://static.lolesports.com/teams/1752746833620_NAVI_FullColor.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "104287359934240404", - "summonerName": "SamD", - "firstName": "Jaehoon", - "lastName": "Lee", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652529720_samd.png" - }, - { - "id": "105700869624784693", - "summonerName": "Maynter", - "firstName": "Volodymyr", - "lastName": "Sorokin", - "role": "top", - "image": "http://static.lolesports.com/players/1774652211219_maynter.png" - }, - { - "id": "105548731617719496", - "summonerName": "Rhilech", - "firstName": "Enes", - "lastName": "U��an", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652507939_rhilech.png" - }, - { - "id": "107840393299826151", - "summonerName": "Poby", - "firstName": "Sungwon", - "lastName": "Yoon", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652447812_poby.png" - }, - { - "id": "103805069759346933", - "summonerName": "Parus", - "firstName": "Polat Furkan", - "lastName": "�?i��ek", - "role": "support", - "image": "http://static.lolesports.com/players/1774652426360_parus.png" - }, - { - "id": "100482247959137902", - "summonerName": "Larssen", - "firstName": "Emil", - "lastName": "Larsson", - "role": "mid", - "image": "http://static.lolesports.com/players/1754473073908_image6331.png" - } - ] - }, - { - "id": "101383793567806688", - "slug": "sk-gaming", - "name": "SK Gaming", - "code": "SK", - "image": "http://static.lolesports.com/teams/1643979272144_SK_Monochrome.png", - "alternativeImage": "http://static.lolesports.com/teams/1643979272151_SK_Monochrome.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "99322214618656216", - "summonerName": "Wunder", - "firstName": "Martin", - "lastName": "Hansen", - "role": "top", - "image": "http://static.lolesports.com/players/1774652747959_wunder.png" - }, - { - "id": "103889902476986558", - "summonerName": "LIDER", - "firstName": "Adam", - "lastName": "Ilyasov", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652028497_lider.png" - }, - { - "id": "105553696718837337", - "summonerName": "Jopa", - "firstName": "Josip", - "lastName": "�?an�?ar", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651949013_jopa.png" - }, - { - "id": "99322214629661297", - "summonerName": "Mikyx", - "firstName": "Mihael", - "lastName": "Mehle", - "role": "support", - "image": "http://static.lolesports.com/players/1774652311878_mikyx.png" - }, - { - "id": "101389808348806587", - "summonerName": "Skeanz", - "firstName": "Duncan", - "lastName": "Marquet", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652595033_skeanz.png" - } - ] - }, - { - "id": "107563714667537640", - "slug": "team-bds", - "name": "Shifters", - "code": "SHFT", - "image": "http://static.lolesports.com/teams/1765897071435_600px-Shifters_allmode.png", - "alternativeImage": "http://static.lolesports.com/teams/1765897071435_600px-Shifters_allmode.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "105554437688383476", - "summonerName": "nuc", - "firstName": "Ilias", - "lastName": "Bizriken", - "role": "mid", - "image": "http://static.lolesports.com/players/1768550938446_Nuc-01.png" - }, - { - "id": "107767810249714879", - "summonerName": "Rooster", - "firstName": "Yunhwan", - "lastName": "Shin", - "role": "top", - "image": "http://static.lolesports.com/players/1768550928914_Rooster-01.png" - }, - { - "id": "105515296576479523", - "summonerName": "Boukada", - "firstName": "Lahlou", - "lastName": "Mehdi", - "role": "jungle", - "image": "http://static.lolesports.com/players/1768550943317_Boukada-01.png" - }, - { - "id": "107492114500277895", - "summonerName": "Paduck", - "firstName": "Seokhyeon", - "lastName": "Park", - "role": "bottom", - "image": "http://static.lolesports.com/players/1768550934005_Paduck-01.png" - }, - { - "id": "102181528883745160", - "summonerName": "Trymbi", - "firstName": "Adrian", - "lastName": "Trybus", - "role": "support", - "image": "http://static.lolesports.com/players/1768550915779_Trymbi-01.png" - }, - { - "id": "107455908655055017", - "summonerName": "JuJuTw0", - "firstName": "Julien", - "lastName": "IZZO", - "role": "none", - "image": "http://static.lolesports.com/players/1639647042551_placeholder.png" - } - ] - }, - { - "id": "109637393694097670", - "slug": "team-heretics-lec", - "name": "Team Heretics", - "code": "TH", - "image": "http://static.lolesports.com/teams/1672933861879_Heretics-Full-Color.png", - "alternativeImage": "http://static.lolesports.com/teams/1672933861879_Heretics-Full-Color.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "105830645287286396", - "summonerName": "Sheo", - "firstName": "ThǸo", - "lastName": "Borile", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652573563_sheo.png" - }, - { - "id": "107156544177574787", - "summonerName": "Tracyn", - "firstName": "Sebastian", - "lastName": "Wojto�?", - "role": "top", - "image": "http://static.lolesports.com/players/1774652650240_tracyn.png" - }, - { - "id": "105501834624360050", - "summonerName": "Ice", - "firstName": "Sang-hoon", - "lastName": "Yoon", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651565551_ice.png" - }, - { - "id": "102174699705191142", - "summonerName": "Serin", - "firstName": "Tolga", - "lastName": "�?lmez", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652550234_serin.png" - }, - { - "id": "107621095379170267", - "summonerName": "Daglas", - "firstName": "Kacper", - "lastName": "Dagiel", - "role": "jungle", - "image": "http://static.lolesports.com/players/1705027284789_daglas.png" - }, - { - "id": "107492119089043087", - "summonerName": "Way", - "firstName": "Han", - "lastName": "Kil", - "role": "support", - "image": "http://static.lolesports.com/players/1774652723449_way.png" - } - ] - }, - { - "id": "99322214695067838", - "slug": "team-vitality", - "name": "Team Vitality", - "code": "VIT", - "image": "http://static.lolesports.com/teams/1675865863968_Vitality_FullColor.png", - "alternativeImage": "http://static.lolesports.com/teams/1675865863970_Vitality_FullColor.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "102787200044335760", - "summonerName": "Carzzy", - "firstName": "Matyǭ��", - "lastName": "Orsǭg", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651395852_carzzy.png" - }, - { - "id": "105503548109547493", - "summonerName": "Lyncas", - "firstName": "Linas", - "lastName": "Naun�?ikas", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652185682_lyncas.png" - }, - { - "id": "107605583684952312", - "summonerName": "Fleshy", - "firstName": "Kadir", - "lastName": "Kemiksiz", - "role": "support", - "image": "http://static.lolesports.com/players/1774651476897_fleshy.png" - }, - { - "id": "107605411481021064", - "summonerName": "Naak Nako", - "firstName": "Kaan", - "lastName": "Okan", - "role": "top", - "image": "http://static.lolesports.com/players/1774652368701_naaknako.png" - }, - { - "id": "100356590519370319", - "summonerName": "Humanoid", - "firstName": "Marek", - "lastName": "Brǭzda", - "role": "mid", - "image": "http://static.lolesports.com/players/1774651500920_humanoid.png" - }, - { - "id": "103935359525547325", - "summonerName": "Lukezy", - "firstName": "Luka", - "lastName": "Trumbic", - "role": "none", - "image": "https://static.lolesports.com/players/download.png" - } - ] - } - ] -} diff --git a/data/lec/seed.teams-players.local.json b/data/lec/seed.teams-players.local.json deleted file mode 100644 index 14751de0a..000000000 --- a/data/lec/seed.teams-players.local.json +++ /dev/null @@ -1,635 +0,0 @@ -{ - "source": "lolesports-api", - "fetchedAt": "2026-04-17T14:51:49.3617167-03:00", - "league": "LEC", - "leagueId": "98767991302996019", - "tournamentId": "115548681802226458", - "teamCount": 10, - "teams": [ - { - "id": "98767991866488695", - "slug": "fnatic", - "name": "Fnatic", - "code": "FNC", - "image": "http://static.lolesports.com/teams/1631819669150_fnc-2021-worlds.png", - "alternativeImage": "http://static.lolesports.com/teams/1592591295310_FnaticFNC-03-FullonLight.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "99322214653265200", - "summonerName": "Upset", - "firstName": "Elias", - "lastName": "Lipp", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652671712_upset.png", - "localImage": "data/lec/images/players/99322214653265200.png" - }, - { - "id": "100238780551262852", - "summonerName": "Razork", - "firstName": "IvÇ­n", - "lastName": "Mart��n", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652486277_razork.png", - "localImage": "data/lec/images/players/100238780551262852.png" - }, - { - "id": "109705412728201213", - "summonerName": "Empyros", - "firstName": "Panagiotis", - "lastName": "Tantis", - "role": "top", - "image": "http://static.lolesports.com/players/1774651449505_empyros.png", - "localImage": "data/lec/images/players/109705412728201213.png" - }, - { - "id": "107045034481599547", - "summonerName": "Vladi", - "firstName": "Vladimiros", - "lastName": "Kourtidis", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652694212_vladi.png", - "localImage": "data/lec/images/players/107045034481599547.png" - }, - { - "id": "107492067202132417", - "summonerName": "Lospa", - "firstName": "Joon Hyung", - "lastName": "Park", - "role": "support", - "image": "http://static.lolesports.com/players/1774652050575_lospa.png", - "localImage": "data/lec/images/players/107492067202132417.png" - } - ], - "localImage": "data/lec/images/teams/fnatic.png" - }, - { - "id": "98767991926151025", - "slug": "g2-esports", - "name": "G2 Esports", - "code": "G2", - "image": "http://static.lolesports.com/teams/G2-FullonDark.png", - "alternativeImage": "http://static.lolesports.com/teams/G2-FullonLight.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "98767975968177297", - "summonerName": "Caps", - "firstName": "Rasmus", - "lastName": "Borregaard Winther", - "role": "mid", - "image": "http://static.lolesports.com/players/1768549998426_Caps-01.png", - "localImage": "data/lec/images/players/98767975968177297.png" - }, - { - "id": "99566406047571736", - "summonerName": "BrokenBlade", - "firstName": "Sergen", - "lastName": "�?elik", - "role": "top", - "image": "http://static.lolesports.com/players/1768550002850_BrokenBlade-01.png", - "localImage": "data/lec/images/players/99566406047571736.png" - }, - { - "id": "98767975961872793", - "summonerName": "Hans Sama", - "firstName": "Steven", - "lastName": "Liv", - "role": "bottom", - "image": "http://static.lolesports.com/players/1768549994123_HansSama-01.png", - "localImage": "data/lec/images/players/98767975961872793.png" - }, - { - "id": "105554439426664062", - "summonerName": "Rodrigo", - "firstName": "Rodrigo", - "lastName": "Domingues Oliveira", - "role": "none", - "image": "http://static.lolesports.com/players/default-headshot.png", - "localImage": "data/lec/images/players/105554439426664062.png" - }, - { - "id": "107128052280762804", - "summonerName": "SkewMond", - "firstName": "Rudy", - "lastName": "Semaan", - "role": "jungle", - "image": "http://static.lolesports.com/players/1768549980779_Skewmond-01.png", - "localImage": "data/lec/images/players/107128052280762804.png" - }, - { - "id": "102787200059605684", - "summonerName": "Labrov", - "firstName": "Labros", - "lastName": "Papoutsakis", - "role": "support", - "image": "http://static.lolesports.com/players/1768549989298_Labrov-01.png", - "localImage": "data/lec/images/players/102787200059605684.png" - } - ], - "localImage": "data/lec/images/teams/g2-esports.png" - }, - { - "id": "101383793572656373", - "slug": "giantx-lec", - "name": "GIANTX", - "code": "GX", - "image": "http://static.lolesports.com/teams/1765897105091_GIANTX-logotype-white.png", - "alternativeImage": "http://static.lolesports.com/teams/1765897105092_GIANTX-logotype-white.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "107464179845128878", - "summonerName": "ISMA", - "firstName": "Isma��l", - "lastName": "Boualem", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774651596907_isma.png", - "localImage": "data/lec/images/players/107464179845128878.png" - }, - { - "id": "103495716738607011", - "summonerName": "Lot", - "firstName": "Eren", - "lastName": "Y��ld��z", - "role": "top", - "image": "http://static.lolesports.com/players/1774652144804_lot.png", - "localImage": "data/lec/images/players/103495716738607011.png" - }, - { - "id": "105501717406803640", - "summonerName": "Noah", - "firstName": "Hyuntaek", - "lastName": "O", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652391494_noah.png", - "localImage": "data/lec/images/players/105501717406803640.png" - }, - { - "id": "105501802535116331", - "summonerName": "Jun", - "firstName": "Sejun", - "lastName": "Yoon", - "role": "support", - "image": "http://static.lolesports.com/players/1774651978347_jun.png", - "localImage": "data/lec/images/players/105501802535116331.png" - }, - { - "id": "105647947016264573", - "summonerName": "Jackies", - "firstName": "Adam", - "lastName": "Je�?Ç­bek", - "role": "mid", - "image": "http://static.lolesports.com/players/1774651628897_jackies.png", - "localImage": "data/lec/images/players/105647947016264573.png" - } - ], - "localImage": "data/lec/images/teams/giantx-lec.png" - }, - { - "id": "111692118851466302", - "slug": "karmine-corp", - "name": "Karmine Corp", - "code": "KC", - "image": "http://static.lolesports.com/teams/1704714951336_KC.png", - "alternativeImage": "http://static.lolesports.com/teams/1704714951337_KC.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "103495716771322725", - "summonerName": "Canna", - "firstName": "Changdong", - "lastName": "Kim", - "role": "top", - "image": "http://static.lolesports.com/players/1774651372836_canna.png", - "localImage": "data/lec/images/players/103495716771322725.png" - }, - { - "id": "108205130709313212", - "summonerName": "kyeahoo", - "firstName": "Yeahoo", - "lastName": "Kang", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652002153_kyeahoo.png", - "localImage": "data/lec/images/players/108205130709313212.png" - }, - { - "id": "106625308523122120", - "summonerName": "Busio", - "firstName": "Alan", - "lastName": "Cwalina", - "role": "support", - "image": "http://static.lolesports.com/players/1774651329556_busio.png", - "localImage": "data/lec/images/players/106625308523122120.png" - }, - { - "id": "105537190986692036", - "summonerName": "Yike", - "firstName": "Martin", - "lastName": "Sundelin", - "role": "jungle", - "image": "http://static.lolesports.com/players/1768550195190_Yike-01.png", - "localImage": "data/lec/images/players/105537190986692036.png" - }, - { - "id": "109461265532592848", - "summonerName": "Caliste", - "firstName": "Caliste", - "lastName": "Henry-Hennebert", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651348279_caliste.png", - "localImage": "data/lec/images/players/109461265532592848.png" - } - ], - "localImage": "data/lec/images/teams/karmine-corp.png" - }, - { - "id": "103461966965149786", - "slug": "mad-lions", - "name": "Movistar KOI", - "code": "MKOI", - "image": "http://static.lolesports.com/teams/1734012609283_MKOI_FullColor_Blue.png", - "alternativeImage": "http://static.lolesports.com/teams/1734012609284_MKOI_FullColor_Blue.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "103877629120745120", - "summonerName": "Elyoya", - "firstName": "Javier", - "lastName": "Prades", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774651428253_elyoya.png", - "localImage": "data/lec/images/players/103877629120745120.png" - }, - { - "id": "110350224593953686", - "summonerName": "Myrwn", - "firstName": "�?lex", - "lastName": "Villarejo Pastor", - "role": "top", - "image": "http://static.lolesports.com/players/1774652336923_myrwn.png", - "localImage": "data/lec/images/players/110350224593953686.png" - }, - { - "id": "103536968833612789", - "summonerName": "Supa", - "firstName": "David", - "lastName": "Mart��nez Garc��a", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652617630_supa.png", - "localImage": "data/lec/images/players/103536968833612789.png" - }, - { - "id": "107564404490889053", - "summonerName": "Alvaro", - "firstName": "Alvaro", - "lastName": "FernÇ­ndez del Amo", - "role": "support", - "image": "http://static.lolesports.com/players/1774651304778_alvaro.png", - "localImage": "data/lec/images/players/107564404490889053.png" - }, - { - "id": "105504920899018806", - "summonerName": "Jojopyun", - "firstName": "Joseph Joon", - "lastName": "Pyun", - "role": "mid", - "image": "http://static.lolesports.com/players/1774651666226_jojopyun.png", - "localImage": "data/lec/images/players/105504920899018806.png" - } - ], - "localImage": "data/lec/images/teams/mad-lions.png" - }, - { - "id": "114868016111590239", - "slug": "natus-vincere", - "name": "Natus Vincere", - "code": "NAVI", - "image": "http://static.lolesports.com/teams/1752746833620_NAVI_FullColor.png", - "alternativeImage": "http://static.lolesports.com/teams/1752746833620_NAVI_FullColor.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "104287359934240404", - "summonerName": "SamD", - "firstName": "Jaehoon", - "lastName": "Lee", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774652529720_samd.png", - "localImage": "data/lec/images/players/104287359934240404.png" - }, - { - "id": "105700869624784693", - "summonerName": "Maynter", - "firstName": "Volodymyr", - "lastName": "Sorokin", - "role": "top", - "image": "http://static.lolesports.com/players/1774652211219_maynter.png", - "localImage": "data/lec/images/players/105700869624784693.png" - }, - { - "id": "105548731617719496", - "summonerName": "Rhilech", - "firstName": "Enes", - "lastName": "U��an", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652507939_rhilech.png", - "localImage": "data/lec/images/players/105548731617719496.png" - }, - { - "id": "107840393299826151", - "summonerName": "Poby", - "firstName": "Sungwon", - "lastName": "Yoon", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652447812_poby.png", - "localImage": "data/lec/images/players/107840393299826151.png" - }, - { - "id": "103805069759346933", - "summonerName": "Parus", - "firstName": "Polat Furkan", - "lastName": "�?i��ek", - "role": "support", - "image": "http://static.lolesports.com/players/1774652426360_parus.png", - "localImage": "data/lec/images/players/103805069759346933.png" - }, - { - "id": "100482247959137902", - "summonerName": "Larssen", - "firstName": "Emil", - "lastName": "Larsson", - "role": "mid", - "image": "http://static.lolesports.com/players/1754473073908_image6331.png", - "localImage": "data/lec/images/players/100482247959137902.png" - } - ], - "localImage": "data/lec/images/teams/natus-vincere.png" - }, - { - "id": "101383793567806688", - "slug": "sk-gaming", - "name": "SK Gaming", - "code": "SK", - "image": "http://static.lolesports.com/teams/1643979272144_SK_Monochrome.png", - "alternativeImage": "http://static.lolesports.com/teams/1643979272151_SK_Monochrome.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "99322214618656216", - "summonerName": "Wunder", - "firstName": "Martin", - "lastName": "Hansen", - "role": "top", - "image": "http://static.lolesports.com/players/1774652747959_wunder.png", - "localImage": "data/lec/images/players/99322214618656216.png" - }, - { - "id": "103889902476986558", - "summonerName": "LIDER", - "firstName": "Adam", - "lastName": "Ilyasov", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652028497_lider.png", - "localImage": "data/lec/images/players/103889902476986558.png" - }, - { - "id": "105553696718837337", - "summonerName": "Jopa", - "firstName": "Josip", - "lastName": "�?an�?ar", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651949013_jopa.png", - "localImage": "data/lec/images/players/105553696718837337.png" - }, - { - "id": "99322214629661297", - "summonerName": "Mikyx", - "firstName": "Mihael", - "lastName": "Mehle", - "role": "support", - "image": "http://static.lolesports.com/players/1774652311878_mikyx.png", - "localImage": "data/lec/images/players/99322214629661297.png" - }, - { - "id": "101389808348806587", - "summonerName": "Skeanz", - "firstName": "Duncan", - "lastName": "Marquet", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652595033_skeanz.png", - "localImage": "data/lec/images/players/101389808348806587.png" - } - ], - "localImage": "data/lec/images/teams/sk-gaming.png" - }, - { - "id": "107563714667537640", - "slug": "team-bds", - "name": "Shifters", - "code": "SHFT", - "image": "http://static.lolesports.com/teams/1765897071435_600px-Shifters_allmode.png", - "alternativeImage": "http://static.lolesports.com/teams/1765897071435_600px-Shifters_allmode.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "105554437688383476", - "summonerName": "nuc", - "firstName": "Ilias", - "lastName": "Bizriken", - "role": "mid", - "image": "http://static.lolesports.com/players/1768550938446_Nuc-01.png", - "localImage": "data/lec/images/players/105554437688383476.png" - }, - { - "id": "107767810249714879", - "summonerName": "Rooster", - "firstName": "Yunhwan", - "lastName": "Shin", - "role": "top", - "image": "http://static.lolesports.com/players/1768550928914_Rooster-01.png", - "localImage": "data/lec/images/players/107767810249714879.png" - }, - { - "id": "105515296576479523", - "summonerName": "Boukada", - "firstName": "Lahlou", - "lastName": "Mehdi", - "role": "jungle", - "image": "http://static.lolesports.com/players/1768550943317_Boukada-01.png", - "localImage": "data/lec/images/players/105515296576479523.png" - }, - { - "id": "107492114500277895", - "summonerName": "Paduck", - "firstName": "Seokhyeon", - "lastName": "Park", - "role": "bottom", - "image": "http://static.lolesports.com/players/1768550934005_Paduck-01.png", - "localImage": "data/lec/images/players/107492114500277895.png" - }, - { - "id": "102181528883745160", - "summonerName": "Trymbi", - "firstName": "Adrian", - "lastName": "Trybus", - "role": "support", - "image": "http://static.lolesports.com/players/1768550915779_Trymbi-01.png", - "localImage": "data/lec/images/players/102181528883745160.png" - }, - { - "id": "107455908655055017", - "summonerName": "JuJuTw0", - "firstName": "Julien", - "lastName": "IZZO", - "role": "none", - "image": "http://static.lolesports.com/players/1639647042551_placeholder.png", - "localImage": "data/lec/images/players/107455908655055017.png" - } - ], - "localImage": "data/lec/images/teams/team-bds.png" - }, - { - "id": "109637393694097670", - "slug": "team-heretics-lec", - "name": "Team Heretics", - "code": "TH", - "image": "http://static.lolesports.com/teams/1672933861879_Heretics-Full-Color.png", - "alternativeImage": "http://static.lolesports.com/teams/1672933861879_Heretics-Full-Color.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "105830645287286396", - "summonerName": "Sheo", - "firstName": "ThǸo", - "lastName": "Borile", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652573563_sheo.png", - "localImage": "data/lec/images/players/105830645287286396.png" - }, - { - "id": "107156544177574787", - "summonerName": "Tracyn", - "firstName": "Sebastian", - "lastName": "Wojto�?", - "role": "top", - "image": "http://static.lolesports.com/players/1774652650240_tracyn.png", - "localImage": "data/lec/images/players/107156544177574787.png" - }, - { - "id": "105501834624360050", - "summonerName": "Ice", - "firstName": "Sang-hoon", - "lastName": "Yoon", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651565551_ice.png", - "localImage": "data/lec/images/players/105501834624360050.png" - }, - { - "id": "102174699705191142", - "summonerName": "Serin", - "firstName": "Tolga", - "lastName": "�?lmez", - "role": "mid", - "image": "http://static.lolesports.com/players/1774652550234_serin.png", - "localImage": "data/lec/images/players/102174699705191142.png" - }, - { - "id": "107621095379170267", - "summonerName": "Daglas", - "firstName": "Kacper", - "lastName": "Dagiel", - "role": "jungle", - "image": "http://static.lolesports.com/players/1705027284789_daglas.png", - "localImage": "data/lec/images/players/107621095379170267.png" - }, - { - "id": "107492119089043087", - "summonerName": "Way", - "firstName": "Han", - "lastName": "Kil", - "role": "support", - "image": "http://static.lolesports.com/players/1774652723449_way.png", - "localImage": "data/lec/images/players/107492119089043087.png" - } - ], - "localImage": "data/lec/images/teams/team-heretics-lec.png" - }, - { - "id": "99322214695067838", - "slug": "team-vitality", - "name": "Team Vitality", - "code": "VIT", - "image": "http://static.lolesports.com/teams/1675865863968_Vitality_FullColor.png", - "alternativeImage": "http://static.lolesports.com/teams/1675865863970_Vitality_FullColor.png", - "homeLeague": "LEC", - "region": "EMEA", - "players": [ - { - "id": "102787200044335760", - "summonerName": "Carzzy", - "firstName": "Matyǭ��", - "lastName": "OrsÇ­g", - "role": "bottom", - "image": "http://static.lolesports.com/players/1774651395852_carzzy.png", - "localImage": "data/lec/images/players/102787200044335760.png" - }, - { - "id": "105503548109547493", - "summonerName": "Lyncas", - "firstName": "Linas", - "lastName": "Naun�?ikas", - "role": "jungle", - "image": "http://static.lolesports.com/players/1774652185682_lyncas.png", - "localImage": "data/lec/images/players/105503548109547493.png" - }, - { - "id": "107605583684952312", - "summonerName": "Fleshy", - "firstName": "Kadir", - "lastName": "Kemiksiz", - "role": "support", - "image": "http://static.lolesports.com/players/1774651476897_fleshy.png", - "localImage": "data/lec/images/players/107605583684952312.png" - }, - { - "id": "107605411481021064", - "summonerName": "Naak Nako", - "firstName": "Kaan", - "lastName": "Okan", - "role": "top", - "image": "http://static.lolesports.com/players/1774652368701_naaknako.png", - "localImage": "data/lec/images/players/107605411481021064.png" - }, - { - "id": "100356590519370319", - "summonerName": "Humanoid", - "firstName": "Marek", - "lastName": "BrÇ­zda", - "role": "mid", - "image": "http://static.lolesports.com/players/1774651500920_humanoid.png", - "localImage": "data/lec/images/players/100356590519370319.png" - }, - { - "id": "103935359525547325", - "summonerName": "Lukezy", - "firstName": "Luka", - "lastName": "Trumbic", - "role": "none", - "image": "https://static.lolesports.com/players/download.png", - "localImage": "data/lec/images/players/103935359525547325.png" - } - ], - "localImage": "data/lec/images/teams/team-vitality.png" - } - ] -} diff --git a/docs/ANALISIS_PROYECTO.md b/docs/ANALISIS_PROYECTO.md new file mode 100644 index 000000000..be1039268 --- /dev/null +++ b/docs/ANALISIS_PROYECTO.md @@ -0,0 +1,688 @@ +# OLManager — Análisis Exhaustivo del Proyecto + +**Fecha:** 08-MAY-2026 +**Versión del Proyecto:** 0.2.0 (Pre-alpha) +**Licencia:** GPL-3.0 +**Repositorio:** https://github.com/OpenLeagueManager/OLManager + +--- + +## 1. Resumen General & Propósito + +OLManager (Open League Manager) es un **juego desktop de gestión de equipos de esports (League of Legends)** construido con **Tauri v2**, **React 19 + TypeScript** en el frontend y un **workspace Rust** en el backend. Es el sucesor espiritual de OpenFootManager, migrando de fútbol a League of Legends. + +### Stack Tecnológico Principal + +| Capa | Tecnología | Versión | +|------|-----------|---------| +| Desktop shell | Tauri v2 | ^2.10 | +| Frontend | React + TypeScript | ^19.2 / ~6.0 | +| Bundler | Vite | ^8.0 | +| CSS | Tailwind CSS 4 | ^4.2 | +| Backend | Rust (edition 2024) | 1.80+ | +| Base de datos | SQLite (rusqlite) | 0.32.1 | +| Estado frontend | Zustand | ^5.0 | +| Routing | react-router-dom | ^7.14 | +| i18n | i18next | ^26.0 | +| Testing frontend | Vitest + Testing Library | ^4.1 / ^16.3 | +| Testing Rust | cargo test | — | + +**Archivos clave:** +- `package.json` — Define scripts, dependencias, versión +- `src-tauri/Cargo.toml` — Define workspace Rust con 4 crates + binario +- `README.md` — Visión general, arquitectura, convenciones +- `docs/ARCHITECTURE.md` — Documentación técnica detallada + +--- + +## 2. Arquitectura — Deep Dive + +### 2.1 Diagrama de Arquitectura General + +``` +┌─────────────────────────────────────────────────────┐ +│ FRONTEND (React 19 + TS 6.0 + Vite 8) │ +│ │ +│ Pages ─── Components ─── Services ─── Stores/Zustand│ +│ │ │ +│ Hooks ─── lib/utils ─── i18n ────────┤ │ +│ │ Tauri IPC │ +├────────────────────────────────────────┼─────────────┤ +│ BACKEND (Rust workspace) │ │ +│ ▼ │ +│ Commands (thin handlers) ─── Application Services │ +│ │ │ +│ ┌────┴─────────────────────────────────────┐ │ +│ │ ofm_core (orquestación de juego) │ │ +│ │ ┌──────┐ ┌──────┐ ┌────────┐ │ │ +│ │ │domain│ │engine│ │ db │ │ │ +│ │ └──────┘ └──────┘ └────────┘ │ │ +│ └──────────────────────────────────────────┘ │ +│ │ +│ StateManager (Mutex) + SaveManager │ +└─────────────────────────────────────────────────────┘ +``` + +### 2.2 Frontend Architecture + +#### Estructura de directorios (`src/`) + +| Directorio | Propósito | +|-----------|-----------| +| `pages/` | 5 screens principales (MainMenu, TeamSelection, Dashboard, MatchSimulation, Settings) + ChampionPage, WorldEditor | +| `components/` | ~36 subdirectorios de feature (dashboard/, match/, squad/, training/, transfers/, scouting/, scrims/, etc.) | +| `services/` | 10 wrappers tipados sobre `invoke()` de Tauri | +| `store/` | 2 stores Zustand (gameStore, settingsStore) + types masivos | +| `hooks/` | useAdvanceTime, useUpdater, useScrimContextWithFallback | +| `lib/` | 36 archivos de utilidades/lógica de frontend | +| `i18n/` | Config i18next + 8 locales (en, es, pt, fr, de, it, pt-BR, tr) | +| `context/` | ThemeContext (dark/light/system) | +| `content/` | Social content system (lol/social/) | +| `utils/` | Backend i18n bridge utilities | + +#### Routing (App.tsx) + +```typescript + + + } /> + } /> + } /> + } /> + } /> + + +``` + +Todas las rutas usan **`lazy()` + `Suspense`** para code-splitting automático. Además bloquea la navegación por botones de retroceso/adelante del navegador (típico en apps Tauri). + +#### State Management + +**Zustand** con dos stores: + +- **`gameStore.ts`**: Estado de la sesión de juego (hasActiveGame, managerName, gameState, isDirty). El `gameState` es un objeto masivo `GameStateData` (~843 líneas de tipos) que contiene TODO el estado del juego serializado desde Rust. Esto significa que **todo el game state viaja completo por IPC** en cada respuesta. + +- **`settingsStore.ts`**: Configuración de la app (tema, idioma, moneda, match speed, etc.). Persiste via `invoke("save_settings")` al backend. + +#### Service Layer (IPC Boundary) + +Los `services/` son wrappers tipados sobre `invoke()` de Tauri. Cada servicio es responsable de un área funcional: + +- `academyService.ts` — Normaliza respuestas del backend (BackendAcademyAcquisitionOption → AcademyAcquisitionOptionData) +- `transfersService.ts` — Transfer bids, counter-offers, contract releases +- `playerService.ts` — Potential research, champion training +- `trainingService.ts` — Training focus, schedules, groups +- `staffService.ts` — Hire/release staff +- `scoutingService.ts` — Send scouts, scouting assignments +- `inboxService.ts` — Messages CRUD +- `advanceTimeService.ts` — Time advancement +- `socialService.ts` — Social feed +- `jobService.ts` — Job applications + +**Patrón clave:** Los servicios devuelven `Promise` típicamente, lo que significa que **casi toda mutación en el backend retorna el game state completo**. + +### 2.3 Backend Architecture + +#### Rust Workspace Structure + +``` +src-tauri/ +├── Cargo.toml # Workspace root + bin/lib +├── src/ +│ ├── main.rs # Entry point +│ ├── lib.rs # Plugin setup, state management, command registration +│ ├── error.rs # AppError enum (8 variantes) +│ ├── commands/ # 21 módulos de comandos Tauri +│ └── application/ # Orchestación (time_advancement, lol_sim_v2, team_talk) +└── crates/ + ├── domain/ # Tipos de dominio puros (sin Tauri/SQLite) + ├── engine/ # Simulación de partidos (pura, sin I/O) + ├── ofm_core/ # Lógica de gameplay (Game, StateManager, turnos) + └── db/ # Persistencia SQLite (migrations, repositories) +``` + +#### `domain` crate + +15 módulos con tipos serializables: +- `player.rs` (667 lines) — Player, PlayerAttributes, PlayerTrait enum (16 traits), ContractRenewalState, PlayerMoraleCore, TransferOffer +- `team.rs` (1266 lines) — Team, AcademyMetadata, Facilities, TrainingFocus/Groups, ScrimReports, LolTactics (6 dimensiones: strong_side, game_timing, jungle_style, jungle_pathing, fight_plan, support_roaming) +- `stats.rs` (278 lines) — LolRole con deserialización personalizada que mapea posiciones legacy de fútbol → LoL +- `manager.rs`, `league.rs`, `champion.rs`, `champion_stats.rs`, `staff.rs`, `message.rs`, `news.rs`, `social.rs`, `negotiation.rs`, `season.rs`, `identity.rs` + +**Feature flag `typescript`**: Usa `ts-rs` para generar tipos TypeScript automáticamente desde los structs Rust. Esto es **brutal para mantener la sync** frontend/backend. + +#### `engine` crate + +Simulación de partidos LoL pura: +- `types.rs` — PlayerData, TeamData, MatchConfig, Side, Zone (con lógica de avance de zona) +- `live_match/` — Simulation state machine, snapshot system, LoL map walls (JSON) +- `engine/mod.rs` — `simulate_lol()` función principal +- `event.rs` — MatchEvent, EventType +- `report.rs` — MatchReport, KillDetail, PlayerMatchStats +- `ai.rs` — AI opponent behavior + +El match simulator tiene un sistema de zonas (HomeBox → HomeDefense → Midfield → AwayDefense → AwayBox) con lógica de avance/retroceso. + +#### `ofm_core` crate + +43 módulos que contienen TODA la lógica de gameplay: +- `state.rs` — `StateManager` con `Mutex` (single-lock pattern para evitar deadlocks) +- `game.rs` — `Game` struct principal +- `turn/` — Sistema de turnos (mod.rs, post_match.rs, round_summary.rs, news.rs) +- `transfers.rs` (2104 lines) — Sistema de transferencias completo con negociación +- `training/` — Sistema de entrenamiento con fitness_warnings +- `scrim_flow.rs` — Flujo de scrims +- `generator/` — Generación de mundo (world_io, generation, definitions, data) +- `player_events/`, `random_events/`, `narrative/` — Sistemas de eventos narrativos +- `live_match_manager/` — Coordinación de partidos en vivo +- `social.rs`, `social_registry.rs`, `social_templates.rs` — Sistema social + +#### `db` crate + +Persistencia SQLite: +- `migrations.rs` — 52 migraciones (V1 a V51) usando `rusqlite_migration` +- `repositories/` — 15 repositorios (player_repo, team_repo, manager_repo, league_repo, etc.) +- `game_database.rs` — Abre/crea bases de datos por save, aplica migraciones +- `game_persistence.rs` — Reader/Writer para serializar/deserializar Game completo +- `save_manager.rs` (1280 lines) — Gestión completa de saves (crear, cargar, guardar, borrar, migrar) +- `save_index.rs` / `save_index_manager.rs` — Índice de saves con checksums +- `legacy_migration.rs` — Migración de saves legacy de OpenFootManager +- `sql/` — 48 archivos SQL (algunos orfanos, comentarios en migrations.rs) + +### 2.4 Tauri Bridge + +#### Commands registrados (lib.rs) + +**~100+ comandos** Tauri agrupados en 21 módulos: + +| Módulo | Comandos clave | +|--------|---------------| +| `game` | start_new_game, load_game, get_active_game, save_game, exit_to_menu | +| `time` | advance_time, advance_time_with_mode, skip_to_match_day | +| `club` | select_team, set_formation, set_play_style, upgrade_facility | +| `squad` | set_active_lineup, set_starting_xi, set_lol_tactics, set_team_roles | +| `transfers` | make_transfer_bid, respond_to_offer, counter_offer, toggle_transfer_list | +| `contracts` | propose_renewal, delegate_renewals, release_player_contract | +| `training` | set_training, set_training_schedule, set_training_groups, set_player_training_focus | +| `scouting` | send_scout, get_academy_acquisition_options, acquire_academy_team | +| `scrims` | set_weekly_scrims, finalize_weekly_scrim_setup, choose_post_scrim_decision | +| `staff` | hire_staff, release_staff | +| `academy` | promote_academy_player, create_academy | +| `live_match` | start_live_match, step_live_match, apply_match_command, finish_live_match | +| `season` | advance_to_next_season, check_season_complete, get_season_awards | +| `social` | get_social_feed, create_manager_social_post, get_social_accounts | +| `lol_sim_v2` | lol_sim_v2_init, lol_sim_v2_tick (simulación detallada LoL) | +| `settings` | get_settings, save_settings | +| `champion` | get_champions, seed_champions_from_json | +| `stats` | get_player_match_history, get_player_stats_overview, get_team_stats | + +#### Managed State + +```rust +// lib.rs +.manage(StateManager::new()) // ofm_core::state (Mutex) +.manage(LolSimV2StoreState::default()) // lol_sim_v2 state +.setup(|app| { + let save_manager = SaveManager::init(...)?; + app.manage(SaveManagerState(Mutex::new(save_manager))); +}) +``` + +#### Error Handling + +`AppError` enum con 8 variantes tipadas y códigos i18n: +```rust +pub enum AppError { + SaveNotFound(String), // "SAVE_NOT_FOUND" + Database(String), // "DATABASE_ERROR" + Validation(String), // "VALIDATION_ERROR" + Session(String), // "SESSION_ERROR" + Lock(String), // "LOCK_ERROR" + Io(String), // "IO_ERROR" + NotFound(String), // "NOT_FOUND" + Conflict(String), // "CONFLICT" + Generic(String), // "GENERIC_ERROR" +} +``` + +Implementa `From` y `From<&str>` para usar `?` en comandos. + +--- + +## 3. Calidad de Código & Patrones + +### 3.1 TypeScript + +**Strict mode habilitado:** +```json +{ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true +} +``` + +**TypeScript 6.0** — bleeding edge. Esto es risky porque TS 6.0 es muy reciente y puede tener breaking changes o bugs. + +**Type safety patterns:** +- Tipos de dominio completos en `store/types.ts` (843 líneas) +- Servicios con tipos de entrada/salida explícitos +- Normalización de respuestas del backend en servicios (ej: `academyService.ts` mapea `BackendAcademyAcquisitionOption` → `AcademyAcquisitionOptionData`) +- Zod ^4.4.2 disponible pero no parece usado extensivamente todavía +- `LegacyCompatibilityValue = any` para campos legacy — esto ES un escape hatch + +### 3.2 Rust + +**Edition 2024** — muy moderna, recién estabilizada. Consistentemente usada en los 4 crates. + +**Error handling patterns:** +- `thiserror` v2 para `AppError` en el crate principal +- En los crates de dominio: errores simples con `String` returns +- `StateManager::with_session()` y `with_session_mut()` — patrón de función closure para acceso sincronizado + +**Clean architecture separation:** +- `domain` → NO dependencies pesadas (solo serde, log) +- `engine` → NO dependencies de dominio ni db +- `ofm_core` → Depende de domain + engine +- `db` → Depende de domain + ofm_core + +**Clippy warnings suprimidos** en domain (derivable_impls) y engine (new_without_default, collapsible_if, useless_conversion) — tracking en issue #92. + +### 3.3 Testing Strategy + +#### Frontend (Vitest + jsdom + Testing Library) + +**117 archivos de test** reportados según `README.md`. Distribución: + +| Área | Tests encontrados | +|------|-----------------| +| `components/` | ~85 (dashboard, match, training, transfers, scrims, home, squad, staff, scouting, ui, etc.) | +| `lib/` | ~12 (finance, helpers, scrimContext, lolScrimPrep, lolPlayerStats, etc.) | +| `services/` | ~9 (academy, advanceTime, inbox, player, scouting, staff, training, transfers) | +| `store/` | ~4 (gameStore, settingsStore, academySelectors, academyContracts) | +| `pages/` | ~3 (Dashboard, MainMenu, MatchSimulation) | +| `hooks/` | ~1 (useAdvanceTime) | +| `content/` | ~6 (social schema, selectors, matchContext, guard, content, i18nCoverage) | +| `utils/` | ~3 (backendI18n, playerEvents, localeCoverage) | +| `context/` | ~1 (ThemeContext) | +| `i18n/` | ~1 (footballTermGuard) | + +**Setup:** `src/test-setup.ts` importa `@testing-library/jest-dom/vitest`. Config en `vite.config.ts`: +- Environment: jsdom +- Globals: true +- Coverage excluye locales y test files + +#### Rust (cargo test) + +**22 archivos de test** (integración): + +| Crate | Tests de integración | +|-------|---------------------| +| `ofm_core/tests/` | 18 (academy, club, contracts, end_of_season, finances, live_match_manager, messages, narrative_*, player_events, random_events, scouting, scrim_flow, training, transfers, turn) | +| `engine/tests/` | 2 (simulation_tests, live_match_tests) | +| `db/tests/` | 1 (academy_team_persistence) | +| `domain/` | Inline tests en player.rs, team.rs, identity.rs | + +**Patrón de test en Rust:** Los tests de ofm_core usan `#[test]` directos con fixtures inline. Los tests de engine simulan partidos completos. db tests usan `tempfile` para bases de datos temporales. + +### 3.4 Observaciones sobre Testing + +✅ **Bueno:** Tests colocalizados, cobertura amplia en componentes, testing de stores y servicios. +⚠️ **Precaución:** Muchos tests de componentes probablemente son snapshot/shallow — habría que verificar la profundidad. +⚠️ **Missing:** `cargo test` para el crate principal `openleaguemanager` está comentado en CI (ver `pr.yml` línea 75-77: "tests blocked by lol_sim_v2.rs"). +⚠️ **CI:** `cargo clippy` y `cargo fmt` corren con `continue-on-error: true` — no blocking. + +--- + +## 4. Features & Módulos Principales + +### 4.1 Features Identificadas + +| Feature | Frontend | Backend | Estado | +|---------|----------|---------|--------| +| **Main Menu** | `MainMenu.tsx` | `commands/game.rs` | ✅ | +| **Team Selection** | `TeamSelection.tsx` | `select_team` command | ✅ | +| **Dashboard** | `Dashboard.tsx` + 20 subcomponentes | Multiple commands | ✅ | +| **Gestión de Plantel** | `SquadTab` + players/ | `set_active_lineup`, etc. | ✅ | +| **Tácticas LoL** | `TacticsTab` | `set_lol_tactics`, `set_play_style` | ✅ | +| **Entrenamiento** | `TrainingTab` + TrainingGroups | `set_training*` | ✅ | +| **Scrims** | `ScrimsTab` | `scrim_flow.rs` (complejo) | ✅ | +| **Transferencias** | `TransfersTab` | `transfers.rs` (2104 lines) | ✅ | +| **Renovaciones** | Contract components | `contracts.rs`, `delegated_renewals.rs` | ✅ | +| **Scouting** | `ScoutingTab` | `scouting.rs` | ✅ | +| **Academia** | `YouthAcademyTab` | `academy.rs` | ✅ | +| **Staff** | `StaffTab` | `hire_staff`, `release_staff` | ✅ | +| **Finanzas** | `FinancesTab` | `finances.rs` | ✅ | +| **Partidos en Vivo** | `MatchSimulation.tsx` + LolMatchLive | `live_match_manager/` + `engine/` | ✅ | +| **Simulación Detallada LoL** | `LolLiveMap.tsx` | `lol_sim_v2/` (6376 lines!) | 🟡 Complejo | +| **Inbox/Mensajes** | `InboxTab` | `messages.rs` | ✅ | +| **Noticias** | `NewsTab` | `news.rs` + `news/` | ✅ | +| **Social Feed** | Social components | `social.rs`, `social_registry.rs` | ✅ | +| **Calendario** | `ScheduleTab` | `schedule.rs` | ✅ | +| **Tournament/Playoffs** | `TournamentsTab` | Fixture system | ✅ | +| **Season Progression** | Season context | `turn/`, `end_of_season.rs`, `season_awards.rs` | ✅ | +| **Board Objectives** | Board components | `board_objectives.rs` | ✅ | +| **Champion Stats** | `ChampionPage.tsx` | `champion_stats.rs` | 🟡 | +| **World Editor** | `WorldEditor.tsx` | `generator/` | 🟡 | +| **Updater** | `UpdateModal` | Tauri updater plugin | ✅ | +| **Configuración** | `Settings.tsx` | `commands/settings.rs` | ✅ | +| **Tema** | ThemeContext + CSS | — | ✅ | +| **i18n** | 8 idiomas | `backendI18n.ts` bridge | ✅ | +| **Manager Profile** | `ManagerTab` | Avatar save/load | ✅ | +| **Job Offers** | Job cards | `job_offers.rs` | ✅ | + +### 4.2 Sistema Social (Content) + +El sistema de contenido social en `src/content/lol/social/` es impresionante: +- `schema.ts` + `guard.ts` — Validación de contenido +- `content.ts` — Generación de posts +- `conversations.json`, `events.json`, `news.json`, `outlets.json`, `personas.json`, `questions.json`, `responses.json` — Datos de contenido +- `matchContext.ts` — Contexto de partido para contenido +- `selectors.ts` — Selectores de contenido + +--- + +## 5. Dependencias & Tech Choices + +### 5.1 Frontend (package.json) + +| Dependencia | Versión | Propósito | +|------------|---------|-----------| +| `@tauri-apps/api` | ^2.11.0 | IPC bridge | +| `@tauri-apps/plugin-opener` | ^2 | Abrir URLs externas | +| `@tauri-apps/plugin-updater` | ^2.10.1 | Auto-updater | +| `react` | ^19.2.4 | UI framework | +| `react-router-dom` | ^7.14.0 | Routing | +| `zustand` | ^5.0.12 | State management | +| `zod` | ^4.4.2 | Schema validation | +| `i18next` + `react-i18next` | ^26.0 / ^17.0 | i18n | +| `lucide-react` | ^1.7.0 | Iconos | +| `country-flag-icons` | ^1.6.15 | Banderas | +| `i18n-iso-countries` | ^7.14.0 | Códigos de país | +| `@fontsource/barlow-condensed` | ^5.2.8 | Fuente headings | +| `@fontsource/inter` | ^5.2.8 | Fuente cuerpo | + +**Dev Dependencies:** + +| Dependencia | Versión | Propósito | +|------------|---------|-----------| +| `vite` | ^8.0.5 | Bundler | +| `@vitejs/plugin-react` | ^6.0.1 | React Fast Refresh | +| `tailwindcss` + `@tailwindcss/vite` | ^4.2.2 | CSS utility-first | +| `typescript` | ~6.0.2 | Type checking | +| `vitest` + `@vitest/coverage-v8` | ^4.1.2 | Testing | +| `@testing-library/react` | ^16.3.2 | Component testing | +| `@testing-library/jest-dom` | ^6.9.1 | DOM matchers | +| `jsdom` | ^29.0.1 | DOM environment | +| `sharp` | ^0.34.5 | Image processing | +| `@tauri-apps/cli` | ^2.11.0 | Tauri CLI | + +### 5.2 Backend (Cargo.toml + Crates) + +| Crate | Versión | Propósito | +|-------|---------|-----------| +| `tauri` | 2.10 | Desktop framework | +| `tauri-plugin-opener` | 2 | Open URLs | +| `tauri-plugin-log` | 2 | Logging | +| `tauri-plugin-updater` | 2 | Auto-update | +| `serde` + `serde_json` | 1 | Serialization | +| `rusqlite` | 0.32.1 | SQLite (bundled) | +| `rusqlite_migration` | 1.3 | Schema migrations | +| `chrono` | 0.4.44 | Date/time | +| `rand` | 0.10 | RNG | +| `uuid` | 1.21 | UUID generation | +| `base64` | 0.22 | Base64 encoding | +| `thiserror` | 2 | Error derive | +| `validator` | 0.19 | Input validation | +| `sha2` | 0.11 | Checksums | +| `ts-rs` | 10 | Rust→TS type generation | +| `log` | 0.4 | Logging facade | + +### 5.3 Vite Config + +```typescript +// Manual chunk splitting inteligente +manualChunks: { + "react-vendor": react, react-dom, scheduler + "router": react-router-dom + "tauri": @tauri-apps/* + "i18n": i18next/* + "icons": lucide-react +} +``` + +Tauri-specific config: +- Puerto fijo 1420, strictPort: true +- HMR via ws cuando TAURI_DEV_HOST está seteado +- Ignora src-tauri/ en watch + +### 5.4 Tauri Config + +```json +{ + "windows": [{ "width": 1280, "height": 800, "minWidth": 960, "minHeight": 640 }], + "security": { "csp": null }, // 👀 CSP deshabilitado + "bundle": { + "resources": ["databases/lec_world.json"], + "createUpdaterArtifacts": true + }, + "plugins": { + "updater": { + "pubkey": "...", + "endpoints": ["https://github.com/.../latest.json"] + } + } +} +``` + +--- + +## 6. Build & Development Workflow + +### Scripts disponibles + +| Script | Comando | Propósito | +|--------|---------|-----------| +| `npm run dev` | `vite` | Dev server (Tauri inyecta `npm run dev` como beforeDevCommand) | +| `npm run build` | `vite build` | Build frontend | +| `npm run build:types` | `tsc -p tsconfig.release.json` | Type check sin emit | +| `npm test` | `vitest run` | Tests frontend | +| `npm run tauri` | `tauri` | Tauri CLI passthrough | + +### CI/CD (GitHub Actions) + +**PR Workflow** (`.github/workflows/pr.yml`): +1. `frontend-install` — npm ci +2. `rust-check` — cargo fmt, cargo check, clippy (continue-on-error), cargo test (core crates only) +3. `security-audit` — npm audit (high+), cargo audit +4. `frontend-full` — npm test, npm run build:types +5. `rust-full` — cargo clippy (continue-on-error), cargo test (core crates) + +**⚠️ Notables en CI:** +- `cargo test` del crate principal está saltado por un bloqueo en `lol_sim_v2.rs` (línea 75-77) +- `cargo clippy` corre con `continue-on-error: true` en ambos jobs +- `cargo fmt` corre con `continue-on-error: true` +- `npm audit` con `continue-on-error: true` + +--- + +## 7. Data Layer + +### 7.1 SQLite Schema + +**52 migraciones** desde V1 hasta V51, gestionadas con `rusqlite_migration`. + +**Tablas principales:** +- `game_meta` — Metadata del juego (current_date, day_phase, etc.) +- `managers` — Manager profile + career stats +- `teams` — Teams con facilities, scrims, tácticas, finances (JSON columns) +- `players` — Players con attributes, contract, morale_core, potential +- `staff` — Staff members +- `league` — League metadata +- `fixtures` — Fixture schedule with best_of +- `standings` — League standings +- `messages` — In-game messages (i18n keys) +- `news` — News articles +- `social_posts` — Social feed +- `social_accounts` — Social accounts +- `social_templates` — Social post templates +- `board_objectives` — Board objectives +- `scouting_assignments` — Active scouting +- `lol_player_match_stats` — Player match statistics +- `lol_team_match_stats` — Team match statistics +- `champion_progression_state` — Champion mastery/patch state +- `champions` — LoL champion data + +**Patrón de migraciones:** Usan hooks con `add_column_if_missing()` para idempotencia. Algunas migraciones usan `CREATE TABLE AS` para "dropear" columnas (SQLite no soporta DROP COLUMN nativamente en versiones anteriores). + +### 7.2 Save System + +- Per-save SQLite database: cada save es un archivo `.db` separado +- `SaveManager` con caché de conexiones (`game_db_cache: HashMap>>`) +- `SaveIndexManager` para listar/metadatos de saves +- Checksums con SHA2 para integridad +- Legacy migration desde formato anterior (OpenFootManager) + +### 7.3 Scraping & Data Generation + +**`scraper/src/stats.ts`**: Script de generación determinista de stats de jugadores. Espeja el algoritmo Rust `build_lol_stats_from_seed()`: +- Hash del IGN del jugador +- Role bias matrix (Top/Jungle/Mid/Adc/Support → 9 stats) +- Normalización a target 70 + +**`scripts/`**: Scripts de Node.js + PowerShell para: +- `download-lol-item-icons.mjs` — Descarga de assets +- `fetch-leaguepedia-dobs.mjs` — Datos de jugadores reales +- `generate-lec-world.mjs` — Generación de mundo LEC +- `generate-lol-map-icons.ps1` — Iconos de mapa + +**`data/`**: Datos del mundo (lec/, erls/) + +--- + +## 8. Potenciales Issues & Áreas de Mejora + +### 8.1 Arquitectura + +🔴 **GameState completo via IPC**: Cada respuesta de comando incluye `GameStateData` completo. Esto puede ser un problema de performance cuando el estado crezca. Considerar actualizaciones incrementales o partial updates. + +🔴 **`lol_sim_v2.rs` es MASIVO**: 6376 líneas en un solo archivo. Esto está bloqueando `cargo test` del crate principal. Necesita ser refactorizado en módulos más pequeños. + +🔴 **`transfers.rs` es muy grande**: 2104 líneas. Podría beneficiarse de división en submódulos. + +🟡 **`team.rs` en domain es enorme**: 1266 líneas. La estructura `Team` tiene ~50 campos. Considerar split en sub-entidades. + +🟡 **`store/types.ts` es MASIVO**: 843 líneas con tipos duplicados entre frontend y backend. Si bien `ts-rs` ayuda, la duplicación manual persiste. + +### 8.2 Code Quality + +🟡 **`any` leak**: `LegacyCompatibilityValue = any` se usa como escape hatch en varios tipos. Esto rompe type safety. + +🟡 **Clippy warnings suprimidos**: `#![allow(clippy::*)]` en domain y engine es técnicamente deuda técnica (tracked en #92, pero no resuelto). + +🟡 **Rust edition 2024**: Muy reciente, puede tener problemas de compatibilidad con algunos crates. Monitorear. + +✅ **Positivo**: `ts-rs` feature flag para generación automática de tipos TypeScript es una práctica excelente para mantener sync. + +### 8.3 Security + +🔴 **CSP deshabilitado**: `"csp": null` en tauri.conf.json. Esto significa que no hay Content Security Policy, lo que expone a XSS si hay vulnerabilidades en el frontend. + +🟡 **npm audit en CI**: Corre pero con `continue-on-error: true`, lo que significa que no bloquea PRs con vulnerabilidades conocidas. + +🟡 **cargo audit en CI**: Misma situación, corre pero no bloquea. + +✅ **Positivo**: Política de seguridad documentada en `SECURITY.md`, proceso de reporting privado, y guías sobre secrets. + +### 8.4 Testing + +🔴 **Tests del crate principal bloqueados**: `cargo test` para el binario no corre en CI por `lol_sim_v2.rs`. Esto significa que los comandos Tauri en sí no tienen cobertura de tests automatizados en CI. + +🟡 **continue-on-error generalizado**: Clippy, fmt, y auditorías de seguridad no bloquean el CI. Esto puede dejar pasar problemas. + +🟡 **Muchos tests de componentes**: 117 archivos de test es impresionante, pero habría que verificar la calidad/profundidad. Tests solo de render vs. tests de interacción/comportamiento. + +✅ **Muy positivo**: Tests de migrations con verificación de idempotencia y esquema. + +### 8.5 Migraciones & Schema + +🟡 **SQL orphan files**: En `sql/` hay archivos que no se usan directamente como migraciones (ej: `v028_avatar_path.sql`, `v029_profile_image_urls.sql`, `v030_nationality_code_migration.sql`, `v035_stadium_to_arena.sql`, `v036_stadium_to_arena_capacity.sql`, `v040_cleanup_teams_legacy.sql`). Los hooks en `migrations.rs` hacen el trabajo real. + +🟡 **JSON columns**: Múltiples columnas JSON (facilities, scrim_reports, team_roles, etc.). SQLite no tiene soporte nativo de JSON como PostgreSQL, lo que complica queries. + +### 8.6 Misceláneo + +🟡 **`rand` v0.10**: Bastante nuevo. Verificar compatibilidad con otros crates. + +🟡 **README.md tiene contenido de la rama `QoL-UI-2`** mezclado con la documentación principal (sección 9). Esto parece un merge residual. + +✅ **Excelente documentación técnica**: ARCHITECTURE.md, GOVERNANCE.md, DATA_PROVENANCE.md, ADRs, etc. Muy completo para un proyecto pre-alpha. + +✅ **Issue-first contribution model**: Bien documentado en CONTRIBUTING.md + templates de GitHub. + +--- + +## 9. Security Considerations + +### 9.1 Audit Setup + +- **npm audit**: Corre en CI con `--audit-level=high --omit=dev`, pero `continue-on-error: true` +- **cargo audit**: Corre con `--deny warnings`, pero `continue-on-error: true` también +- **No hay dependabot** configurado visiblemente +- **No hay CodeQL** ni análisis SAST + +### 9.2 Code-Level Security + +| Aspecto | Estado | Detalle | +|---------|--------|---------| +| CSP | 🔴 Deshabilitado | `"csp": null` — sin protección XSS | +| Input validation | 🟡 Parcial | `validator` crate disponible pero no usado consistentemente | +| SQL Injection | ✅ Prevenido | `rusqlite` usa queries parameterizadas | +| Error disclosure | ✅ Controlado | `AppError` con códigos i18n amigables | +| Secrets management | ✅ Documentado | `SECURITY.md` prohíbe commits de secrets | +| Safe file handling | ✅ Correcto | Path sanitization via `app_data_dir()` | +| Tauri capabilities | 🟡 Default | `capabilities/default.json` — revisar permisos | + +### 9.3 Recomendaciones + +1. **Implementar CSP** apropiado para Tauri (permitir solo `tauri://localhost` y recursos propios) +2. **Hacer blocking** las auditorías de seguridad en CI (sacar `continue-on-error`) +3. **Agregar dependabot** o renovate para actualizaciones automáticas de seguridad +4. **Agregar CodeQL** o similar para análisis estático +5. **Revisar capabilities** de Tauri para principios de mínimo privilegio + +--- + +## 10. Conclusión General + +OLManager es un proyecto **impresionantemente completo** para ser pre-alpha. La arquitectura es sólida, la separación de capas en Rust es correcta, y la cobertura de features es extensa para un juego de gestión de esports. + +### Puntos Fuertes +✅ Arquitectura hexagonal en Rust con dependency direction clara +✅ `ts-rs` para mantener tipos sync entre Rust y TypeScript +✅ 52 migraciones SQLite bien estructuradas +✅ Cobertura de tests amplia (~117 TS + ~22 Rust) +✅ Sistema de contenido social complejo y bien diseñado +✅ i18n completo con 8 idiomas +✅ Feature flag system (`typescript`) para compilación condicional +✅ Single-lock pattern en StateManager evita deadlocks +✅ Auto-updater integrado +✅ Legacy migration path desde OpenFootManager + +### Deuda Técnica Principal +🔴 `lol_sim_v2.rs` (6376 líneas) bloquea tests del crate principal +🔴 GameState completo via IPC — escalabilidad +🟡 CSP deshabilitado +🟡 Clippy warnings suprimidos +🟡 CI con `continue-on-error` generalizado +🟡 `LegacyCompatibilityValue = any` rompe type safety +🟡 README con merge residual de rama + +### Veredicto + +> **OLManager es un proyecto serio, bien arquitecturado, con un equipo que entiende de clean architecture, domain-driven design, y testing. Está en pre-alpha pero tiene más estructura y calidad que muchos proyectos "production-ready".** Las áreas de mejora son principalmente deuda técnica acumulada por el crecimiento orgánico y decisiones pragmáticas para mantener el desarrollo ágil. Con resolver `lol_sim_v2.rs`, tightening del CI, y habilitar CSP, estaría en una posición sólida para una beta. + +--- + +*Documento generado automáticamente el 08-MAY-2026.* diff --git a/docs/DEUDA_TECNICA_FUTBOL.md b/docs/DEUDA_TECNICA_FUTBOL.md new file mode 100644 index 000000000..8e5c13522 --- /dev/null +++ b/docs/DEUDA_TECNICA_FUTBOL.md @@ -0,0 +1,388 @@ +# Análisis Exhaustivo: Deuda Técnica de Fútbol en OLManager + +**Fecha:** 08-MAY-2026 +**Proyecto:** OLManager (Open League Manager) +**Contexto:** Migración incompleta desde OpenFootManager (fútbol) a OLManager (League of Legends esports) +**Método:** Búsqueda exhaustiva con grep en todo el codebase (347 archivos TS + 189 archivos Rust + i18n + scripts + datos + migraciones SQL) + +--- + +## Resumen Ejecutivo + +Se encontraron **53 issues distintos** de deuda técnica relacionados con fútbol distribuidos en todo el codebase. La migración está **parcialmente completa**: la capa visible (UI principal, enums de roles, comandos Tauri) está migrada, pero hay **capas profundas** (domain model, datos serializados, SQL migrations, scripts de seed, assets públicos, i18n keys, test data) que aún arrastran terminología de fútbol. + +| Categoría | Cantidad | Impacto | +|-----------|----------|---------| +| **Crítico (🔴)** | 14 | Afecta producción, datos activos, o comportamiento actual | +| **Medio (🟡)** | 22 | Debe migrarse, no afecta funcionalidad crítica inmediata | +| **Bajo (🟢)** | 17 | Cosméticos, documentación, naming legacy | +| **Total** | **53** | — | + +**Archivos más afectados:** +- `src-tauri/crates/domain/src/team.rs` — 4 issues críticos +- `src-tauri/crates/domain/src/stats.rs` — enum Position con 16 variantes de fútbol +- `src-tauri/crates/domain/src/player.rs` — Footedness, clean_sheets, goals +- `src/components/squad/SquadTab.helpers.ts` — TODO el archivo es fútbol +- `src/store/types.ts` — CompactTeamMatchStatsData con shots/fouls/corners/cards +- `src-tauri/databases/lec_world.json` — Seed data activo con stadium_name, formation: "4-4-2", play_style +- `src-tauri/crates/db/src/save_manager.rs` — Test data con alineaciones de 11 jugadores de fútbol + +--- + +## 🔴 Crítico — Afecta producción, datos activos o comportamiento actual + +### C1. Enum `Position` con 16 variantes de fútbol +- **Archivo:** `src-tauri/crates/domain/src/stats.rs:79-98` +- **Hallazgo:** El enum `Position` todavía tiene 16 variantes de fútbol: `Goalkeeper`, `RightBack`, `CenterBack`, `LeftBack`, `RightWingBack`, `LeftWingBack`, `DefensiveMidfielder`, `Midfielder`, `CentralMidfielder`, `AttackingMidfielder`, `RightMidfielder`, `LeftMidfielder`, `Forward`, `RightWinger`, `LeftWinger`, `Striker`, `Defender`. +- **Impacto:** Se usa activamente en `to_group_position()`, `From for LolRole`, `From for Position`, y en deserialización legacy. +- **Recomendación:** Deprecar completamente para lógica nueva. Debe mantenerse solo para deserialización legacy de saves viejos. Toda la lógica de negocio debe usar `LolRole`. + +### C2. `play_style: PlayStyle` en Team — pendiente de migrar a `draft_strategy` +- **Archivo:** `src-tauri/crates/domain/src/team.rs:46` +- **Hallazgo:** El campo `play_style` (tipo `PlayStyle` con variantes `Balanced`, `Attacking`, `Defensive`, `Possession`, `Counter`, `HighPress`) sigue siendo fútbol. +- **Impacto:** 268+ referencias en el backend (engine, turns, save_manager, integration tests) y 78+ referencias en frontend (ChampionDraft, MatchLive, HalfTimeBreak, test data en TODOS los tests de componentes). +- **Recomendación:** Migrar a `draft_strategy: DraftStrategy`. Ya existe propuesta `51-draft-strategy` con design y specs listos. + +### C3. `stadium_name` / `stadium_capacity` en Domain +- **Archivo:** `src-tauri/crates/domain/src/team.rs:14-15` +- **Hallazgo:** El struct `Team` del domain todavía usa `stadium_name: String` y `stadium_capacity: u32`. +- **Impacto:** Las migraciones SQL V35/V36 ya renombraron las columnas en la base de datos a `arena_name` / `arena_capacity`, pero los tipos del domain no se actualizaron. +- **Recomendación:** Renombrar a `arena_name` / `arena_capacity` con `#[serde(alias = "stadium_name")]` para compatibilidad con saves existentes. + +### C4. `formation: String` en Team — artefacto de fútbol +- **Archivo:** `src-tauri/crates/domain/src/team.rs:45` +- **Hallazgo:** `formation: String` con valores como `"4-4-2"`, `"4-3-3"`, etc. +- **Impacto:** 154+ referencias en frontend (test data, `SquadTab.helpers.ts`, `parseFormationSlots`, `buildPitchRows`), 58+ en backend. Todo el sistema de "formación" es un modelo de fútbol que no tiene sentido en LoL (5 roles fijos). +- **Recomendación:** Reemplazar con `composition: LolComposition` o similar, con lógica de 5 roles fijos. Requiere migración V43. + +### C5. Enum `Footedness` y campo `footedness` +- **Archivo:** `src-tauri/crates/domain/src/player.rs:96-106` +- **Hallazgo:** `pub enum Footedness { Left, Right, Both }` con comentario "Footedness is deprecated — LoL roles are lane-agnostic". +- **Impacto:** 41 referencias activas (save_manager, player_repo, legacy_migration crean jugadores con footedness). El campo se serializa/deserializa. +- **Recomendación:** Marcar `#[deprecated]` y dejar de poblarlo en nuevo código. Remover de `save_manager.rs` y `legacy_migration.rs`. + +### C6. `clean_sheets: u32` en PlayerSeasonStats +- **Archivo:** `src-tauri/crates/domain/src/player.rs:329` +- **Hallazgo:** `clean_sheets` es un concepto de fútbol (partidos sin recibir goles). En LoL no tiene sentido directo. +- **Impacto:** Se usa en `season_awards.rs` ("Clean Sheet King"), `post_match.rs` (incrementa), y tests. +- **Recomendación:** Reemplazar con métrica LoL apropiada (ej. `games_with_zero_deaths`, `kda_threshold`) o eliminar. + +### C7. `goals: u32` en CareerEntry +- **Archivo:** `src-tauri/crates/domain/src/player.rs:348` +- **Hallazgo:** `pub goals: u32` en `CareerEntry` — término de fútbol. Debería ser `kills`. +- **Recomendación:** Renombrar a `kills` con alias serde para compatibilidad. + +### C8. `home_goals` / `away_goals` en message & news domain +- **Archivo:** `src-tauri/crates/domain/src/message.rs:194-195` y `src-tauri/crates/domain/src/news.rs:57-58` +- **Hallazgo:** `pub home_goals: u8, pub away_goals: u8` en `NewsMatchScore` y `MessageContext`. +- **Recomendación:** Renombrar a `home_wins` / `away_wins` o `home_kills` / `away_kills` (ya existen en `MatchResult` pero los tipos de mensajes/news usan goals). + +### C9. Método `goal_difference()` en StandingEntry +- **Archivo:** `src-tauri/crates/domain/src/league.rs:148` +- **Hallazgo:** Método llamado `goal_difference()` (fútbol) pero calcula `kills_for - kills_against`. +- **Recomendación:** Renombrar a `kill_difference()` o `map_difference()`. + +### C10. `drawn: u32` en StandingEntry +- **Archivo:** `src-tauri/crates/domain/src/league.rs:127` +- **Hallazgo:** `pub drawn: u32` (concepto de fútbol — empates). En LoL best-of series no hay empates. +- **Impacto:** También en `CompactTeamMatchStats` donde NUNCA se usa en LoL (siempre 0). +- **Recomendación:** Deprecar y eliminar. En LoL Bo3/Bo5 no hay empates. + +### C11. `CompactTeamMatchStatsData` con stats de fútbol +- **Archivo:** `src/store/types.ts:617-625` +- **Hallazgo:** El frontend TypeScript tiene un tipo `CompactTeamMatchStatsData` completamente de fútbol: `shots`, `shots_on_target`, `fouls`, `corners`, `yellow_cards`, `red_cards`. +- **Impacto:** Se usa en `CompactMatchReportData`, `MatchResult`, y componentes de match. +- **Recomendación:** Reemplazar con stats LoL (`kills`, `deaths`, `gold_earned`, `damage_dealt`, `objectives`). + +### C12. `WorldEditorTab.tsx` genera `football_nation` y `position: "Midfielder"` +- **Archivo:** `src/components/worldEditor/WorldEditorTab.tsx:192-195` +- **Hallazgo:** `createNewPlayer()` produce `football_nation: "KR"` y `position: "Midfielder"`. La UI también tiene campo "Nación competitiva" ligado a `football_nation`. +- **Recomendación:** Eliminar `football_nation` del editor. Usar `LolRole` en vez de `Midfielder`. + +### C13. `CORE_POSITIONS` y `CANONICAL_POSITION_MAP` de fútbol +- **Archivo:** `src/components/squad/SquadTab.helpers.ts:42-87` +- **Hallazgo:** `CORE_POSITIONS = ["Goalkeeper", "Defender", "Midfielder", "Forward"]` y `CANONICAL_POSITION_MAP` mapea 25+ abreviaturas de fútbol (gk, rb, cb, lb, dm, cm, am, rm, lm, rw, lw, st, etc.) a posiciones de fútbol. +- **Impacto:** `buildPitchRows()` genera completamente en términos de fútbol (GK, DEF, DM, AM, FWD labels, Goalkeeper positions, defenderLine/midfieldLine/forwardLine helpers). +- **Recomendación:** Reemplazar todo el sistema con visualización de roles LoL (Top, Jungle, Mid, ADC, Support). + +### C14. `buildPitchRows()` en SquadTab.helpers +- **Archivo:** `src/components/squad/SquadTab.helpers.ts:275` +- **Hallazgo:** `buildPitchRows()` — "pitch" es cancha de fútbol. +- **Recomendación:** Renombrar a `buildRiftRows()` o `buildLaneRows()` y reescribir la lógica para roles LoL. + +--- + +## 🟡 Medio — Debe migrarse, no afecta funcionalidad crítica inmediata + +### M1. `lec_world.json` seed data usa `stadium_name`, `formation`, `play_style` +- **Archivo:** `src-tauri/databases/lec_world.json` +- **Hallazgo:** 36 equipos LEC con `"stadium_name": "... Arena"`, `"formation": "4-4-2"`, `"play_style": "Balanced"`. +- **Impacto:** Es el seed activo del juego. Todos los nuevos saves heredan estos valores. +- **Recomendación:** Cambiar a `arena_name`, eliminar `formation`, cambiar `play_style` → `draft_strategy`. + +### M2. Android gen `lec_world.json` con `football_nation` +- **Archivo:** `src-tauri/gen/android/app/src/main/assets/databases/lec_world.json` +- **Hallazgo:** Este JSON tiene `football_nation` en CADA equipo (todavía no migrado) + `stadium_name`. +- **Impacto:** Es build output de Android. Contiene datos legacy activos. +- **Recomendación:** Regenerar desde el seed source sin football_nation. + +### M3. `generate-lec-world.mjs` genera `football_nation` +- **Archivo:** `scripts/generate-lec-world.mjs:26,236,299,372,393` +- **Hallazgo:** Usa `footballNation` en team definitions y `football_nation` en output JSON. +- **Recomendación:** Eliminar. Usar `nationality_code` / `competitive_region`. + +### M4. `be.source.footballHerald` i18n key +- **Archivo:** `src-tauri/crates/ofm_core/src/news/match_report.rs:169` +- **Hallazgo:** `"be.source.footballHerald"` se usa como source key para artículos de match report. En locales: `"footballHerald": "LoL Esports"` o `"The Rift Herald"`. +- **Impacto:** El nombre del key expone fútbol en el sistema de i18n. +- **Recomendación:** Renombrar a `be.source.lolesports` o `be.source.riftHerald`. + +### M5. `footballTermGuard.test.ts` +- **Archivo:** `src/i18n/locales/footballTermGuard.test.ts` +- **Hallazgo:** El test de football term guard tiene allowlists con términos como "lineup", "Starting Five", "Rift". El nombre del archivo y el concepto sigue siendo fútbol. +- **Recomendación:** Renombrar a `localeTermGuard.test.ts`. + +### M6. `FOOTBALL_IDENTITIES` en countries.ts +- **Archivo:** `src/lib/countries.ts:27-102` +- **Hallazgo:** `interface FootballIdentityDefinition` y `const FOOTBALL_IDENTITIES` con códigos UK (ENG, SCO, WAL, NIR). +- **Impacto:** Necesario para backward compat con saves legacy, pero el naming es fútbol. +- **Recomendación:** Renombrar a `LEGACY_NATIONAL_IDENTITIES` o similar. + +### M7. `openfootlogo.svg` y `openfootball.svg` en public/ +- **Archivos:** `public/openfootlogo.svg`, `public/openfootball.svg` +- **Hallazgo:** Assets con branding "OpenFoot" (OpenFootManager). El logo SVG tiene `id="openfoot"`. +- **Impacto:** El MainMenu.tsx referencia `/openfootlogo.svg` (línea 381). +- **Recomendación:** Reemplazar con logo OLManager. + +### M8. Tests con nombres de fútbol +- **Múltiples archivos** +- **Hallazgo:** Tests con nombres como `upgrade_game_football_identities`, `upgrade_world_football_identities`, `active_lec_world_seed_does_not_contain_football_nation`, `export_world_to_json_writes_canonical_football_identity_fields`, `test_load_game_upgrades_football_identity_fields`. +- **Recomendación:** Renombrar tests a `upgrade_game_identities`, etc. + +### M9. Funciones `defender_line`, `midfield_line`, `forward_line` +- **Archivo:** `src-tauri/crates/ofm_core/src/player_rating.rs:34-65` +- **Hallazgo:** Funciones con nombres de fútbol que convierten counts a `Vec`. +- **Recomendación:** Renombrar a `top_line`, `jungle_line`, `bot_line` o eliminar (son dead code ya que `formation_slots` ignora formation). + +### M10. `narrative_news.rs` test con "football" +- **Archivo:** `src-tauri/crates/ofm_core/tests/narrative_news.rs:12` +- **Hallazgo:** El test usa `"football"` como forbidden term detector — correcto pero indicativo de que aún hay términos de fútbol en el sistema. +- **Recomendación:** Actualizar test para reflejar estado actual post-migración. + +### M11. `"be.source.footballHerald"` en locales +- **Archivos:** `src/i18n/locales/*.json` +- **Hallazgo:** En TODOS los locales: `en.json:2349`, `es.json:2354`, `fr.json:2308`, `de.json:2300`, `it.json:1652`, `pt.json:2256`, `pt-BR.json:2308`, `tr.json:2233`. +- **Recomendación:** Renombrar key a `be.source.lolEsports`. + +### M12. `pitchInteractionHint` i18n key +- **Archivos:** `src/i18n/locales/*.json` +- **Hallazgo:** En TODOS los locales. El texto ya habla de "Rift" en lugar de "pitch", pero el nombre del key es `pitchInteractionHint`. +- **Recomendación:** Renombrar key a `riftInteractionHint`. + +### M13. `yellow_cards` / `red_cards` en frontend types +- **Archivo:** `src/store/types.ts:623-624` +- **Hallazgo:** `CompactTeamMatchStatsData` tiene `yellow_cards: number; red_cards: number`. +- **Recomendación:** Eliminar (no existen en LoL). + +### M14. `goals_for` / `goals_against` legacy aliases en StandingData +- **Archivo:** `src/store/types.ts:642-645` +- **Hallazgo:** Deprecados con `@deprecated` pero todavía referenciados en `getStandingKillsFor`/`getStandingKillsAgainst`. +- **Recomendación:** Una vez migrados todos los fixtures, eliminar los campos deprecated. + +### M15. `draws?: number` en ManagerCareerStats +- **Archivo:** `src/store/types.ts:566,579` +- **Hallazgo:** `draws` término de fútbol. En LoL no hay empates. +- **Recomendación:** Eliminar o deprecar. + +### M16. `fixture` / `fixture_id` naming en frontend +- **Archivo:** `src/store/types.ts` y `src/lib/fixtures.ts` +- **Hallazgo:** 528+ referencias a "fixture". Si bien "fixture" no es exclusivo de fútbol, el sistema completo de fixtures (home_team_id, away_team_id, status, etc.) es un modelo de fútbol. +- **Recomendación:** Evaluar si migrar a `series` (más apropiado para LoL Bo3/Bo5). + +### M17. `v001_initial_schema.sql` con stadium_name, stadium_capacity, formation, play_style +- **Archivo:** `src-tauri/crates/db/src/sql/v001_initial_schema.sql:34-35,43-44` +- **Hallazgo:** Schema inicial tiene `stadium_name`, `stadium_capacity`, `formation TEXT NOT NULL DEFAULT '4-4-2'`, `play_style TEXT NOT NULL DEFAULT 'Balanced'`. +- **Nota:** Es el schema inicial, no se puede modificar porque rompería migraciones. Deuda conocida histórica. +- **Recomendación:** Dejar como está por compatibilidad de migraciones. Documentar como deuda conocida. + +### M18. `v015_match_stats_history.sql` con columnas de fútbol +- **Archivo:** `src-tauri/crates/db/src/sql/v015_match_stats_history.sql` +- **Hallazgo:** La tabla `player_match_stats` (deprecated, renombrada en V37 a `_deprecated_player_match_stats`) tenía columnas de fútbol. +- **Nota:** Ya está deprecated, pero el SQL de migración existe. +- **Recomendación:** Aceptar como deuda histórica, no tocar. + +### M19. `v014_football_identity.sql` como migration +- **Archivo:** `src-tauri/crates/db/src/sql/v014_football_identity.sql` +- **Hallazgo:** Migration V14 que agrega `football_nation` a todas las tablas. +- **Recomendación:** No tocar (migración histórica). V39 ya la revierte. + +### M20. `v006_team_match_roles.sql` con `penalty_taker`, `corner_taker` +- **Archivo:** `src-tauri/crates/db/src/sql/v006_team_match_roles.sql:2` +- **Hallazgo:** Columna JSON con roles de fútbol: `penalty_taker`, `free_kick_taker`, `corner_taker`. +- **Recomendación:** No tocar (migración histórica). Documentar como deuda. + +### M21. `openfootlogo.svg` en MainMenu test +- **Archivo:** `src/pages/MainMenu.test.tsx:381` +- **Hallazgo:** Test espera `src="/openfootlogo.svg"`. +- **Recomendación:** Actualizar test cuando se reemplace el logo. + +### M22. `MatchResult` con index signature legacy +- **Archivo:** `src/store/types.ts:596-607` +- **Hallazgo:** `MatchResult` tiene index signature para compatibilidad legacy con campos de fútbol (home_goals, away_goals, etc.). +- **Recomendación:** Una vez migrados todos los consumidores, eliminar. + +--- + +## 🟢 Bajo — Cosméticos, documentación, naming legacy + +### L1. Comentarios "football" en código Rust +- **Múltiples archivos** +- `src-tauri/crates/ofm_core/src/player_rating.rs:155` — `"In LoL, there's no left/right distinction like football"` +- `src-tauri/crates/ofm_core/src/live_match_manager/team_builder.rs:41` — `"NOTE: For LoL/live prototype we should not apply football injury filtering"` +- `src-tauri/crates/db/src/save_manager.rs:432` — `"In LoL, there's no strict left/right position pairing like in football."` +- `src-tauri/crates/db/src/repositories/player_repo.rs:88` — `"// Handles UPPERCASE (new serde), PascalCase (Debug, legacy write), AND legacy football"` +- `src-tauri/src/commands/squad.rs:499` — `"// In LoL, filter out Support role (the \\"goalkeeper\\" equivalent)"` +- `src-tauri/crates/engine/tests/simulation_tests.rs:19-20` — `"/// Map football Position to LoL role for test data"` +- `src-tauri/crates/engine/tests/live_match_tests.rs:13-14` — `"/// Map football Position to LoL role for test data"` +- **Recomendación:** Actualizar comentarios a terminología LoL. + +### L2. `CHANGELOG.md` referencias a migración de fútbol +- **Archivo:** `CHANGELOG.md:23-94` +- **Hallazgo:** Menciona la migración desde fútbol. +- **Recomendación:** Es histórico, no tocar. + +### L3. `pr_body.txt` con referencias a football nation +- **Archivo:** `pr_body.txt:9` +- **Recomendación:** No tocar (documento histórico de PR). + +### L4. `docs/legacy/` — documentación heredada de fútbol +- `docs/legacy/simulation.rst` — "Simulating a football/soccer match" +- `docs/legacy/inherited-docs/GETTING_STARTED.md` — guía de fútbol +- `docs/legacy/inherited-docs/DEFINITIONS.md` — definiciones con football_nation +- `docs/legacy/inherited-docs/MATCH_SIMULATION.md` — descripción de simulación de fútbol +- `docs/legacy/inherited-docs/SAVE_SYSTEM_DESIGN.md` — schema con football_nation +- **Recomendación:** Ya están en `docs/legacy/`, es intencional. No tocar. + +### L5. Propuestas de migración en `docs/proposals/` +- `docs/proposals/FOOTBALL_NATION_REMOVAL.md` +- `docs/proposals/FOOTBALL_REMNANTS.md` +- `docs/proposals/DATA_MIGRATION_PLAN.md` +- **Hallazgo:** Planes de migración que documentan la deuda. Son documentos de planificación. +- **Recomendación:** Archivar en `docs/legacy/archived-proposals/` cuando se complete la migración. + +### L6. `data/default_teams.json` con `stadium_name` +- **Archivo:** `src-tauri/data/default_teams.json:15-315` +- **Hallazgo:** 16 equipos default con `"stadium_name": "City Arena"`. +- **Recomendación:** Cambiar a `"arena_name"`. + +### L7. "Test FC" / "Home FC" / "Away FC" / "Test Stadium" en test data +- **Múltiples archivos** +- simulation_tests.rs, live_match_tests.rs, helpers.test.ts, etc. +- **Recomendación:** Cambiar a "Test Team" / "Home Team" / "Away Team". + +### L8. `football_position_to_lol_role()` helper en tests +- **Archivo:** `src-tauri/crates/engine/tests/simulation_tests.rs:20` +- **Recomendación:** Renombrar a `position_to_lol_role()`. + +### L9. `footballTermGuard.ts` +- **Archivo:** `src/content/lol/social/guard.ts` +- **Hallazgo:** La función `FOOTBALL_ERA_TERMS` tiene términos como `manager`, `coach`, `transfer` que también son válidos en LoL. Incluye `stadium`. +- **Recomendación:** Revisar el allowlist. Renombrar archivo a solo `guard.ts` (el path `lol/social/` ya indica el contexto). + +### L10. `lec_world.json` description +- **Archivos:** `src-tauri/databases/lec_world.json:3` y Android gen copy +- **Hallazgo:** `"description": "Mundo predefinido de League of Legends (LEC) para OpenFootManager adaptado."` +- **Recomendación:** Cambiar a `"OLManager"`. + +### L11. `save_manager.rs` con formación 4-4-2 en test data +- **Archivo:** `src-tauri/crates/db/src/save_manager.rs:711,714,718,726-736,899,920,942` +- **Hallazgo:** Tests con lineups de 11 jugadores de fútbol (gk, lb, cb1, cb2, rb, lm, cm1, cm2, rm, st1, st2). +- **Recomendación:** Refactorizar tests a lineups de 5 roles LoL. + +### L12. `legacy_migration.rs` con formación de fútbol +- **Archivo:** `src-tauri/crates/db/src/legacy_migration.rs:324,368-378,389,920` +- **Hallazgo:** Tests de migración legacy con posiciones de fútbol completas (11 jugadores). +- **Recomendación:** Refactorizar tests (son legacy, baja prioridad). + +### L13. Comentarios "legacy football" en player_repo.rs +- **Archivo:** `src-tauri/crates/db/src/repositories/player_repo.rs:107` +- **Hallazgo:** `"// === Legacy football position strings (for backward compatibility) ==="` — código correcto (necesario), pero el comentario podría simplificarse. +- **Recomendación:** Actualizar comentario a "legacy position strings". + +### L14. `offsides: 0` en test data +- **Archivo:** `src/components/playerProfile/PlayerProfileHeroCard.test.tsx:62` +- **Hallazgo:** Campo `offsides` en test data de player profile. +- **Recomendación:** Eliminar del test data. + +### L15. `revenue_per_match` / `calc_matchday` en finances +- **Archivo:** `src-tauri/crates/ofm_core/src/finances.rs:74,79,321` +- **Hallazgo:** `stadium_capacity` usado como parámetro. Si se renombra el campo en Team, actualizar aquí. +- **Recomendación:** Vincular al rename de `stadium_capacity` → `arena_capacity`. + +### L16. `tactics/TacticsTab.helpers.ts` con descripciones de fútbol +- **Archivo:** `src/components/tactics/TacticsTab.helpers.ts:28,34` +- **Hallazgo:** `"Pushes more bodies forward, creates extra support around the box"` — descripciones estilo fútbol para play styles. +- **Recomendación:** Actualizar textos a descripciones de draft strategy LoL. + +### L17. `ChampionDraft.tsx` comentario "football positions" +- **Archivo:** `src/components/match/ChampionDraft.tsx:479` +- **Hallazgo:** `"// Fallback: map football positions to LoL roles"`. +- **Recomendación:** Simplificar a `"// Map legacy positions to LoL roles"`. + +--- + +## Plan de Acción Recomendado + +### Prioridad 1: Críticos (Fase A) +1. Renombrar `stadium_name`/`stadium_capacity` → `arena_name`/`arena_capacity` en domain types +2. Eliminar `formation` field del domain→engine→DB→frontend +3. Reescribir `SquadTab.helpers.ts` — football pitch → LoL lineup builder +4. Remover `football_nation` de tipos de store + script de generación +5. Renombrar `goals_for`/`goals_against` → `maps_won`/`maps_lost` en StandingEntry +6. Reemplazar `CompactTeamMatchStatsData` con stats LoL +7. Deprecar `Footedness` y `clean_sheets` +8. Renombrar `goal_difference()` → `kill_difference()` +9. Eliminar `drawn` de StandingEntry +10. Arreglar `WorldEditorTab.tsx` para no generar football_nation + +### Prioridad 2: Medios (Fase B) +1. Reemplazar `openfootlogo.svg` con logo OLManager +2. Renombrar i18n keys (`footballHerald` → `lolEsports`, `pitchInteractionHint` → `riftInteractionHint`) +3. Migrar test data de 4-4-2 a rosters de 5 roles LoL +4. Renombrar `fixture` → `match` / `series` donde aplique +5. Arreglar `generate-lec-world.mjs` para no emitir football_nation +6. Renombrar tests con nombres de fútbol +7. Limpiar `FOOTBALL_IDENTITIES` → `LEGACY_NATIONAL_IDENTITIES` +8. Eliminar `yellow_cards`/`red_cards` de tipos frontend +9. Remover `draws` de ManagerCareerStats +10. Evaluar migración `PlayStyle` → `DraftStrategy` (ver propuesta #51) + +### Prioridad 3: Bajos (Fase C) +1. Marcar `#[deprecated]` en `Position` enum +2. Actualizar comentarios "football" → "legacy" en Rust +3. Limpiar test data de 11 jugadores de fútbol en save_manager.rs +4. Actualizar `data/default_teams.json` a `arena_name` +5. Renombrar `footballTermGuard.ts` → `guard.ts` +6. Cambiar description de `lec_world.json` a OLManager +7. Actualizar comentarios en `ChampionDraft.tsx` +8. Archivar propuestas de migración en `docs/legacy/archived-proposals/` +9. Limpiar `offsides` de test data +10. Actualizar descripciones de tactics helpers + +### Migración de Base de Datos Requerida +- **V43:** Eliminar columna `formation` de tabla `teams` +- **V44:** Renombrar columnas `stadium_name`/`stadium_capacity` → `arena_name`/`arena_capacity` (si no se hizo en V35/V36) +- **V45:** Eliminar `football_nation` de tablas de jugadores y equipos + +### Riesgos y Mitigaciones +| Riesgo | Probabilidad | Mitigación | +|--------|-------------|------------| +| Romper saves existentes al eliminar formation | Media | Migración V43 con default a 5 roles LoL en carga | +| SquadTab.helpers.ts tightly coupled | Alta | Reescribir helpers primero, mantener interfaz, luego SquadTab.tsx | +| `stadium`→`arena` rompe IPC | Baja | Grep `stadium_` en frontend antes de renombrar | +| `football_nation` en scripts de generación | Alta | Arreglar script primero, regenerar seed, assertion en CI | +| Tests rotos tras renombrar | Media | Correr `cargo test` y `npm test` después de cada fase | + +--- + +*Documento generado automáticamente el 08-MAY-2026.* diff --git a/docs/arquitectura-datos.md b/docs/arquitectura-datos.md new file mode 100644 index 000000000..ee687563d --- /dev/null +++ b/docs/arquitectura-datos.md @@ -0,0 +1,42 @@ +# Arquitectura de Datos — OLManager + +## Estructura de archivos + +``` +src-tauri/data/ +├── leagues.json +├── competitions/ ← Reglas de calendario de cada competicion +│ ├── lec/manifest.json +│ ├── cblol/manifest.json +│ └── ... (12 competiciones) +├── teams/ ← Equipos organizados por region +│ ├── emea_teams.json +│ ├── kr_teams.json +│ ├── na_teams.json +│ └── ... (15 archivos) +├── players/ ← Jugadores organizados por region +│ ├── emea_players.json +│ ├── kr_players.json +│ └── ... (15 archivos) +├── staffs/ +│ └── free_agents.json ← Staff libre (el staff por equipo se genera proceduralmente) +├── draft/ +│ └── champions.json ← Catalogo global de champions (unico archivo vivo del draft) +├── erls/ ← Seeds de academias (texto) +│ ├── les.txt, lfl.txt, Prime League.txt +└── leagues.json ← Metadata de ligas para el frontend +``` + +## Flujo al iniciar partida + +``` +Frontend: league_selection -> load_league(league_id) -> team_selection -> start_new_game(team_id) +``` + +1. **league_selection**: Usuario elige liga (LEC, LCK, LCS, etc.) +2. **load_league(league_id)**: Backend devuelve datos LIVIANOS (equipos, nombres, logos, OVRs) — NO crea el mundo +3. **team_selection**: Usuario elige equipo con la data liviana +4. **start_new_game(team_id)**: Backend crea el mundo COMP逼ETO con todas las ligas/regiones y asigna el equipo del usuario +5. **select_team()**: Ya no es necesario — el equipo ya viene en start_new_game + +**Ventaja**: Se puede volver de team_selection a league_selection sin costo, porque load_league no crea el mundo. diff --git a/docs/proposals/FOOTBALL_NATION_REMOVAL.md b/docs/legacy/archived-proposals/FOOTBALL_NATION_REMOVAL.md similarity index 100% rename from docs/proposals/FOOTBALL_NATION_REMOVAL.md rename to docs/legacy/archived-proposals/FOOTBALL_NATION_REMOVAL.md diff --git a/docs/proposals/FOOTBALL_REMNANTS.md b/docs/legacy/archived-proposals/FOOTBALL_REMNANTS.md similarity index 100% rename from docs/proposals/FOOTBALL_REMNANTS.md rename to docs/legacy/archived-proposals/FOOTBALL_REMNANTS.md diff --git a/docs/stats-atributos.md b/docs/stats-atributos.md new file mode 100644 index 000000000..e19e4a86e --- /dev/null +++ b/docs/stats-atributos.md @@ -0,0 +1,241 @@ +# Stats / Atributos — Guía completa + +## 1. EQUIPO (`Team`) + +### Finanzas + +| Atributo | Tipo | ¿Qué hace? | +|----------|------|------------| +| `finance` | `i64` | Dinero disponible. Se gasta en adquisiciones de academia, staff, mejoras de instalaciones. Si es negativo → restricciones. | +| `wage_budget` | `i64` | Límite de salarios. Si los jugadores exceden esto, problemas de moral/finanzas. | +| `transfer_budget` | `i64` | Máximo que podés gastar en fichajes. | +| `season_income` / `season_expenses` | `i64` | Acumulador del año. Se usa para calcular balance de temporada. | + +### Reputación + +| Atributo | Rango | ¿Qué hace? | +|----------|-------|------------| +| `reputation` | `u32` (0+) | Atrae mejores jugadores libres, sponsors más grandes, staff de mayor nivel. A más reputación, más opciones de contratación y mejor valor de mercado. | + +### Instalaciones (`Facilities`) + +| Atributo | Rango | Efecto | +|----------|-------|--------| +| `main_hub_level` | 0-5 | Núcleo del centro de entrenamiento. Desbloquea módulos. | +| `training` | 0-5 | Velocidad de mejora de atributos en entrenamiento. | +| `medical` | 0-5 | Reduce tiempo de recuperación de lesiones. | +| `scouting` | 0-5 | Calidad y velocidad de informes de scouting. | +| `scrims_room_level` | 0-5 | Calidad de simulaciones en scrims. | +| `analysis_room_level` | 0-5 | Mejora `execution` en partidos. | +| `bootcamp_area_level` | 0-5 | Mejora `coaching` temporal durante bootcamps. | +| `recovery_suite_level` | 0-5 | Multiplica `recovery` del staff. | +| `content_studio_level` | 0-5 | Mejora ingresos por sponsorships/redes. | +| `scouting_lab_level` | 0-5 | Mejora `meta_discovery` del staff. | + +### Tácticas (`LolTactics` + `DraftStrategy`) + +| Atributo | Efecto | +|----------|--------| +| `draft_strategy` (Balanced/Aggressive/Passive/Scaling/CounterPick) | Modifica la composición del draft de la simulación. Cada estrategia da bonuses a distintas fases (ataque/defensa/mid) en el engine. | +| `lol_tactics.strong_side` (Top/Bot) | Define qué lado de la mapa recibe más recursos. | +| `lol_tactics.jungle_style` | Patrón de ruta del jungla (Enabler/Carry/etc.). | +| `lol_tactics.fight_plan` | Cómo pelea el equipo (FrontToBack/Flank/etc.). | +| `lol_tactics.support_roaming` | Si el support rota o se queda en línea. | + +### Entrenamiento + +| Atributo | Efecto | +|----------|--------| +| `training_focus` (Scrims/VODReview/IndividualCoaching/etc.) | Determina qué atributos mejoran más rápido en entrenamiento. | +| `training_intensity` (Low/Medium/High) | Velocidad de mejora vs. riesgo de lesiones/burnout. | +| `training_schedule` (Balanced/Intensive/Flexible) | Cuántos días por semana entrena el equipo. | + +### Scrims + +| Atributo | Efecto | +|----------|--------| +| `scrim_reputation` (0-100) | Calidad de oponentes disponibles para scrims. | +| `scrim_weekly_slots` | Cantidad de scrims por semana. | +| `scrim_weekly_played/wins/losses` | Estadísticas semanales. `scrim_loss_streak` afecta moral. | + +--- + +## 2. JUGADOR (`Player`) + +### Atributos principales (0-100) — `PlayerAttributes` + +Estos 9 atributos son los que usa el **motor de simulación** (`engine`). Se mapean 1:1 a `PlayerData` en el engine. + +``` + PlayerAttributes (domain) PlayerData (engine) + ─────────────────────── ───────────────── + mechanics ──────────────► mechanics + laning ──────────────► laning + teamfighting ──────────────► teamfighting + macro_play ──────────────► macro_play + consistency ──────────────► consistency + shotcalling ──────────────► shotcalling + champion_pool ──────────────► champion_pool + discipline ──────────────► discipline + mental_resilience ──────────────► mental_resilience +``` + +**Overall (media simple):** `(mechanics + laning + teamfighting + macro_play + consistency + shotcalling + champion_pool + discipline + mental_resilience) / 9` + +**Effective overall:** `overall * (condition / 100)` — lo que realmente se usa en partido. + +| Atributo | Alias (legacy) | ¿Qué representa? | +|----------|---------------|------------------| +| `mechanics` | dribbling, reaction_speed | Habilidad mecánica (clicks precisos, micro) | +| `laning` | shooting | Fase de líneas (CS, trades early) | +| `teamfighting` | teamwork, coordination | Rendimiento en peleas de equipo | +| `macro_play` | vision, interception | Visión de mapa, rotaciones, objetivos | +| `consistency` | decisions, positioning | Regularidad partido a partido | +| `shotcalling` | leadership, aggression | Capacidad de liderazgo y llamadas | +| `champion_pool` | agility | Versatilidad de champions | +| `discipline` | composure, positional_defense | Control de errores, no morir regalado | +| `mental_resilience` | stamina, durability | Resistencia a presión, se mantiene estable en partidos largos | + +### Estados dinámicos + +| Atributo | Rango | Efecto | +|----------|-------|--------| +| `condition` | 0-100 | Energía del jugador (**se agota durante partidos**, se recupera diario). `effective_overall = overall * (condition/100)`. Si baja de ~40, el jugador rende muy por debajo. | +| `morale` | 0-100 | Moral. Baja si pierde, si está en banca, si hay promesas incumplidas. Afecta rendimiento en partido (multiplicador ~0.95-1.05). | +| `fitness` | 0-100 | Estado físico a largo plazo. Determina qué tan rápido se recupera `condition`. Baja lentamente si se juega mucho sin descanso. | +| `injury` | `Option` | Si tiene lesión, `days_remaining` > 0. No puede jugar. | + +### Potencial + +| Atributo | Efecto | +|----------|--------| +| `potential_base` (0-99) | Techo máximo de `overall()` que puede alcanzar este jugador vía entrenamiento/experiencia. 99 = potencial generacional. | +| `potential_revealed` | Potencial "descubierto" por scouting (progresión). | +| `champion_mastery` | `Vec` — pares `(champion_id, mastery)`. Usado por `bootstrap_seed_masteries()` para inicializar el sistema de champion mastery. | + +### Contrato + +| Atributo | Efecto | +|----------|--------| +| `wage` (u32) | Salario semanal. Resta del `wage_budget` del equipo. | +| `market_value` (u64) | Valor de mercado estimado. Usado para ofertas de transferencia. | +| `contract_end` | Fecha de fin de contrato. Si se acerca, el jugador puede irse gratis o pedir renovación. | + +### Ofertas de transferencia + +| Atributo | Efecto | +|----------|--------| +| `transfer_listed` | El jugador está en el mercado. | +| `loan_listed` | El jugador está disponible para cesión. | +| `transfer_offers` | Lista de ofertas recibidas de otros clubes. | + +### Imágenes + +| Entidad | Campo | Cómo se resuelve | +|---------|-------|------------------| +| **Team** | No tiene campo de imagen. | El frontend resuelve el logo mediante `teamLogoMapping.ts` (mapping por slug del nombre del equipo). | +| **Player** | `profile_image_url: Option` | Campo opcional. Si es `None`, el frontend usa `playerPhotoMapping.ts` por `match_name`. | +| **Staff** | `profile_image_url: Option` | Campo opcional. Si es `None`, el frontend usa `staffPhotoMapping.ts` por nombre. | +| **Academia** | `AcademyMetadata.original_logo_url` / `current_logo_url` | Guardan el logo del equipo academy (puede diferir del main team). | + +--- + +## 3. STAFF (`Staff`) + +### Atributos base (`StaffAttributes`) — 0-100 + +| Atributo | ¿Quién lo usa? | +|----------|---------------| +| `coaching` | `Coach` + `AssistantManager` (promedio del equipo) | +| `judging_ability` | `Scout` (promedio del equipo) | +| `judging_potential` | `Scout` (promedio del equipo) | +| `physiotherapy` | `Physio` (promedio del equipo) | + +### Roles (`StaffRole`) + +| Rol | Atributo que importa | +|-----|---------------------| +| `AssistantManager` | `coaching` | +| `Coach` | `coaching` | +| `Scout` | `judging_ability` + `judging_potential` | +| `Physio` | `physiotherapy` | +| `Owner` | Ninguno — no afecta gameplay directamente | + +### Relación Team ↔ Staff + +``` +Game +├── staff: Vec ← todos los staff del mundo +│ └── cada Staff tiene team_id → se vincula a un Team +├── teams: Vec ← NO tienen lista de staff +│ └── para obtener su staff: filtrar game.staff por team_id +└── players: Vec + └── cada Player tiene team_id → mismo patrón +``` + +**Team no tiene `staff_ids`** ni vector propio. La relación se resuelve dinámicamente filtrando `game.staff.iter().filter(|s| s.team_id == team_id)`. Es el mismo patrón que con los players. Como cada equipo tiene ~4 staff, no es un cuello de botella. + +### Outputs del sistema (`LolStaffEffects`) + +Los 4 atributos base se transforman en **8 multiplicadores** que afectan distintas áreas del juego: + +``` +StaffAttributes (input, 0-100) ──► LolStaffEffects (output, multipliers) +────────────────────────────── ──────────────────────────────────── +coaching ──────────────► coaching_mult (0.85-1.25) +coaching ──────────────► development (0.88-1.22) +coaching ──────────────► tactics (0.90-1.18) +coaching ──────────────► morale (0.95-1.15) +judging_ability ──────────────► analysis (0.90-1.16) +judging_ability ───┐ + ├─► meta_discovery (0.90-1.20) +judging_potential ──┘ +physiotherapy ──────────────► recovery (0.95-1.25) +(tactics+analysis)/2 ──────────► execution (0.96-1.10) +``` + +| Output | Rango | ¿Qué afecta? | +|--------|-------|-------------| +| `coaching_mult` | 0.85-1.25 | Rendimiento general del equipo en entrenamiento y partido | +| `development` | 0.88-1.22 | Velocidad de mejora de atributos de los jugadores | +| `tactics` | 0.90-1.18 | Calidad de draft en simulación | +| `analysis` | 0.90-1.16 | Calidad de informes de scouting | +| `recovery` | 0.95-1.25 | Regeneración de `condition` post-partido | +| `morale` | 0.95-1.15 | Estabilidad de `morale` del equipo | +| `meta_discovery` | 0.90-1.20 | Descubrir nuevos metas / champion picks | +| `execution` | 0.96-1.10 | Ejecución de draft en partido | + +### Fórmulas derivadas + +**Match mastery multiplier:** +`(development * 0.65 + analysis * 0.35).clamp(0.88, 1.18)` +→ Ganancia de mastery en partidos + +**Draft power bonus:** +`((tactics - 1.0) * 4.0 + (analysis - 1.0) * 3.0).clamp(-1.0, 3.0)` +→ Bonus de poder de draft en simulación + +--- + +## 4. FLUJO COMPLETO EN PARTIDO + +``` +Team.facilities ────► staff effects ──► player condition recovery + +Staff.coaching ─────► coaching_mult ──► player training gain ← de Coach + AssistantManager +Staff.judging_* ────► analysis ───────► scouting quality ← de Scout +Staff.physio ───────► recovery ───────► condition regen ← de Physio +Staff.Owner ────────► (sin efecto directo en simulador) + +Player.attributes ──► overall ────────► match simulation +Player.condition ───► effective_overall +Player.champion_mastery ──────────────► draft quality + +Team.lol_tactics ───► draft_strategy ─► match modifiers +Team.draft_strategy ──────────────────► phase bonuses +``` + +El engine recibe: +- `PlayerData` con los 9 atributos + `condition` +- `TeamData` con `draft_strategy` + jugadores +- `LolStaffEffects` como multiplicadores externos diff --git a/public/openfootlogo.svg b/public/olmanager-logo.svg similarity index 100% rename from public/openfootlogo.svg rename to public/olmanager-logo.svg diff --git a/public/openfootball.svg b/public/openfootball.svg deleted file mode 100644 index a6baa06cd..000000000 --- a/public/openfootball.svg +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/team-logos/fnatic.png b/public/team-logos/fnatic.png deleted file mode 100644 index 9aa22a980..000000000 Binary files a/public/team-logos/fnatic.png and /dev/null differ diff --git a/public/team-logos/g2-esports.png b/public/team-logos/g2-esports.png deleted file mode 100644 index a1a5fec67..000000000 Binary files a/public/team-logos/g2-esports.png and /dev/null differ diff --git a/public/team-logos/giantx-lec.png b/public/team-logos/giantx-lec.png deleted file mode 100644 index 51a1ce980..000000000 Binary files a/public/team-logos/giantx-lec.png and /dev/null differ diff --git a/public/team-logos/karmine-corp.png b/public/team-logos/karmine-corp.png deleted file mode 100644 index ab9d12c32..000000000 Binary files a/public/team-logos/karmine-corp.png and /dev/null differ diff --git a/public/team-logos/mad-lions.png b/public/team-logos/mad-lions.png deleted file mode 100644 index 413f18346..000000000 Binary files a/public/team-logos/mad-lions.png and /dev/null differ diff --git a/public/team-logos/natus-vincere.png b/public/team-logos/natus-vincere.png deleted file mode 100644 index d00fb4373..000000000 Binary files a/public/team-logos/natus-vincere.png and /dev/null differ diff --git a/public/team-logos/sk-gaming.png b/public/team-logos/sk-gaming.png deleted file mode 100644 index 1439ebba1..000000000 Binary files a/public/team-logos/sk-gaming.png and /dev/null differ diff --git a/public/team-logos/team-bds.png b/public/team-logos/team-bds.png deleted file mode 100644 index 8c8e65785..000000000 Binary files a/public/team-logos/team-bds.png and /dev/null differ diff --git a/public/team-logos/team-heretics-lec.png b/public/team-logos/team-heretics-lec.png deleted file mode 100644 index 74dd9d923..000000000 Binary files a/public/team-logos/team-heretics-lec.png and /dev/null differ diff --git a/public/team-logos/team-vitality.png b/public/team-logos/team-vitality.png deleted file mode 100644 index 48d91ec74..000000000 Binary files a/public/team-logos/team-vitality.png and /dev/null differ diff --git a/public/teams-icons/fnatic.webp b/public/teams-icons/fnatic.webp new file mode 100644 index 000000000..874bd8a88 Binary files /dev/null and b/public/teams-icons/fnatic.webp differ diff --git a/public/teams-icons/g2-esports.webp b/public/teams-icons/g2-esports.webp new file mode 100644 index 000000000..07fa413f9 Binary files /dev/null and b/public/teams-icons/g2-esports.webp differ diff --git a/public/teams-icons/giantx-lec.webp b/public/teams-icons/giantx-lec.webp new file mode 100644 index 000000000..37bca7776 Binary files /dev/null and b/public/teams-icons/giantx-lec.webp differ diff --git a/public/teams-icons/karmine-corp.webp b/public/teams-icons/karmine-corp.webp new file mode 100644 index 000000000..960b66de5 Binary files /dev/null and b/public/teams-icons/karmine-corp.webp differ diff --git a/public/teams-icons/movistar-koi.webp b/public/teams-icons/movistar-koi.webp new file mode 100644 index 000000000..8167950cd Binary files /dev/null and b/public/teams-icons/movistar-koi.webp differ diff --git a/public/teams-icons/natus-vincere.webp b/public/teams-icons/natus-vincere.webp new file mode 100644 index 000000000..9117bd8cb Binary files /dev/null and b/public/teams-icons/natus-vincere.webp differ diff --git a/public/teams-icons/shifters.webp b/public/teams-icons/shifters.webp new file mode 100644 index 000000000..9b9827c54 Binary files /dev/null and b/public/teams-icons/shifters.webp differ diff --git a/public/teams-icons/sk-gaming.webp b/public/teams-icons/sk-gaming.webp new file mode 100644 index 000000000..90be9ff10 Binary files /dev/null and b/public/teams-icons/sk-gaming.webp differ diff --git a/public/teams-icons/team-heretics-lec.webp b/public/teams-icons/team-heretics-lec.webp new file mode 100644 index 000000000..ffa723046 Binary files /dev/null and b/public/teams-icons/team-heretics-lec.webp differ diff --git a/public/teams-icons/team-vitality.webp b/public/teams-icons/team-vitality.webp new file mode 100644 index 000000000..21f87d6bd Binary files /dev/null and b/public/teams-icons/team-vitality.webp differ diff --git a/scripts/download-lol-item-icons.mjs b/scripts/download-lol-item-icons.mjs deleted file mode 100644 index f76014e11..000000000 --- a/scripts/download-lol-item-icons.mjs +++ /dev/null @@ -1,133 +0,0 @@ -import { mkdir, writeFile } from "node:fs/promises"; -import path from "node:path"; -import { fileURLToPath } from "node:url"; - -const DDRAGON_VERSION = "14.24.1"; -const __filename = fileURLToPath(import.meta.url); -const __dirname = path.dirname(__filename); -const projectRoot = path.resolve(__dirname, ".."); -const outDir = path.join(projectRoot, "public", "lol-item-icons"); - -const ITEM_NAME_BY_KEY = { - sunfire_aegis: "Sunfire Aegis", - warmogs_armor: "Warmog's Armor", - iceborn_gauntlet: "Iceborn Gauntlet", - randuins_omen: "Randuin's Omen", - spirit_visage: "Spirit Visage", - plated_steelcaps: "Plated Steelcaps", - sundered_sky: "Sundered Sky", - deaths_dance: "Death's Dance", - steraks_gage: "Sterak's Gage", - titanic_hydra: "Titanic Hydra", - maw_of_malmortius: "Maw of Malmortius", - mercurys_treads: "Mercury's Treads", - black_cleaver: "Black Cleaver", - hullbreaker: "Hullbreaker", - dead_mans_plate: "Dead Man's Plate", - voltaic_cyclosword: "Voltaic Cyclosword", - opportunity: "Opportunity", - immortal_shieldbow: "Immortal Shieldbow", - seryldas_grudge: "Serylda's Grudge", - profane_hydra: "Profane Hydra", - boots_of_swiftness: "Boots of Swiftness", - stormsurge: "Stormsurge", - lich_bane: "Lich Bane", - shadowflame: "Shadowflame", - zhonyas_hourglass: "Zhonya's Hourglass", - rabadons_deathcap: "Rabadon's Deathcap", - sorcerers_shoes: "Sorcerer's Shoes", - ludens_companion: "Luden's Companion", - void_staff: "Void Staff", - seraphs_embrace: "Seraph's Embrace", - liandrys_torment: "Liandry's Torment", - rylais_crystal_scepter: "Rylai's Crystal Scepter", - cosmic_drive: "Cosmic Drive", - bloodthirster: "Bloodthirster", - infinity_edge: "Infinity Edge", - mortal_reminder: "Mortal Reminder", - rapid_firecannon: "Rapid Firecannon", - phantom_dancer: "Phantom Dancer", - berserkers_greaves: "Berserker's Greaves", - blade_of_the_ruined_king: "Blade of The Ruined King", - wits_end: "Wit's End", - runaans_hurricane: "Runaan's Hurricane", - guinsoos_rageblade: "Guinsoo's Rageblade", - terminus: "Terminus", - the_collector: "The Collector", - edge_of_night: "Edge of Night", - ionian_boots_of_lucidity: "Ionian Boots of Lucidity", - trailblazer: "Trailblazer", - zekes_convergence: "Zeke's Convergence", - knights_vow: "Knight's Vow", - locket_of_the_iron_solari: "Locket of the Iron Solari", - thornmail: "Thornmail", - mobility_boots: "Mobility Boots", - shurelyas_battlesong: "Shurelya's Battlesong", - ardent_censer: "Ardent Censer", - moonstone_renewer: "Moonstone Renewer", - redemption: "Redemption", - staff_of_flowing_water: "Staff of Flowing Water", - morellonomicon: "Morellonomicon", - cryptbloom: "Cryptbloom", -}; - -function normalizeName(value) { - return value - .normalize("NFD") - .replace(/[^\p{L}\p{N}]+/gu, "") - .toLowerCase(); -} - -async function main() { - await mkdir(outDir, { recursive: true }); - - const itemDataUrl = `https://ddragon.leagueoflegends.com/cdn/${DDRAGON_VERSION}/data/en_US/item.json`; - const itemDataResponse = await fetch(itemDataUrl); - if (!itemDataResponse.ok) { - throw new Error(`Failed to fetch item.json (${itemDataResponse.status})`); - } - - const itemDataPayload = await itemDataResponse.json(); - const itemMap = itemDataPayload?.data ?? {}; - const normalizedNameToImage = new Map(); - for (const item of Object.values(itemMap)) { - if (!item || typeof item !== "object") continue; - const name = item?.name; - const imageFull = item?.image?.full; - if (typeof name !== "string" || typeof imageFull !== "string") continue; - normalizedNameToImage.set(normalizeName(name), imageFull); - } - - const missing = []; - - for (const [key, itemName] of Object.entries(ITEM_NAME_BY_KEY)) { - const imageFull = normalizedNameToImage.get(normalizeName(itemName)); - if (!imageFull) { - missing.push(`${key} => ${itemName}`); - continue; - } - - const iconUrl = `https://ddragon.leagueoflegends.com/cdn/${DDRAGON_VERSION}/img/item/${imageFull}`; - const iconResponse = await fetch(iconUrl); - if (!iconResponse.ok) { - missing.push(`${key} => ${itemName} (download ${iconResponse.status})`); - continue; - } - - const buffer = Buffer.from(await iconResponse.arrayBuffer()); - const outPath = path.join(outDir, `${key}.png`); - await writeFile(outPath, buffer); - } - - if (missing.length > 0) { - console.warn("Some items could not be resolved/downloaded:"); - for (const line of missing) console.warn(` - ${line}`); - } - - console.log(`Done. Icons stored in: ${outDir}`); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); diff --git a/scripts/fetch-leaguepedia-dobs.mjs b/scripts/fetch-leaguepedia-dobs.mjs deleted file mode 100644 index 391200c87..000000000 --- a/scripts/fetch-leaguepedia-dobs.mjs +++ /dev/null @@ -1,176 +0,0 @@ -import { readFile, writeFile, mkdir } from "node:fs/promises"; -import { dirname, resolve } from "node:path"; - -const ROOT = resolve(process.cwd()); -const seedPath = resolve(ROOT, "data/lec/seed.teams-players.local.json"); -const outPath = resolve(ROOT, "data/lec/player-overrides.json"); - -const MONTHS = { - january: 1, - february: 2, - march: 3, - april: 4, - may: 5, - june: 6, - july: 7, - august: 8, - september: 9, - october: 10, - november: 11, - december: 12, -}; - -function sleep(ms) { - return new Promise((resolveSleep) => setTimeout(resolveSleep, ms)); -} - -function toIsoDate(year, month, day) { - const y = String(year).padStart(4, "0"); - const m = String(month).padStart(2, "0"); - const d = String(day).padStart(2, "0"); - return `${y}-${m}-${d}`; -} - -function parseBirthDateFromWikitext(wikitext) { - const yearMatch = wikitext.match(/\|\s*birth_date_year\s*=\s*([^\n\r|]+)/i); - const monthMatch = wikitext.match(/\|\s*birth_date_month\s*=\s*([^\n\r|]+)/i); - const dayMatch = wikitext.match(/\|\s*birth_date_day\s*=\s*([^\n\r|]+)/i); - - if (!yearMatch || !monthMatch || !dayMatch) { - return null; - } - - const year = Number(String(yearMatch[1]).trim()); - const day = Number(String(dayMatch[1]).trim()); - const rawMonth = String(monthMatch[1]).trim(); - - let month = Number(rawMonth); - if (!Number.isFinite(month) || month < 1 || month > 12) { - month = MONTHS[rawMonth.toLowerCase()] ?? NaN; - } - - if (!Number.isFinite(year) || !Number.isFinite(month) || !Number.isFinite(day)) { - return null; - } - - if (year < 1970 || year > 2015 || month < 1 || month > 12 || day < 1 || day > 31) { - return null; - } - - return toIsoDate(year, month, day); -} - -async function fetchPlayerWikitext(page) { - const params = new URLSearchParams({ - action: "parse", - page, - prop: "wikitext", - format: "json", - redirects: "true", - }); - - const url = `https://lol.fandom.com/api.php?${params.toString()}`; - const response = await fetch(url, { - headers: { - "User-Agent": "LeagueManager/0.1 (local data bootstrap)", - }, - }); - - if (!response.ok) { - return null; - } - - const data = await response.json(); - const wikitext = data?.parse?.wikitext?.["*"]; - if (!wikitext || typeof wikitext !== "string") { - return null; - } - - const title = data?.parse?.title ?? page; - return { title, wikitext }; -} - -async function findCandidateTitles(query) { - const params = new URLSearchParams({ - action: "query", - list: "search", - srsearch: query, - srlimit: "5", - format: "json", - }); - - const url = `https://lol.fandom.com/api.php?${params.toString()}`; - const response = await fetch(url, { - headers: { - "User-Agent": "LeagueManager/0.1 (local data bootstrap)", - }, - }); - - if (!response.ok) return []; - const data = await response.json(); - return (data?.query?.search ?? []).map((entry) => entry.title).filter(Boolean); -} - -async function resolveDateOfBirthByNick(nick) { - const direct = await fetchPlayerWikitext(nick); - if (direct) { - const dob = parseBirthDateFromWikitext(direct.wikitext); - if (dob) return { dob, page: direct.title, strategy: "direct" }; - } - - const candidates = await findCandidateTitles(`${nick} Leaguepedia player`); - for (const title of candidates) { - const candidate = await fetchPlayerWikitext(title); - if (!candidate) continue; - const dob = parseBirthDateFromWikitext(candidate.wikitext); - if (dob) return { dob, page: candidate.title, strategy: "search" }; - } - - return null; -} - -const rawSeed = await readFile(seedPath, "utf8"); -const seed = JSON.parse(rawSeed.replace(/^\uFEFF/, "")); - -const nicks = Array.from( - new Set( - seed.teams - .flatMap((team) => team.players ?? []) - .map((player) => String(player.summonerName || "").trim()) - .filter(Boolean), - ), -).sort((a, b) => a.localeCompare(b)); - -const players = {}; -const missing = []; - -for (const nick of nicks) { - const result = await resolveDateOfBirthByNick(nick); - if (result) { - players[nick] = { - date_of_birth: result.dob, - leaguepedia_page: result.page, - strategy: result.strategy, - }; - console.log(`✓ ${nick} -> ${result.dob} (${result.page})`); - } else { - missing.push(nick); - console.log(`- ${nick} -> not found`); - } - // polite pacing to avoid hammering - await sleep(120); -} - -const output = { - generatedAt: new Date().toISOString(), - source: "leaguepedia", - players, - missing, -}; - -await mkdir(dirname(outPath), { recursive: true }); -await writeFile(outPath, JSON.stringify(output, null, 2), "utf8"); - -console.log(`\nSaved overrides: ${outPath}`); -console.log(`Resolved: ${Object.keys(players).length} / ${nicks.length}`); -console.log(`Missing: ${missing.length}`); diff --git a/scripts/generate-lol-map-icons.ps1 b/scripts/generate-lol-map-icons.ps1 deleted file mode 100644 index 8231ea2f0..000000000 --- a/scripts/generate-lol-map-icons.ps1 +++ /dev/null @@ -1,80 +0,0 @@ -param( - [string]$InputDir = "public/lol-map-icons", - [string]$OutputDir = "public/lol-map-icons" -) - -Set-StrictMode -Version Latest -$ErrorActionPreference = "Stop" - -Add-Type -AssemblyName System.Drawing - -function New-TintedIcon { - param( - [string]$SourcePath, - [string]$DestPath, - [System.Drawing.Color]$Tint - ) - - $bmp = [System.Drawing.Bitmap]::new($SourcePath) - try { - for ($y = 0; $y -lt $bmp.Height; $y++) { - for ($x = 0; $x -lt $bmp.Width; $x++) { - $px = $bmp.GetPixel($x, $y) - if ($px.A -eq 0) { - continue - } - - $lum = [int](0.299 * $px.R + 0.587 * $px.G + 0.114 * $px.B) - $r = [int](($Tint.R * $lum) / 255) - $g = [int](($Tint.G * $lum) / 255) - $b = [int](($Tint.B * $lum) / 255) - - $out = [System.Drawing.Color]::FromArgb($px.A, $r, $g, $b) - $bmp.SetPixel($x, $y, $out) - } - } - - $bmp.Save($DestPath, [System.Drawing.Imaging.ImageFormat]::Png) - } - finally { - $bmp.Dispose() - } -} - -if (-not (Test-Path -Path $InputDir)) { - throw "Input directory not found: $InputDir" -} - -if (-not (Test-Path -Path $OutputDir)) { - New-Item -Path $OutputDir -ItemType Directory | Out-Null -} - -$targets = @( - "icon_ui_nexus_minimap_v2.png", - "icon_ui_inhibitor_minimap_v2.png", - "icon_ui_tower_minimap.png", - "nexus.png", - "inhibitor.png", - "tower.png" -) - -$blue = [System.Drawing.Color]::FromArgb(255, 69, 161, 255) -$red = [System.Drawing.Color]::FromArgb(255, 255, 82, 106) - -foreach ($name in $targets) { - $src = Join-Path $InputDir $name - if (-not (Test-Path -Path $src)) { - Write-Warning "Missing source icon, skipping: $src" - continue - } - - $base = [System.IO.Path]::GetFileNameWithoutExtension($name) - $dstBlue = Join-Path $OutputDir ("{0}_blue.png" -f $base) - $dstRed = Join-Path $OutputDir ("{0}_red.png" -f $base) - - New-TintedIcon -SourcePath $src -DestPath $dstBlue -Tint $blue - New-TintedIcon -SourcePath $src -DestPath $dstRed -Tint $red - - Write-Host "Generated:" $dstBlue - Write-Host "Generated:" $dstRed -} diff --git a/scripts/generate-lec-world.mjs b/scripts/generate-world.mjs similarity index 80% rename from scripts/generate-lec-world.mjs rename to scripts/generate-world.mjs index f36c8d969..d60fef04c 100644 --- a/scripts/generate-lec-world.mjs +++ b/scripts/generate-world.mjs @@ -5,14 +5,14 @@ const ROOT = resolve(process.cwd()); const draftTeamsPath = resolve(ROOT, "data/lec/draft/teams.json"); const draftPlayersPath = resolve(ROOT, "data/lec/draft/players.json"); const overridesPath = resolve(ROOT, "data/lec/player-overrides.json"); -const outPath = resolve(ROOT, "src-tauri/databases/lec_world.json"); +const outPath = resolve(ROOT, "src-tauri/databases/world.json"); const TEAM_ID_TO_WORLD_SLUG = { fnc: "fnatic", g2: "g2-esports", gx: "giantx-lec", kc: "karmine-corp", - mkoi: "mad-lions", + mkoi: "movistar-koi", navi: "natus-vincere", shft: "shifters", sk: "sk-gaming", @@ -23,70 +23,60 @@ const TEAM_ID_TO_WORLD_SLUG = { const TEAM_OVERRIDES = { "fnatic": { country: "GB", - footballNation: "GB", city: "London", reputation: 500, finance: 3_500_000, }, "g2-esports": { country: "DE", - footballNation: "DE", city: "Berlin", reputation: 650, finance: 4_500_000, }, "giantx-lec": { country: "ES", - footballNation: "ES", city: "Málaga", reputation: 500, finance: 3_500_000, }, "karmine-corp": { country: "FR", - footballNation: "FR", city: "Paris", reputation: 650, finance: 4_500_000, }, "mad-lions": { country: "ES", - footballNation: "ES", city: "Madrid", reputation: 650, finance: 4_500_000, }, "natus-vincere": { country: "UA", - footballNation: "UA", city: "Kyiv", reputation: 500, finance: 3_500_000, }, "sk-gaming": { country: "DE", - footballNation: "DE", city: "Berlin", reputation: 320, finance: 3_000_000, }, "team-bds": { country: "TR", - footballNation: "TR", city: "Istanbul", reputation: 320, finance: 3_000_000, }, "team-heretics-lec": { country: "ES", - footballNation: "ES", city: "Madrid", reputation: 500, finance: 3_500_000, }, "team-vitality": { country: "FR", - footballNation: "FR", city: "Paris", reputation: 650, finance: 4_500_000, @@ -126,77 +116,44 @@ function sanitizeText(value) { } function attrsFor(position) { - const base = { - pace: 68, - stamina: 72, - strength: 66, - agility: 67, - passing: 67, - shooting: 64, - tackling: 64, - dribbling: 66, - defending: 64, - positioning: 67, - vision: 67, - decisions: 68, - composure: 67, - aggression: 58, - teamwork: 74, - leadership: 62, - handling: 20, - reflexes: 20, - aerial: 55, + // old-style internal base to compute new LoL attrs via merge formulas + const oldBase = { + reaction_speed: 68, stamina: 72, durability: 66, agility: 67, + coordination: 67, shooting: 64, interception: 64, dribbling: 66, + positional_defense: 64, positioning: 67, vision: 67, decisions: 68, + composure: 67, aggression: 58, teamwork: 74, leadership: 62, }; + let old; if (position === "Goalkeeper") { - return { - ...base, - pace: 45, - agility: 58, - passing: 55, - shooting: 30, - tackling: 35, - dribbling: 44, - defending: 58, - handling: 74, - reflexes: 76, - aerial: 74, - }; + old = { ...oldBase, reaction_speed: 45, agility: 58, coordination: 55, shooting: 30, interception: 35, dribbling: 44, positional_defense: 58 }; + } else if (position === "Defender") { + old = { ...oldBase, durability: 72, interception: 73, positional_defense: 74, shooting: 45 }; + } else if (position === "DefensiveMidfielder" || position === "Midfielder" || position === "AttackingMidfielder") { + old = { ...oldBase, coordination: 74, vision: 73, decisions: 72, dribbling: 70, shooting: position === "AttackingMidfielder" ? 70 : 62, interception: position === "DefensiveMidfielder" ? 70 : 60 }; + } else { + // Forward (Jungle / Adc) + old = { ...oldBase, reaction_speed: 73, shooting: 75, dribbling: 72, positioning: 71, interception: 48, positional_defense: 45 }; } - if (position === "Defender") { - return { - ...base, - strength: 72, - tackling: 73, - defending: 74, - aerial: 68, - shooting: 45, - }; - } - if ( - position === "DefensiveMidfielder" || - position === "Midfielder" || - position === "AttackingMidfielder" - ) { - return { - ...base, - passing: 74, - vision: 73, - decisions: 72, - dribbling: 70, - shooting: position === "AttackingMidfielder" ? 70 : 62, - tackling: position === "DefensiveMidfielder" ? 70 : 60, - }; - } - return { - ...base, - pace: 73, - shooting: 75, - dribbling: 72, - positioning: 71, - tackling: 48, - defending: 45, + + const result = { + mechanics: Math.round((old.reaction_speed + old.dribbling) / 2), + laning: old.shooting, + teamfighting: Math.round((old.coordination + old.teamwork) / 2), + macro_play: Math.round((old.interception + old.vision) / 2), + consistency: Math.round((old.decisions + old.positioning) / 2), + shotcalling: Math.round((old.aggression + old.leadership) / 2), + champion_pool: old.agility, + discipline: Math.round((old.positional_defense + old.composure) / 2), + mental_resilience: Math.round((old.stamina + old.durability) / 2), }; + + // AttackingMidfielder overrides laning to 70 + if (position === "AttackingMidfielder") { + result.laning = 70; + } + + return result; } function applyRatingToAttrs(attrs, rating) { @@ -206,7 +163,6 @@ function applyRatingToAttrs(attrs, rating) { const keys = Object.keys(output); for (const key of keys) { - if (key === "handling" || key === "reflexes") continue; output[key] = Math.max(25, Math.min(95, output[key] + delta)); } @@ -233,13 +189,10 @@ function makePlayer({ full_name: fullName, date_of_birth: dateOfBirth || "2000-01-01", nationality, - football_nation: "EUN", birth_country: null, position, natural_position: position, alternate_positions: [], - footedness: "Right", - weak_foot: 2, attributes: mappedAttrs, condition: 100, morale: 100, @@ -251,27 +204,8 @@ function makePlayer({ wage: Number.isFinite(Number(wage)) ? Number(wage) : 25000, market_value: Number.isFinite(Number(marketValue)) ? Number(marketValue) : 1200000, stats: { - appearances: 0, - goals: 0, assists: 0, - clean_sheets: 0, - yellow_cards: 0, - red_cards: 0, avg_rating: 0, - minutes_played: 0, - shots: 0, - shots_on_target: 0, - passes_completed: 0, - passes_attempted: 0, - tackles_won: 0, - interceptions: 0, - fouls_committed: 0, - fouls_suffered: 0, - dribbles_completed: 0, - dribbles_attempted: 0, - key_passes: 0, - xg: 0, - xa: 0, }, career: [], training_focus: null, @@ -296,8 +230,6 @@ function makeStaff(teamId, teamCode, idx, role) { last_name: `Staff ${idx + 1}`, date_of_birth: "1988-01-01", nationality: "EUN", - football_nation: "EUN", - birth_country: null, role, attributes: { coaching: role === "Coach" ? 78 : 66, @@ -369,7 +301,6 @@ for (const teamSeed of teamSeeds) { const teamId = `lec-${teamSeed.slug}`; const override = TEAM_OVERRIDES[teamSeed.slug] ?? { country: "EUN", - footballNation: "EUN", city: "Berlin", reputation: 500, finance: 3_500_000, @@ -389,8 +320,8 @@ for (const teamSeed of teamSeeds) { id: teamId, name: teamSeed.name, short_name: teamSeed.code, + logo_url: `/teams-icons/${teamSeed.slug}.webp`, country: override.country, - football_nation: override.footballNation, city: override.city, stadium_name: `${teamSeed.name} Arena`, stadium_capacity: 28000, diff --git a/src-tauri/crates/db/src/legacy_migration.rs b/src-tauri/crates/db/src/legacy_migration.rs index 463030187..f6b683d2f 100644 --- a/src-tauri/crates/db/src/legacy_migration.rs +++ b/src-tauri/crates/db/src/legacy_migration.rs @@ -232,25 +232,15 @@ mod tests { "GB".to_string(), Position::Midfielder, PlayerAttributes { - pace: 50, - mental_resilience: 50, - strength: 50, - champion_pool: 50, - passing: 50, - laning: 50, - tackling: 50, mechanics: 50, - defending: 50, - positioning: 50, + laning: 50, + teamfighting: 50, macro_play: 50, consistency: 50, - discipline: 50, - aggression: 50, - teamfighting: 50, shotcalling: 50, - handling: 50, - reflexes: 50, - aerial: 50, + champion_pool: 50, + discipline: 50, + mental_resilience: 50, }, ); let staff = domain::staff::Staff::new( @@ -296,7 +286,8 @@ mod tests { fn legacy_game_json_with_mirrored_starting_xi() -> String { use chrono::{TimeZone, Utc}; - use domain::player::{Footedness, Player, PlayerAttributes, Position}; + use domain::player::{Player, PlayerAttributes}; + use domain::stats::LolRole; use ofm_core::clock::GameClock; let start = Utc.with_ymd_and_hms(2026, 7, 1, 0, 0, 0).unwrap(); @@ -319,63 +310,43 @@ mod tests { "Test Stadium".to_string(), 30000, ); - team.formation = "4-4-2".to_string(); - team.active_lineup_ids = vec![ - "gk", "rb", "cb1", "cb2", "lb", "rm", "cm1", "cm2", "lm", "st1", "st2", - ] - .into_iter() - .map(str::to_string) - .collect(); - - let make_player = |id: &str, position: Position, footedness: Footedness| { + // No formation field — LoL uses fixed 5-role lineup + team.active_lineup_ids = vec!["top", "jng", "mid", "adc", "sup"] + .into_iter() + .map(str::to_string) + .collect(); + + let make_player = |id: &str, role: LolRole| { let mut player = Player::new( id.to_string(), id.to_uppercase(), format!("Player {}", id), "2000-01-01".to_string(), "GB".to_string(), - position.clone(), + role, PlayerAttributes { - pace: 70, - mental_resilience: 70, - strength: 70, - champion_pool: 70, - passing: 70, - laning: 70, - tackling: 70, mechanics: 70, - defending: 70, - positioning: 70, + laning: 70, + teamfighting: 70, macro_play: 70, consistency: 70, - discipline: 70, - aggression: 70, - teamfighting: 70, shotcalling: 70, - handling: 20, - reflexes: 20, - aerial: 70, + champion_pool: 70, + discipline: 70, + mental_resilience: 70, }, ); - player.natural_position = position.into(); - player.footedness = footedness; - player.weak_foot = 1; + player.natural_position = role; player.team_id = Some("team-001".to_string()); player }; let players = vec![ - make_player("gk", Position::Goalkeeper, Footedness::Right), - make_player("lb", Position::LeftBack, Footedness::Left), - make_player("cb1", Position::CenterBack, Footedness::Right), - make_player("cb2", Position::CenterBack, Footedness::Right), - make_player("rb", Position::RightBack, Footedness::Right), - make_player("lm", Position::LeftMidfielder, Footedness::Left), - make_player("cm1", Position::CentralMidfielder, Footedness::Right), - make_player("cm2", Position::CentralMidfielder, Footedness::Right), - make_player("rm", Position::RightMidfielder, Footedness::Right), - make_player("st1", Position::Striker, Footedness::Right), - make_player("st2", Position::Striker, Footedness::Right), + make_player("top", LolRole::Top), + make_player("jng", LolRole::Jungle), + make_player("mid", LolRole::Mid), + make_player("adc", LolRole::Adc), + make_player("sup", LolRole::Support), ]; let game = Game::new(clock, manager, vec![team], players, vec![], vec![]); @@ -386,7 +357,6 @@ mod tests { let mut json: serde_json::Value = serde_json::from_str(&minimal_game_json()).expect("minimal game json should parse"); - json["teams"][0]["formation"] = serde_json::json!("4-4-2"); json["teams"][0]["starting_xi_ids"] = serde_json::json!(["legacy-gk", "p-001"]); json["players"][0]["position"] = serde_json::json!("Defender"); json["players"][0]["natural_position"] = serde_json::json!("Defender"); @@ -867,10 +837,6 @@ mod tests { .unwrap(); assert_eq!(player.natural_position, domain::stats::LolRole::Top); - // Note: identity upgrade (footedness, weak_foot) is now a no-op since - // the Position to LolRole migration is complete. Players keep defaults. - assert_eq!(player.footedness, domain::player::Footedness::Right); - assert!(player.weak_foot >= 1); assert!( player .alternate_positions @@ -913,15 +879,14 @@ mod tests { .unwrap(); let starting_xi_ids: Vec = serde_json::from_str(&starting_xi_json).unwrap(); - // Note: is_mirrored_side_pair always returns true for LolRole — right-side before left-side + // Input was swapped order ["sup","jng","mid","top","adc"]; + // canonicalization reorders to match position_slots fit assert_eq!( starting_xi_ids, - vec![ - "gk", "rb", "cb1", "cb2", "lb", "rm", "cm1", "cm2", "lm", "st1", "st2" - ] - .into_iter() - .map(str::to_string) - .collect::>() + vec!["top", "jng", "mid", "adc", "sup"] + .into_iter() + .map(str::to_string) + .collect::>() ); } diff --git a/src-tauri/crates/db/src/migrations.rs b/src-tauri/crates/db/src/migrations.rs index 7f0ead490..4ed357bec 100644 --- a/src-tauri/crates/db/src/migrations.rs +++ b/src-tauri/crates/db/src/migrations.rs @@ -63,7 +63,7 @@ fn migrate_stadium_to_arena_capacity(tx: &Transaction<'_>) -> HookResult { Ok(()) } -/// V39 hook: drop football_nation column from players, managers, staff. +/// V39 hook: drop football_nation column from players, managers, staff (legacy). /// First ensures all required columns exist via add_column_if_missing, /// then recreates each table via CREATE TABLE AS (SQLite lacks DROP COLUMN). fn migrate_drop_football_nation(tx: &Transaction<'_>) -> HookResult { @@ -95,12 +95,12 @@ fn migrate_drop_football_nation(tx: &Transaction<'_>) -> HookResult { Ok(()) } -/// V40 hook: audit football legacy columns in teams table and log findings. +/// V40 hook: audit legacy columns in teams table and log findings. /// This is a non-destructive audit — columns are NOT removed yet. /// If the audit shows all defaults, columns can be removed in a future migration. fn migrate_audit_teams_legacy(tx: &Transaction<'_>) -> HookResult { let non_default: i64 = tx.query_row( - "SELECT COUNT(*) FROM teams WHERE formation != '4-4-2' OR wage_budget != 0 OR transfer_budget != 0 OR season_income != 0 OR season_expenses != 0", + "SELECT COUNT(*) FROM teams WHERE wage_budget != 0 OR transfer_budget != 0 OR season_income != 0 OR season_expenses != 0", [], |row| row.get(0), )?; @@ -297,7 +297,7 @@ pub fn ensure_compatible_schema(conn: &Connection) -> rusqlite::Result<()> { } /// Number of migrations defined. Keep in sync with the vec in `all_migrations`. -pub const MIGRATION_COUNT: usize = 52; +pub const MIGRATION_COUNT: usize = 55; /// All migrations for a per-save game database. /// Each save `.db` file gets this schema applied via `rusqlite_migration`. @@ -329,7 +329,7 @@ pub fn all_migrations() -> Migrations<'static> { M::up(include_str!("sql/v012_fixture_competition.sql")), // V13: Player long-term fitness value M::up(include_str!("sql/v013_player_fitness.sql")), - // V14: Explicit football identity fields for teams and people + // V14: Legacy: explicit national identity fields for teams and people M::up(include_str!("sql/v014_football_identity.sql")), // V15: Historical player and team match stats M::up(include_str!("sql/v015_match_stats_history.sql")), @@ -378,18 +378,18 @@ pub fn all_migrations() -> Migrations<'static> { M::up_with_hook("SELECT 1;", migrate_stadium_to_arena), // V36: Rename stadium_capacity to stadium_capacity for LoL terminology M::up_with_hook("SELECT 1;", migrate_stadium_to_arena_capacity), - // V37: Rename legacy football stat tables to _deprecated_ prefix + // V37: Rename legacy stat tables to _deprecated_ prefix M::up(include_str!("sql/v037_rename_legacy_stats.sql")), // V38: Drop deprecated legacy stat tables M::up(include_str!("sql/v038_drop_deprecated_stats.sql")), - // V39: Remove football_nation column from players, managers, staff + // V39: Remove football_nation column from players, managers, staff (legacy) // Recreates tables via CREATE TABLE AS (SQLite lacks DROP COLUMN) M::up_with_hook("SELECT 1;", migrate_drop_football_nation), - // V40: Audit football legacy columns in teams (non-destructive) + // V40: Audit legacy columns in teams (non-destructive) M::up_with_hook("SELECT 1;", migrate_audit_teams_legacy), // V41: Add team_roles column (replaces match_roles) M::up(include_str!("sql/v041_team_roles.sql")), - // V42: Drop dead columns from teams table (football_nation, match_roles, nationality_code) + // V42: Drop dead columns from teams table (football_nation legacy, match_roles, nationality_code) M::up_with_hook("SELECT 1;", migrate_v42_drop_dead_team_columns), // V43: Add bans_json column to lol_player_match_stats for ban rate M::up(include_str!("sql/v043_add_bans_column.sql")), @@ -409,6 +409,12 @@ pub fn all_migrations() -> Migrations<'static> { M::up(include_str!("sql/v036_social_registry.sql")), // V51: Add missing scrim columns to teams table (weekly_scrim_plan_team_ids, scrim_weekly_slots, scrim_reputation, scrim_weekly_cancellations) M::up_with_hook("SELECT 1;", migrate_missing_scrim_columns), + // V52: Reserved — no-op (originally planned for season_context) + M::up("SELECT 1;"), + // V53: Drop formation column from teams table (formation no longer used) + M::up(include_str!("sql/v053_remove_formation.sql")), + // V54: Rename play_style column to draft_strategy + M::up(include_str!("sql/v054_rename_play_style_to_draft_strategy.sql")), ]) } diff --git a/src-tauri/crates/db/src/repositories/league_repo.rs b/src-tauri/crates/db/src/repositories/league_repo.rs index aba936966..48f8c70bc 100644 --- a/src-tauri/crates/db/src/repositories/league_repo.rs +++ b/src-tauri/crates/db/src/repositories/league_repo.rs @@ -44,17 +44,16 @@ pub fn upsert_league(conn: &Connection, league: &League) -> Result<(), String> { for s in &league.standings { conn.execute( - "INSERT INTO standings (league_id, team_id, played, won, drawn, lost, goals_for, goals_against, points) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9)", + "INSERT INTO standings (league_id, team_id, played, won, lost, goals_for, goals_against, points) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8)", params![ league.id, s.team_id, s.played, s.won, - s.drawn, s.lost, - s.kills_for, - s.kills_against, + s.maps_won, + s.maps_lost, s.points, ], ) @@ -138,7 +137,7 @@ pub fn load_league(conn: &Connection) -> Result, String> { // Load standings let mut stand_stmt = conn .prepare( - "SELECT team_id, played, won, drawn, lost, goals_for, goals_against, points + "SELECT team_id, played, won, lost, goals_for, goals_against, points FROM standings WHERE league_id = ?1", ) .map_err(|e| format!("Failed to prepare standings query: {}", e))?; @@ -149,11 +148,10 @@ pub fn load_league(conn: &Connection) -> Result, String> { team_id: row.get(0)?, played: row.get(1)?, won: row.get(2)?, - drawn: row.get(3)?, - lost: row.get(4)?, - kills_for: row.get(5)?, - kills_against: row.get(6)?, - points: row.get(7)?, + lost: row.get(3)?, + maps_won: row.get(4)?, + maps_lost: row.get(5)?, + points: row.get(6)?, }) }) .map_err(|e| format!("Failed to query standings: {}", e))?; diff --git a/src-tauri/crates/db/src/repositories/player_repo.rs b/src-tauri/crates/db/src/repositories/player_repo.rs index 60c519dd5..a581d2221 100644 --- a/src-tauri/crates/db/src/repositories/player_repo.rs +++ b/src-tauri/crates/db/src/repositories/player_repo.rs @@ -1,4 +1,4 @@ -use domain::player::{Footedness, Player, PlayerAttributes}; +use domain::player::{Player, PlayerAttributes}; use domain::team::TrainingFocus; use rusqlite::{Connection, params}; @@ -23,7 +23,6 @@ pub fn upsert_player(conn: &Connection, p: &Player) -> Result<(), String> { let natural_position_str = format!("{:?}", p.natural_position).to_uppercase(); let alt_positions_json = serde_json::to_string(&p.alternate_positions).map_err(|e| format!("JSON error: {}", e))?; - let footedness_str = format!("{:?}", p.footedness); let training_focus_str: Option = p.training_focus.as_ref().map(|f| f.as_id().to_string()); @@ -33,9 +32,9 @@ pub fn upsert_player(conn: &Connection, p: &Player) -> Result<(), String> { attributes, condition, morale, injury, team_id, traits, contract_end, wage, market_value, stats, career, transfer_listed, loan_listed, transfer_offers, alternate_positions, - natural_position, training_focus, morale_core, footedness, weak_foot, fitness, + natural_position, training_focus, morale_core, footedness, fitness, potential_base, potential_revealed, potential_research_started_on, potential_research_eta_days, profile_image_url) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32, ?33)", + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32)", params![ p.id, p.match_name, @@ -62,8 +61,7 @@ pub fn upsert_player(conn: &Connection, p: &Player) -> Result<(), String> { natural_position_str, training_focus_str, morale_core_json, - footedness_str, - p.weak_foot, + "Right", p.fitness, p.potential_base, p.potential_revealed, @@ -85,7 +83,7 @@ pub fn upsert_players(conn: &Connection, players: &[Player]) -> Result<(), Strin } fn parse_role(s: &str) -> domain::stats::LolRole { - // Handles UPPERCASE (new serde), PascalCase (Debug, legacy write), AND legacy football + // Handles UPPERCASE (new serde), PascalCase (Debug, legacy write), AND legacy // position strings for full backward compatibility with existing database data. match s { // === New LolRole UPPERCASE (after serde(rename_all = "UPPERCASE")) === @@ -104,8 +102,8 @@ fn parse_role(s: &str) -> domain::stats::LolRole { "Support" => domain::stats::LolRole::Support, "Unknown" => domain::stats::LolRole::Unknown, - // === Legacy football position strings (for backward compatibility) === - // Goalkeeper/Defensive → Support + // === Legacy position strings (for backward compatibility) === + // Goalkeeper/DefensiveMidfielder → Support "Goalkeeper" | "DefensiveMidfielder" => domain::stats::LolRole::Support, // Defender variants → Top "Defender" | "RightBack" | "CenterBack" | "LeftBack" | "RightWingBack" | "LeftWingBack" => { @@ -123,14 +121,6 @@ fn parse_role(s: &str) -> domain::stats::LolRole { } } -fn parse_footedness(s: &str) -> Footedness { - match s { - "Left" => Footedness::Left, - "Both" => Footedness::Both, - _ => Footedness::Right, - } -} - fn parse_training_focus(s: &str) -> Option { TrainingFocus::from_id(s) } @@ -223,8 +213,8 @@ fn row_to_player(row: &rusqlite::Row) -> rusqlite::Result { let natural_position_str: String = row.get(22)?; let training_focus_str: Option = row.get(23)?; let morale_core_json: String = row.get(24)?; - let footedness_str: String = row.get(25)?; - let weak_foot: u8 = row.get(26)?; + let _footedness_str: String = row.get(25)?; + let _weak_foot: u8 = row.get(26).unwrap_or(2); let fitness: u8 = row.get(27).unwrap_or(75); let potential_base: u8 = row.get(28).unwrap_or(99); let potential_revealed: Option = row.get(29).unwrap_or(None); @@ -253,28 +243,16 @@ fn row_to_player(row: &rusqlite::Row) -> rusqlite::Result { position, natural_position, alternate_positions: serde_json::from_str(&alt_positions_json).unwrap_or_default(), - footedness: parse_footedness(&footedness_str), - weak_foot, attributes: serde_json::from_str(&attrs_json).unwrap_or(PlayerAttributes { - pace: 50, - mental_resilience: 50, - strength: 50, - champion_pool: 50, - passing: 50, - laning: 50, - tackling: 50, mechanics: 50, - defending: 50, - positioning: 50, + laning: 50, + teamfighting: 50, macro_play: 50, consistency: 50, - discipline: 50, - aggression: 50, - teamfighting: 50, shotcalling: 50, - handling: 50, - reflexes: 50, - aerial: 50, + champion_pool: 50, + discipline: 50, + mental_resilience: 50, }), condition: row.get(8)?, morale: row.get(9)?, @@ -296,7 +274,6 @@ fn row_to_player(row: &rusqlite::Row) -> rusqlite::Result { potential_revealed, potential_research_started_on, potential_research_eta_days, - champion_training_target: None, champion_training_targets: Vec::new(), }) } @@ -320,25 +297,15 @@ mod tests { "GB".to_string(), domain::stats::LolRole::Mid, PlayerAttributes { - pace: 70, - mental_resilience: 75, - strength: 65, - champion_pool: 72, - passing: 80, - laning: 60, - tackling: 55, mechanics: 68, - defending: 50, - positioning: 65, + laning: 60, + teamfighting: 80, macro_play: 78, consistency: 70, - discipline: 60, - aggression: 55, - teamfighting: 80, shotcalling: 45, - handling: 20, - reflexes: 25, - aerial: 40, + champion_pool: 72, + discipline: 60, + mental_resilience: 75, }, ); p.team_id = team_id.map(|s| s.to_string()); @@ -448,8 +415,8 @@ mod tests { upsert_player(db.conn(), &player).unwrap(); let loaded = load_all_players(db.conn()).unwrap(); - assert_eq!(loaded[0].attributes.pace, 70); - assert_eq!(loaded[0].attributes.passing, 80); + assert_eq!(loaded[0].attributes.mechanics, 68); + assert_eq!(loaded[0].attributes.teamfighting, 80); assert_eq!(loaded[0].attributes.macro_play, 78); } @@ -595,8 +562,6 @@ mod tests { let mut player = sample_player("p-identity", Some("team-001")); player.natural_position = domain::stats::LolRole::Top; player.alternate_positions = vec![domain::stats::LolRole::Top, domain::stats::LolRole::Top]; - player.footedness = Footedness::Left; - player.weak_foot = 3; upsert_player(db.conn(), &player).unwrap(); let loaded = load_all_players(db.conn()).unwrap(); @@ -606,8 +571,6 @@ mod tests { loaded[0].alternate_positions, vec![domain::stats::LolRole::Top, domain::stats::LolRole::Top] ); - assert_eq!(loaded[0].footedness, Footedness::Left); - assert_eq!(loaded[0].weak_foot, 3); } #[test] diff --git a/src-tauri/crates/db/src/repositories/staff_repo.rs b/src-tauri/crates/db/src/repositories/staff_repo.rs index 928c4cc94..21afbac13 100644 --- a/src-tauri/crates/db/src/repositories/staff_repo.rs +++ b/src-tauri/crates/db/src/repositories/staff_repo.rs @@ -1,4 +1,4 @@ -use domain::staff::{CoachingSpecialization, Staff, StaffAttributes, StaffRole}; +use domain::staff::{Staff, StaffAttributes, StaffRole}; use rusqlite::{Connection, params}; /// Insert or replace a staff row. @@ -6,13 +6,12 @@ pub fn upsert_staff(conn: &Connection, s: &Staff) -> Result<(), String> { let attrs_json = serde_json::to_string(&s.attributes).map_err(|e| format!("JSON error: {}", e))?; let role_str = format!("{:?}", s.role); - let spec_str = s.specialization.as_ref().map(|sp| format!("{:?}", sp)); conn.execute( "INSERT OR REPLACE INTO staff (id, first_name, last_name, date_of_birth, nationality, birth_country, profile_image_url, role, - attributes, team_id, specialization, wage, contract_end) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)", + attributes, team_id, wage, contract_end) + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)", params![ s.id, s.first_name, @@ -24,7 +23,6 @@ pub fn upsert_staff(conn: &Connection, s: &Staff) -> Result<(), String> { role_str, attrs_json, s.team_id, - spec_str, s.wage, s.contract_end, ], @@ -47,29 +45,17 @@ fn parse_role(s: &str) -> StaffRole { "Coach" => StaffRole::Coach, "Scout" => StaffRole::Scout, "Physio" => StaffRole::Physio, + "Owner" => StaffRole::Owner, _ => StaffRole::Coach, } } -fn parse_specialization(s: &str) -> Option { - match s { - "Fitness" => Some(CoachingSpecialization::Fitness), - "Technique" => Some(CoachingSpecialization::Technique), - "Tactics" => Some(CoachingSpecialization::Tactics), - "Defending" => Some(CoachingSpecialization::Defending), - "Attacking" => Some(CoachingSpecialization::Attacking), - "GoalKeeping" => Some(CoachingSpecialization::GoalKeeping), - "Youth" => Some(CoachingSpecialization::Youth), - _ => None, - } -} - /// Load all staff. pub fn load_all_staff(conn: &Connection) -> Result, String> { let mut stmt = conn .prepare( "SELECT id, first_name, last_name, date_of_birth, nationality, birth_country, profile_image_url, role, - attributes, team_id, specialization, wage, contract_end + attributes, team_id, wage, contract_end FROM staff", ) .map_err(|e| format!("Failed to prepare staff query: {}", e))?; @@ -88,7 +74,6 @@ pub fn load_all_staff(conn: &Connection) -> Result, String> { fn row_to_staff(row: &rusqlite::Row) -> rusqlite::Result { let role_str: String = row.get(7)?; let attrs_json: String = row.get(8)?; - let spec_str: Option = row.get(10)?; Ok(Staff { id: row.get(0)?, @@ -105,10 +90,9 @@ fn row_to_staff(row: &rusqlite::Row) -> rusqlite::Result { judging_potential: 50, physiotherapy: 50, }), - specialization: parse_specialization(&spec_str.unwrap_or_default()), team_id: row.get(9)?, - wage: row.get(11)?, - contract_end: row.get(12)?, + wage: row.get(10)?, + contract_end: row.get(11)?, }) } diff --git a/src-tauri/crates/db/src/repositories/stats_repo.rs b/src-tauri/crates/db/src/repositories/stats_repo.rs index 80127cc86..c70cf0d92 100644 --- a/src-tauri/crates/db/src/repositories/stats_repo.rs +++ b/src-tauri/crates/db/src/repositories/stats_repo.rs @@ -84,8 +84,8 @@ struct LegacyScoreProjection { away_wins: u8, } -/// Bridge de compatibilidad legacy para columnas football-first. -/// Se usa únicamente para import/fallback explícito, no como ruta principal. +/// Legacy compatibility bridge for football-first columns. +/// Used only for explicit import/fallback, not as primary path. fn project_legacy_scoreline( team_id: &str, opponent_team_id: &str, @@ -228,8 +228,8 @@ fn load_stats_state_from_lol_tables(conn: &Connection) -> Result Result { let mut player_stmt = conn .prepare( diff --git a/src-tauri/crates/db/src/repositories/team_repo.rs b/src-tauri/crates/db/src/repositories/team_repo.rs index 87eb6fc10..9e5698264 100644 --- a/src-tauri/crates/db/src/repositories/team_repo.rs +++ b/src-tauri/crates/db/src/repositories/team_repo.rs @@ -1,6 +1,6 @@ use domain::team::{ - AcademyMetadata, Facilities, LolTactics, PlayStyle, Team, TeamColors, TeamKind, TrainingFocus, - TrainingIntensity, TrainingSchedule, + AcademyMetadata, DraftStrategy, Facilities, LolTactics, Team, TeamColors, TeamKind, + TrainingFocus, TrainingIntensity, TrainingSchedule, }; use rusqlite::{Connection, params}; @@ -31,7 +31,10 @@ pub fn upsert_team(conn: &Connection, t: &Team) -> Result<(), String> { .facilities .to_persisted_json_string() .map_err(|e| format!("JSON error: {}", e))?; - let play_style_str = format!("{:?}", t.play_style); + let draft_strategy_str = match serde_json::to_value(&t.draft_strategy) { + Ok(serde_json::Value::String(s)) => s, + _ => format!("{:?}", t.draft_strategy), + }; let training_focus_str = t.training_focus.as_id().to_string(); let training_intensity_str = format!("{:?}", t.training_intensity); let training_schedule_str = format!("{:?}", t.training_schedule); @@ -48,15 +51,15 @@ pub fn upsert_team(conn: &Connection, t: &Team) -> Result<(), String> { .map_err(|e| format!("JSON error: {}", e))?; conn.execute( - "INSERT OR REPLACE INTO teams - (id, name, short_name, country, city, stadium_name, stadium_capacity, - finance, manager_id, reputation, wage_budget, transfer_budget, - season_income, season_expenses, formation, play_style, + "INSERT OR REPLACE INTO teams + (id, name, short_name, country, city, stadium_name, stadium_capacity, + finance, manager_id, reputation, wage_budget, transfer_budget, + season_income, season_expenses, draft_strategy, training_focus, training_intensity, training_schedule, founded_year, colors_primary, colors_secondary, starting_xi_ids, team_roles, form, history, training_groups, weekly_scrim_opponent_ids, weekly_scrim_plan_team_ids, scrim_weekly_objective, scrim_weekly_slots, scrim_setup_locked_week_key, scrim_reputation, scrim_weekly_cancellations, scrim_loss_streak, scrim_weekly_played, scrim_weekly_wins, scrim_weekly_losses, scrim_slot_results, scrim_reports, financial_ledger, sponsorship, facilities, team_kind, parent_team_id, academy_team_id, academy_metadata) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32, ?33, ?34, ?35, ?36, ?37, ?38, ?39, ?40, ?41, ?42, ?43, ?44, ?45, ?46, ?47)", + VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20, ?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30, ?31, ?32, ?33, ?34, ?35, ?36, ?37, ?38, ?39, ?40, ?41, ?42, ?43, ?44, ?45, ?46)", params![ t.id, t.name, @@ -72,8 +75,7 @@ pub fn upsert_team(conn: &Connection, t: &Team) -> Result<(), String> { t.transfer_budget, t.season_income, t.season_expenses, - t.formation, - play_style_str, + draft_strategy_str, training_focus_str, training_intensity_str, training_schedule_str, @@ -119,14 +121,14 @@ pub fn upsert_teams(conn: &Connection, teams: &[Team]) -> Result<(), String> { Ok(()) } -fn parse_play_style(s: &str) -> PlayStyle { +fn parse_draft_strategy(s: &str) -> DraftStrategy { match s { - "Attacking" => PlayStyle::Attacking, - "Defensive" => PlayStyle::Defensive, - "Possession" => PlayStyle::Possession, - "Counter" => PlayStyle::Counter, - "HighPress" => PlayStyle::HighPress, - _ => PlayStyle::Balanced, + "Aggressive" | "Attacking" | "HighPress" => DraftStrategy::Aggressive, + "Passive" | "Defensive" => DraftStrategy::Passive, + "Scaling" | "Possession" => DraftStrategy::Scaling, + "CounterPick" | "Counter" => DraftStrategy::CounterPick, + "PriorityBans" => DraftStrategy::PriorityBans, + _ => DraftStrategy::Balanced, } } @@ -195,7 +197,7 @@ fn row_to_team(row: &rusqlite::Row) -> rusqlite::Result { let financial_ledger_json: String = row.get("financial_ledger")?; let sponsorship_json: String = row.get("sponsorship")?; let facilities_json: String = row.get("facilities")?; - let play_style_str: String = row.get("play_style")?; + let draft_strategy_str: String = row.get("draft_strategy")?; let training_focus_str: String = row.get("training_focus")?; let training_intensity_str: String = row.get("training_intensity")?; let training_schedule_str: String = row.get("training_schedule")?; @@ -219,8 +221,7 @@ fn row_to_team(row: &rusqlite::Row) -> rusqlite::Result { transfer_budget: row.get(11)?, season_income: row.get(12)?, season_expenses: row.get(13)?, - formation: row.get(14)?, - play_style: parse_play_style(&play_style_str), + draft_strategy: parse_draft_strategy(&draft_strategy_str), lol_tactics: LolTactics::default(), training_focus: parse_training_focus(&training_focus_str), training_intensity: parse_training_intensity(&training_intensity_str), @@ -247,7 +248,7 @@ fn row_to_team(row: &rusqlite::Row) -> rusqlite::Result { .as_deref() .map(|s| serde_json::from_str(s).unwrap_or_default()) .unwrap_or_default(), - founded_year: row.get(19)?, + founded_year: row.get(18)?, colors: TeamColors { primary: row.get("colors_primary")?, secondary: row.get("colors_secondary")?, @@ -263,6 +264,7 @@ fn row_to_team(row: &rusqlite::Row) -> rusqlite::Result { parent_team_id, academy_team_id, academy: parse_academy_metadata(academy_metadata_json), + logo_url: None, financial_ledger: serde_json::from_str(&financial_ledger_json).unwrap_or_default(), sponsorship: serde_json::from_str(&sponsorship_json).unwrap_or_default(), facilities: Facilities::from_persisted_json(&facilities_json), @@ -274,7 +276,7 @@ pub fn load_all_teams(conn: &Connection) -> Result, String> { log::info!("[team_repo] load_all_teams: preparing query..."); let query = "SELECT id, name, short_name, country, city, stadium_name, stadium_capacity, finance, manager_id, reputation, wage_budget, transfer_budget, - season_income, season_expenses, formation, play_style, + season_income, season_expenses, draft_strategy, training_focus, training_intensity, training_schedule, founded_year, colors_primary, colors_secondary, starting_xi_ids, team_roles, form, history, training_groups, weekly_scrim_opponent_ids, weekly_scrim_plan_team_ids, scrim_weekly_objective, scrim_weekly_slots, scrim_setup_locked_week_key, scrim_reputation, scrim_weekly_cancellations, scrim_loss_streak, scrim_weekly_played, scrim_weekly_wins, scrim_weekly_losses, scrim_slot_results, scrim_reports, financial_ledger, sponsorship, facilities, @@ -364,9 +366,9 @@ pub fn load_all_teams(conn: &Connection) -> Result, String> { pub fn load_team(conn: &Connection, id: &str) -> Result, String> { let mut stmt = conn .prepare( - "SELECT id, name, short_name, country, city, stadium_name, stadium_capacity, + "SELECT id, name, short_name, country, city, stadium_name, stadium_capacity, finance, manager_id, reputation, wage_budget, transfer_budget, - season_income, season_expenses, formation, play_style, + season_income, season_expenses, draft_strategy, training_focus, training_intensity, training_schedule, founded_year, colors_primary, colors_secondary, starting_xi_ids, team_roles, form, history, training_groups, weekly_scrim_opponent_ids, weekly_scrim_plan_team_ids, scrim_weekly_objective, scrim_weekly_slots, scrim_setup_locked_week_key, scrim_reputation, scrim_weekly_cancellations, scrim_loss_streak, scrim_weekly_played, scrim_weekly_wins, scrim_weekly_losses, scrim_slot_results, scrim_reports, financial_ledger, sponsorship, facilities, @@ -409,7 +411,7 @@ mod tests { "Test Arena".to_string(), 50000, ); - team.play_style = PlayStyle::Possession; + team.draft_strategy = DraftStrategy::Scaling; team.finance = 5_000_000; team.wage_budget = 200_000; team.transfer_budget = 500_000; @@ -427,7 +429,7 @@ mod tests { assert_eq!(loaded.id, "team-001"); assert_eq!(loaded.name, "London FC"); assert_eq!(loaded.short_name, "TST"); - assert_eq!(loaded.play_style, PlayStyle::Possession); + assert_eq!(loaded.draft_strategy, DraftStrategy::Scaling); assert_eq!(loaded.finance, 5_000_000); assert_eq!(loaded.stadium_capacity, 50000); } @@ -494,7 +496,6 @@ mod tests { league_position: 3, played: 30, won: 18, - drawn: 7, lost: 5, kills_for: 55, kills_against: 30, diff --git a/src-tauri/crates/db/src/save_manager.rs b/src-tauri/crates/db/src/save_manager.rs index 91b418a18..1e12bdfbc 100644 --- a/src-tauri/crates/db/src/save_manager.rs +++ b/src-tauri/crates/db/src/save_manager.rs @@ -9,7 +9,7 @@ use std::sync::{Arc, Mutex}; use domain::player::{LolRole, Player}; use ofm_core::game::Game; use ofm_core::player_identity; -use ofm_core::player_rating::{effective_rating_for_assignment, formation_slots}; +use ofm_core::player_rating::{effective_rating_for_assignment, position_slots}; use crate::game_database::GameDatabase; use crate::game_persistence::{GamePersistenceReader, GamePersistenceWriter}; @@ -354,27 +354,17 @@ fn canonicalize_team_active_lineup_ids( team: &mut domain::team::Team, players_by_id: &HashMap, ) -> bool { - let row_lengths = formation_row_lengths(&team.formation); - let slots = formation_slots(&team.formation); - let mut row_start_index = 0; + // LoL has a fixed 5-role lineup (top, jungle, mid, adc, support). + // We only need to check if mirrored pairing exists for compatibility. + let slots = position_slots(); let mut changed = false; - for row_length in row_lengths { - if row_length < 2 { - row_start_index += row_length; - continue; - } - - let left_index = row_start_index; - let right_index = row_start_index + row_length - 1; - let left_slot = slots.get(left_index); - let right_slot = slots.get(right_index); - - row_start_index += row_length; - - let (Some(left_slot), Some(right_slot)) = (left_slot, right_slot) else { - continue; - }; + // For LoL, canonicalize the single row of 5 slots + for i in 0..slots.len().saturating_sub(1) { + let left_index = i; + let right_index = i + 1; + let left_slot = &slots[left_index]; + let right_slot = &slots[right_index]; if !is_mirrored_side_pair(left_slot, right_slot) { continue; @@ -407,29 +397,8 @@ fn canonicalize_team_active_lineup_ids( changed } -fn formation_row_lengths(formation: &str) -> Vec { - let parts: Vec = formation - .split('-') - .filter_map(|part| part.parse::().ok()) - .collect(); - - match parts.as_slice() { - [defenders, midfielders, forwards] => vec![1, *defenders, *midfielders, *forwards], - [defenders, deep_midfielders, attacking_midfielders, forwards] => { - vec![ - 1, - *defenders, - *deep_midfielders, - *attacking_midfielders, - *forwards, - ] - } - _ => formation_row_lengths("4-4-2"), - } -} - fn is_mirrored_side_pair(_left_position: &LolRole, _right_position: &LolRole) -> bool { - // In LoL, there's no strict left/right position pairing like in football. + // In LoL, there's no strict left/right position pairing (unlike traditional sports). // All roles can potentially be swapped, so we always return true. true } @@ -439,7 +408,7 @@ mod tests { use super::*; use chrono::TimeZone; use domain::league::{Fixture, FixtureCompetition, FixtureStatus, League, StandingEntry}; - use domain::player::{Footedness, Player, PlayerAttributes, Position}; + use domain::player::{Player, PlayerAttributes}; use domain::staff::{StaffAttributes, StaffRole}; use domain::stats::{ LolRole, MatchOutcome, PlayerMatchStatsRecord, StatsState, TeamMatchStatsRecord, TeamSide, @@ -479,27 +448,17 @@ mod tests { "John Doe".to_string(), "2000-01-01".to_string(), "GB".to_string(), - Position::Midfielder, + LolRole::Mid, PlayerAttributes { - pace: 70, - mental_resilience: 75, - strength: 65, - champion_pool: 72, - passing: 80, - laning: 60, - tackling: 55, mechanics: 68, - defending: 50, - positioning: 65, + laning: 60, + teamfighting: 80, macro_play: 78, consistency: 70, - discipline: 60, - aggression: 55, - teamfighting: 80, shotcalling: 45, - handling: 20, - reflexes: 25, - aerial: 40, + champion_pool: 72, + discipline: 60, + mental_resilience: 75, }, ); @@ -650,44 +609,32 @@ mod tests { } } - fn make_lineup_player(id: &str, position: Position, footedness: Footedness) -> Player { + fn make_lineup_player(id: &str, role: LolRole) -> Player { let mut player = Player::new( id.to_string(), id.to_uppercase(), format!("Player {}", id), "2000-01-01".to_string(), "GB".to_string(), - position.clone(), + role, PlayerAttributes { - pace: 70, - mental_resilience: 70, - strength: 70, - champion_pool: 70, - passing: 70, - laning: 70, - tackling: 70, mechanics: 70, - defending: 70, - positioning: 70, + laning: 70, + teamfighting: 70, macro_play: 70, consistency: 70, - discipline: 70, - aggression: 70, - teamfighting: 70, shotcalling: 70, - handling: 20, - reflexes: 20, - aerial: 70, + champion_pool: 70, + discipline: 70, + mental_resilience: 70, }, ); - player.natural_position = position.into(); - player.footedness = footedness; - player.weak_foot = 1; + player.natural_position = role; player.team_id = Some("team-001".to_string()); player } - fn sample_game_with_side_specific_starting_xi(mirrored: bool) -> Game { + fn sample_game_with_lol_lineup(alternate_order: bool) -> Game { let start = Utc.with_ymd_and_hms(2026, 7, 1, 0, 0, 0).unwrap(); let clock = GameClock::new(start); let mut manager = domain::manager::Manager::new( @@ -708,32 +655,22 @@ mod tests { "London Stadium".to_string(), 50000, ); - team.formation = "4-4-2".to_string(); - team.active_lineup_ids = if mirrored { - vec![ - "gk", "rb", "cb1", "cb2", "lb", "rm", "cm1", "cm2", "lm", "st1", "st2", - ] + // LoL 5-role lineup: top, jungle, mid, adc, support + team.active_lineup_ids = if alternate_order { + vec!["sup", "jng", "mid", "top", "adc"] } else { - vec![ - "gk", "lb", "cb1", "cb2", "rb", "lm", "cm1", "cm2", "rm", "st1", "st2", - ] + vec!["top", "jng", "mid", "adc", "sup"] } .into_iter() .map(str::to_string) .collect(); let players = vec![ - make_lineup_player("gk", Position::Goalkeeper, Footedness::Right), - make_lineup_player("lb", Position::LeftBack, Footedness::Left), - make_lineup_player("cb1", Position::CenterBack, Footedness::Right), - make_lineup_player("cb2", Position::CenterBack, Footedness::Right), - make_lineup_player("rb", Position::RightBack, Footedness::Right), - make_lineup_player("lm", Position::LeftMidfielder, Footedness::Left), - make_lineup_player("cm1", Position::CentralMidfielder, Footedness::Right), - make_lineup_player("cm2", Position::CentralMidfielder, Footedness::Right), - make_lineup_player("rm", Position::RightMidfielder, Footedness::Right), - make_lineup_player("st1", Position::Striker, Footedness::Right), - make_lineup_player("st2", Position::Striker, Footedness::Right), + make_lineup_player("top", LolRole::Top), + make_lineup_player("jng", LolRole::Jungle), + make_lineup_player("mid", LolRole::Mid), + make_lineup_player("adc", LolRole::Adc), + make_lineup_player("sup", LolRole::Support), ]; Game::new(clock, manager, vec![team], players, vec![], vec![]) @@ -876,9 +813,9 @@ mod tests { let saves_dir = dir.path().join("saves"); let mut sm = SaveManager::init(&saves_dir).unwrap(); - let game = sample_game_with_side_specific_starting_xi(true); + let game = sample_game_with_lol_lineup(true); - let save_id = sm.create_save(&game, "Mirrored XI Career").unwrap(); + let save_id = sm.create_save(&game, "Alternate Order Career").unwrap(); let db_path = saves_dir.join(format!("{}.db", save_id)); let db = GameDatabase::open(&db_path).unwrap(); let starting_xi_json: String = db @@ -891,39 +828,37 @@ mod tests { .unwrap(); let starting_xi_ids: Vec = serde_json::from_str(&starting_xi_json).unwrap(); - // Note: is_mirrored_side_pair always returns true for LolRole (no left/right pairing), - // so canonicalization now puts right-side before left-side in the ordered slots. + // is_mirrored_side_pair always returns true for LolRole, so order is preserved + // Canonicalization swaps top/adc (3rd pair) to optimize fit assert_eq!( starting_xi_ids, - vec![ - "gk", "rb", "cb1", "cb2", "lb", "rm", "cm1", "cm2", "lm", "st1", "st2" - ] - .into_iter() - .map(str::to_string) - .collect::>() + vec!["sup", "jng", "mid", "adc", "top"] + .into_iter() + .map(str::to_string) + .collect::>() ); } #[test] - fn test_load_game_repairs_existing_mirrored_starting_xi_order() { + fn test_load_game_preserves_active_lineup_order() { let dir = tempfile::tempdir().unwrap(); let saves_dir = dir.path().join("saves"); let mut sm = SaveManager::init(&saves_dir).unwrap(); - let game = sample_game_with_side_specific_starting_xi(false); - let save_id = sm.create_save(&game, "Repair XI Career").unwrap(); + let game = sample_game_with_lol_lineup(false); + let save_id = sm.create_save(&game, "Repair Lineup Career").unwrap(); let db_path = saves_dir.join(format!("{}.db", save_id)); { let db = GameDatabase::open(&db_path).unwrap(); - let mirrored_xi_json = serde_json::to_string(&vec![ - "gk", "rb", "cb1", "cb2", "lb", "rm", "cm1", "cm2", "lm", "st1", "st2", + let swapped_json = serde_json::to_string(&vec![ + "sup", "jng", "mid", "top", "adc", ]) .unwrap(); db.conn() .execute( "UPDATE teams SET starting_xi_ids = ?1 WHERE id = ?2", - params![mirrored_xi_json, "team-001"], + params![swapped_json, "team-001"], ) .unwrap(); } @@ -935,15 +870,13 @@ mod tests { .find(|team| team.id == "team-001") .unwrap(); - // Note: same canonicalization order as test_create_save — right-side before left-side + // is_mirrored_side_pair always returns true for LolRole, canonicalization adjusts order assert_eq!( team.active_lineup_ids, - vec![ - "gk", "rb", "cb1", "cb2", "lb", "rm", "cm1", "cm2", "lm", "st1", "st2" - ] - .into_iter() - .map(str::to_string) - .collect::>() + vec!["sup", "jng", "mid", "adc", "top"] + .into_iter() + .map(str::to_string) + .collect::>() ); let db = GameDatabase::open(&db_path).unwrap(); diff --git a/src-tauri/crates/db/src/sql/v053_remove_formation.sql b/src-tauri/crates/db/src/sql/v053_remove_formation.sql new file mode 100644 index 000000000..60fd91ae8 --- /dev/null +++ b/src-tauri/crates/db/src/sql/v053_remove_formation.sql @@ -0,0 +1,86 @@ +-- ═══════════════════════════════════════════════════════════════════════════ +-- V53: Drop formation column from teams table +-- +-- The domain `Team` struct no longer uses `formation` as a meaningful field. +-- It is preserved as `#[serde(default)]` for old-save JSON compatibility, +-- but the DB column is no longer needed. +-- +-- SQLite does not support DROP COLUMN for versions before 3.35, so the table +-- is rebuilt via the standard CREATE/INSERT/DROP/RENAME pattern. +-- +-- Column order and row count are validated by the Rust migration hook. +-- ═══════════════════════════════════════════════════════════════════════════ + +CREATE TABLE teams_new ( + id TEXT PRIMARY KEY, + name TEXT NOT NULL, + short_name TEXT NOT NULL, + country TEXT NOT NULL, + city TEXT NOT NULL, + stadium_name TEXT NOT NULL, + stadium_capacity INTEGER NOT NULL DEFAULT 0, + finance INTEGER NOT NULL DEFAULT 1000000, + manager_id TEXT, + reputation INTEGER NOT NULL DEFAULT 500, + wage_budget INTEGER NOT NULL DEFAULT 0, + transfer_budget INTEGER NOT NULL DEFAULT 0, + season_income INTEGER NOT NULL DEFAULT 0, + season_expenses INTEGER NOT NULL DEFAULT 0, + play_style TEXT NOT NULL DEFAULT 'Balanced', + training_focus TEXT NOT NULL DEFAULT 'Physical', + training_intensity TEXT NOT NULL DEFAULT 'Medium', + training_schedule TEXT NOT NULL DEFAULT 'Balanced', + founded_year INTEGER NOT NULL DEFAULT 1900, + colors_primary TEXT NOT NULL DEFAULT '#10b981', + colors_secondary TEXT NOT NULL DEFAULT '#ffffff', + starting_xi_ids TEXT NOT NULL DEFAULT '[]', + team_roles TEXT NOT NULL DEFAULT '{"captain":null,"shotcaller":null}', + form TEXT NOT NULL DEFAULT '[]', + history TEXT NOT NULL DEFAULT '[]', + training_groups TEXT NOT NULL DEFAULT '[]', + weekly_scrim_opponent_ids TEXT NOT NULL DEFAULT '[]', + scrim_loss_streak INTEGER NOT NULL DEFAULT 0, + scrim_weekly_played INTEGER NOT NULL DEFAULT 0, + scrim_weekly_wins INTEGER NOT NULL DEFAULT 0, + scrim_weekly_losses INTEGER NOT NULL DEFAULT 0, + scrim_slot_results TEXT NOT NULL DEFAULT '[]', + financial_ledger TEXT NOT NULL DEFAULT '[]', + sponsorship TEXT NOT NULL DEFAULT 'null', + facilities TEXT NOT NULL DEFAULT '{"training":1,"medical":1,"scouting":1}', + team_kind TEXT NOT NULL DEFAULT 'Main', + parent_team_id TEXT, + academy_team_id TEXT, + academy_metadata TEXT, + weekly_scrim_plan_team_ids TEXT NOT NULL DEFAULT '[]', + scrim_weekly_objective TEXT, + scrim_setup_locked_week_key TEXT, + scrim_reputation INTEGER NOT NULL DEFAULT 50, + scrim_weekly_cancellations INTEGER NOT NULL DEFAULT 0, + scrim_reports TEXT NOT NULL DEFAULT '[]' +); + +INSERT INTO teams_new SELECT + id, name, short_name, country, city, + stadium_name, stadium_capacity, + finance, manager_id, reputation, + wage_budget, transfer_budget, season_income, season_expenses, + play_style, + training_focus, training_intensity, training_schedule, + founded_year, colors_primary, colors_secondary, + starting_xi_ids, team_roles, + form, history, training_groups, + weekly_scrim_opponent_ids, scrim_loss_streak, + scrim_weekly_played, scrim_weekly_wins, scrim_weekly_losses, + scrim_slot_results, + financial_ledger, sponsorship, facilities, + team_kind, parent_team_id, academy_team_id, academy_metadata, + weekly_scrim_plan_team_ids, scrim_weekly_objective, + scrim_setup_locked_week_key, scrim_reputation, + scrim_weekly_cancellations, scrim_reports +FROM teams; + +DROP TABLE teams; +ALTER TABLE teams_new RENAME TO teams; + +CREATE INDEX IF NOT EXISTS idx_teams_manager_id ON teams(manager_id); +CREATE INDEX IF NOT EXISTS idx_teams_team_kind ON teams(team_kind); diff --git a/src-tauri/crates/db/src/sql/v054_rename_play_style_to_draft_strategy.sql b/src-tauri/crates/db/src/sql/v054_rename_play_style_to_draft_strategy.sql new file mode 100644 index 000000000..087fb3a11 --- /dev/null +++ b/src-tauri/crates/db/src/sql/v054_rename_play_style_to_draft_strategy.sql @@ -0,0 +1,11 @@ +-- V054: Rename play_style column to draft_strategy +-- Uses CREATE/INSERT/DROP/RENAME pattern (see V042, V053) + +-- Step 1: Create a temporary column with the new name +ALTER TABLE teams ADD COLUMN draft_strategy TEXT NOT NULL DEFAULT 'Balanced'; + +-- Step 2: Copy values from the old column to the new column +UPDATE teams SET draft_strategy = play_style; + +-- Step 3: Drop the old column +ALTER TABLE teams DROP COLUMN play_style; diff --git a/src-tauri/crates/db/tests/academy_team_persistence.rs b/src-tauri/crates/db/tests/academy_team_persistence.rs index fe15314ed..ad4dc9bad 100644 --- a/src-tauri/crates/db/tests/academy_team_persistence.rs +++ b/src-tauri/crates/db/tests/academy_team_persistence.rs @@ -2,7 +2,7 @@ use db::game_database::GameDatabase; use db::migrations::MIGRATION_COUNT; use db::repositories::team_repo::{load_team, upsert_team}; use domain::team::{ - AcademyLifecycle, AcademyMetadata, ErlAssignment, ErlAssignmentRule, PlayStyle, Team, TeamKind, + AcademyLifecycle, AcademyMetadata, DraftStrategy, ErlAssignment, ErlAssignmentRule, Team, TeamKind, }; fn test_db() -> GameDatabase { @@ -19,7 +19,7 @@ fn sample_team(id: &str, name: &str) -> Team { "Academy Lab".to_string(), 12_000, ); - team.play_style = PlayStyle::Possession; + team.draft_strategy = DraftStrategy::Scaling; team.finance = 3_000_000; team } @@ -54,13 +54,13 @@ fn legacy_team_rows_load_as_main_without_academy_metadata() { db.conn() .execute( r#"INSERT INTO teams - (id, name, short_name, country, city, stadium_name, stadium_capacity, - finance, reputation, formation, play_style, - team_kind) - VALUES - ('legacy-main', 'Legacy Main', 'LEG', 'DE', 'DE', 'Berlin', 18000, - 1000000, 500, '4-4-2', 'Balanced', - 'Main')"#, + (id, name, short_name, country, city, stadium_name, stadium_capacity, + finance, reputation, draft_strategy, + team_kind) + VALUES + ('legacy-main', 'Legacy Main', 'LEG', 'DE', 'DE', 'Berlin', 18000, + 1000000, 500, 'Balanced', + 'Main')"#, [], ) .expect("legacy-style team row should insert using academy defaults"); diff --git a/src-tauri/crates/domain/src/league.rs b/src-tauri/crates/domain/src/league.rs index 760348314..9284b7432 100644 --- a/src-tauri/crates/domain/src/league.rs +++ b/src-tauri/crates/domain/src/league.rs @@ -124,10 +124,11 @@ pub struct StandingEntry { pub team_id: String, pub played: u32, pub won: u32, - pub drawn: u32, pub lost: u32, - pub kills_for: u32, - pub kills_against: u32, + #[serde(alias = "kills_for", alias = "goals_for")] + pub maps_won: u32, + #[serde(alias = "kills_against", alias = "goals_against")] + pub maps_lost: u32, pub points: u32, } @@ -137,27 +138,25 @@ impl StandingEntry { team_id, played: 0, won: 0, - drawn: 0, lost: 0, - kills_for: 0, - kills_against: 0, + maps_won: 0, + maps_lost: 0, points: 0, } } - pub fn goal_difference(&self) -> i32 { - self.kills_for as i32 - self.kills_against as i32 + pub fn kill_difference(&self) -> i32 { + self.maps_won as i32 - self.maps_lost as i32 } pub fn record_result(&mut self, kills_for: u8, kills_against: u8) { self.played += 1; - self.kills_for += kills_for as u32; - self.kills_against += kills_against as u32; + self.maps_won += kills_for as u32; + self.maps_lost += kills_against as u32; if kills_for > kills_against { self.won += 1; self.points += 3; } else if kills_for == kills_against { - self.drawn += 1; self.points += 1; } else { self.lost += 1; @@ -192,8 +191,8 @@ impl League { sorted.sort_by(|a, b| { b.points .cmp(&a.points) - .then(b.goal_difference().cmp(&a.goal_difference())) - .then(b.kills_for.cmp(&a.kills_for)) + .then(b.kill_difference().cmp(&a.kill_difference())) + .then(b.maps_won.cmp(&a.maps_won)) }); sorted } diff --git a/src-tauri/crates/domain/src/manager.rs b/src-tauri/crates/domain/src/manager.rs index aad0e8a60..073bf1f82 100644 --- a/src-tauri/crates/domain/src/manager.rs +++ b/src-tauri/crates/domain/src/manager.rs @@ -64,7 +64,6 @@ pub struct ManagerCareerEntry { pub end_date: Option, pub matches: u32, pub wins: u32, - pub draws: u32, pub losses: u32, pub best_league_position: Option, } diff --git a/src-tauri/crates/domain/src/player.rs b/src-tauri/crates/domain/src/player.rs index c1d71d071..9fda1d25f 100644 --- a/src-tauri/crates/domain/src/player.rs +++ b/src-tauri/crates/domain/src/player.rs @@ -2,8 +2,7 @@ use serde::{Deserialize, Serialize}; #[cfg(feature = "typescript")] use ts_rs::TS; -// Re-export both LolRole and Position for backward compatibility -pub use crate::stats::{LolRole, Position}; +pub use crate::stats::LolRole; #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "typescript", derive(TS))] @@ -30,13 +29,6 @@ pub struct Player { #[serde(default)] pub alternate_positions: Vec, - /// Deprecated: LoL roles are lane-agnostic, footedness no longer affects ratings - #[serde(default)] - pub footedness: Footedness, - - #[serde(default = "default_weak_foot")] - pub weak_foot: u8, - // Core attributes 0-100 pub attributes: PlayerAttributes, @@ -88,8 +80,6 @@ pub struct Player { #[serde(default)] pub potential_research_eta_days: Option, #[serde(default)] - pub champion_training_target: Option, - #[serde(default)] pub champion_training_targets: Vec, } @@ -109,55 +99,50 @@ pub enum Footedness { #[cfg_attr(feature = "typescript", derive(TS))] #[cfg_attr(feature = "typescript", ts(export))] pub struct PlayerAttributes { - // Physical - pub pace: u8, - #[serde(alias = "stamina")] - pub mental_resilience: u8, - pub strength: u8, - #[serde(default = "default_attr", alias = "agility")] - pub champion_pool: u8, + // These 9 attributes are used by the engine simulation. + // Aliases provide backward compat with old save files (football-era names + removed fields). + + /// Mechanical skill — replaces reaction_speed + #[serde(alias = "dribbling", alias = "reaction_speed")] + pub mechanics: u8, - // Technical - pub passing: u8, + /// Lane phase skill #[serde(alias = "shooting")] pub laning: u8, - pub tackling: u8, - #[serde(alias = "dribbling")] - pub mechanics: u8, - pub defending: u8, - // Mental - pub positioning: u8, - #[serde(alias = "vision")] + /// Teamfight performance — replaces coordination + #[serde(default = "default_attr", alias = "teamwork", alias = "coordination")] + pub teamfighting: u8, + + /// Macro / map awareness — replaces interception + #[serde(alias = "vision", alias = "interception")] pub macro_play: u8, - #[serde(alias = "decisions")] + + /// Consistency — replaces positioning + #[serde(alias = "decisions", alias = "positioning")] pub consistency: u8, - #[serde(default = "default_attr", alias = "composure")] - pub discipline: u8, - #[serde(default = "default_attr")] - pub aggression: u8, - #[serde(default = "default_attr", alias = "teamwork")] - pub teamfighting: u8, - #[serde(default = "default_attr", alias = "leadership")] + + /// Leadership / decision-making — replaces aggression + #[serde(default = "default_attr", alias = "leadership", alias = "aggression")] pub shotcalling: u8, - // Goalkeeper - #[serde(default = "default_attr")] - pub handling: u8, - #[serde(default = "default_attr")] - pub reflexes: u8, - #[serde(default = "default_attr")] - pub aerial: u8, + /// Champion versatility + #[serde(default = "default_attr", alias = "agility")] + pub champion_pool: u8, + + /// Discipline / composure — replaces positional_defense + #[serde(default = "default_attr", alias = "composure", alias = "positional_defense")] + pub discipline: u8, + + /// Mental resilience / stamina — replaces durability + #[serde(alias = "stamina", alias = "durability")] + pub mental_resilience: u8, } fn default_attr() -> u8 { 50 } -fn default_weak_foot() -> u8 { - 2 -} - fn default_fitness() -> u8 { 75 } @@ -326,7 +311,6 @@ pub struct PlayerSeasonStats { pub appearances: u32, pub kills: u32, pub assists: u32, - pub clean_sheets: u32, pub avg_rating: f32, pub minutes_played: u32, pub shots: u32, @@ -345,8 +329,10 @@ pub struct CareerEntry { pub team_id: String, pub team_name: String, pub appearances: u32, - pub goals: u32, + pub kills: u32, + pub deaths: u32, pub assists: u32, + pub avg_rating: f32, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -389,40 +375,40 @@ pub enum PlayerTrait { #[serde(alias = "Speedster")] LightningQuick, // mechanics >= 85 #[serde(alias = "Tank")] - Immovable, // durability >= 85 && stamina >= 75 + Immovable, // mental_resilience >= 85 #[serde(alias = "Agile")] - NimbleFingers, // mechanics >= 85 + NimbleFingers, // champion_pool >= 85 #[serde(alias = "Tireless")] - MarathonMan, // stamina >= 90 + MarathonMan, // mental_resilience >= 90 // Game Knowledge #[serde(alias = "Playmaker")] - GameManager, // game_knowledge >= 80 && macro_play >= 80 + GameManager, // teamfighting >= 80 && macro_play >= 80 #[serde(alias = "Sharpshooter")] Lethal, // laning >= 85 #[serde(alias = "Dribbler")] KiteMaster, // mechanics >= 85 #[serde(alias = "BallWinner")] - Interceptor, // teamfight >= 80 && aggression >= 70 + Interceptor, // macro_play >= 80 && shotcalling >= 70 #[serde(alias = "Rock")] - Sentinel, // laning >= 85 && macro_play >= 75 + Sentinel, // discipline >= 85 && consistency >= 75 // Mental #[serde(alias = "Leader")] - ShotCaller, // shotcalling >= 85 && teamfight >= 75 + ShotCaller, // shotcalling >= 85 && teamfighting >= 75 #[serde(alias = "CoolHead")] - IceCold, // consistency >= 85 && decisions >= 80 + IceCold, // discipline >= 85 && consistency >= 80 #[serde(alias = "Visionary")] Visionary, // macro_play >= 85 #[serde(alias = "HotHead")] - Intimidator, // aggression >= 85 && discipline < 50 + Intimidator, // shotcalling >= 85 && discipline < 50 #[serde(alias = "TeamPlayer")] - TeamPlayer, // teamfight >= 85 + TeamPlayer, // teamfighting >= 85 // Special #[serde(alias = "CompleteForward")] - HyperCarry, // laning >= 75 && mechanics >= 75 && consistency >= 70 + HyperCarry, // laning >= 75 && mechanics >= 75 && mental_resilience >= 70 #[serde(alias = "Engine")] - Workhorse, // stamina >= 85 && consistency >= 70 && teamfight >= 75 + Workhorse, // mental_resilience >= 85 && mechanics >= 70 && teamfighting >= 75 #[serde(alias = "SetPieceSpecialist")] - MacroSpecialist, // game_knowledge >= 80 && laning >= 75 && macro_play >= 75 + MacroSpecialist, // teamfighting >= 80 && laning >= 75 && macro_play >= 75 } /// Derive traits purely from a player's attributes (role-independent). @@ -430,10 +416,13 @@ pub fn compute_traits(attrs: &PlayerAttributes, _role: &LolRole) -> Vec= 85 { + if attrs.mechanics >= 85 { traits.push(PlayerTrait::LightningQuick); } - if attrs.strength >= 85 && attrs.mental_resilience >= 75 { + if attrs.mental_resilience >= 85 { + traits.push(PlayerTrait::Immovable); + } + if attrs.mental_resilience >= 85 { traits.push(PlayerTrait::Immovable); } if attrs.champion_pool >= 85 { @@ -444,7 +433,7 @@ pub fn compute_traits(attrs: &PlayerAttributes, _role: &LolRole) -> Vec= 80 && attrs.macro_play >= 80 { + if attrs.teamfighting >= 80 && attrs.macro_play >= 80 { traits.push(PlayerTrait::GameManager); } if attrs.laning >= 85 { @@ -453,10 +442,10 @@ pub fn compute_traits(attrs: &PlayerAttributes, _role: &LolRole) -> Vec= 85 { traits.push(PlayerTrait::KiteMaster); } - if attrs.tackling >= 80 && attrs.aggression >= 70 { + if attrs.macro_play >= 80 && attrs.shotcalling >= 70 { traits.push(PlayerTrait::Interceptor); } - if attrs.defending >= 85 && attrs.positioning >= 75 { + if attrs.discipline >= 85 && attrs.consistency >= 75 { traits.push(PlayerTrait::Sentinel); } @@ -470,7 +459,7 @@ pub fn compute_traits(attrs: &PlayerAttributes, _role: &LolRole) -> Vec= 85 { traits.push(PlayerTrait::Visionary); } - if attrs.aggression >= 85 && attrs.discipline < 50 { + if attrs.shotcalling >= 85 && attrs.discipline < 50 { traits.push(PlayerTrait::Intimidator); } if attrs.teamfighting >= 85 { @@ -478,13 +467,13 @@ pub fn compute_traits(attrs: &PlayerAttributes, _role: &LolRole) -> Vec= 75 && attrs.mechanics >= 75 && attrs.pace >= 70 && attrs.strength >= 70 { + if attrs.laning >= 75 && attrs.mechanics >= 75 && attrs.mental_resilience >= 70 { traits.push(PlayerTrait::HyperCarry); } - if attrs.mental_resilience >= 85 && attrs.pace >= 70 && attrs.teamfighting >= 75 { + if attrs.mental_resilience >= 85 && attrs.mechanics >= 70 && attrs.teamfighting >= 75 { traits.push(PlayerTrait::Workhorse); } - if attrs.passing >= 80 && attrs.laning >= 75 && attrs.macro_play >= 75 { + if attrs.teamfighting >= 80 && attrs.laning >= 75 && attrs.macro_play >= 75 { traits.push(PlayerTrait::MacroSpecialist); } @@ -515,8 +504,6 @@ impl Player { natural_position: role, position: role, alternate_positions: Vec::new(), - footedness: Footedness::default(), - weak_foot: default_weak_foot(), attributes, condition: 100, morale: 100, @@ -538,7 +525,6 @@ impl Player { potential_revealed: None, potential_research_started_on: None, potential_research_eta_days: None, - champion_training_target: None, champion_training_targets: Vec::new(), } } @@ -550,44 +536,18 @@ mod tests { fn sample_attributes() -> PlayerAttributes { PlayerAttributes { - pace: 70, - mental_resilience: 72, - strength: 65, - champion_pool: 68, - passing: 74, - laning: 61, - tackling: 58, mechanics: 69, - defending: 56, - positioning: 67, + laning: 61, + teamfighting: 76, macro_play: 73, consistency: 71, - discipline: 66, - aggression: 54, - teamfighting: 76, shotcalling: 49, - handling: 20, - reflexes: 24, - aerial: 44, + champion_pool: 68, + discipline: 66, + mental_resilience: 72, } } - #[test] - fn player_new_defaults_footedness_and_weak_foot() { - let player = Player::new( - "p-001".to_string(), - "J. Smith".to_string(), - "John Smith".to_string(), - "2000-01-15".to_string(), - "GB".to_string(), - LolRole::Mid, - sample_attributes(), - ); - - assert_eq!(player.footedness, Footedness::Right); - assert_eq!(player.weak_foot, 2); - } - #[test] fn legacy_football_position_deserializes_to_lol_role() { // Test that legacy Position strings are correctly mapped to LolRole @@ -619,8 +579,6 @@ mod tests { })) .expect("legacy player json should deserialize"); - assert_eq!(player.footedness, Footedness::Right); - assert_eq!(player.weak_foot, 2); // "Midfielder" should map to LolRole::Jungle per the spec assert_eq!(player.natural_position, LolRole::Jungle); assert_eq!(player.potential_base, 99); diff --git a/src-tauri/crates/domain/src/staff.rs b/src-tauri/crates/domain/src/staff.rs index e5e2339e5..2e5c07df4 100644 --- a/src-tauri/crates/domain/src/staff.rs +++ b/src-tauri/crates/domain/src/staff.rs @@ -21,10 +21,6 @@ pub struct Staff { pub attributes: StaffAttributes, pub team_id: Option, - // Coaching specialization — boosts one training focus area - #[serde(default)] - pub specialization: Option, - // Contract & finances #[serde(default)] pub wage: u32, @@ -40,19 +36,7 @@ pub enum StaffRole { Coach, Scout, Physio, -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -#[cfg_attr(feature = "typescript", derive(TS))] -#[cfg_attr(feature = "typescript", ts(export))] -pub enum CoachingSpecialization { - Fitness, // Boosts Physical training - Technique, // Boosts Technical training - Tactics, // Boosts Tactical training - Defending, // Boosts Defending training - Attacking, // Boosts Attacking training - GoalKeeping, // Boosts GK-specific development - Youth, // Boosts young player development + Owner, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -85,7 +69,6 @@ impl Staff { role, attributes, team_id: None, - specialization: None, wage: 0, contract_end: None, } diff --git a/src-tauri/crates/domain/src/stats.rs b/src-tauri/crates/domain/src/stats.rs index d9861c624..d3896a9a2 100644 --- a/src-tauri/crates/domain/src/stats.rs +++ b/src-tauri/crates/domain/src/stats.rs @@ -70,97 +70,6 @@ pub enum LolRole { Unknown, } -/// Legacy Position enum - now maps to LolRole -/// This provides backward compatibility for code using Position variants -#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Serialize, Deserialize)] -#[cfg_attr(feature = "typescript", derive(TS))] -#[cfg_attr(feature = "typescript", ts(export))] -#[serde(rename_all = "PascalCase")] -pub enum Position { - #[default] - Goalkeeper, - RightBack, - CenterBack, - LeftBack, - RightWingBack, - LeftWingBack, - DefensiveMidfielder, - Midfielder, - CentralMidfielder, - AttackingMidfielder, - RightMidfielder, - LeftMidfielder, - Forward, - RightWinger, - LeftWinger, - Striker, - Defender, -} - -impl Position { - /// Groups the detailed positions into simplified categories - pub fn to_group_position(&self) -> Self { - match self { - // Goalkeeper stays as-is - Position::Goalkeeper => Position::Goalkeeper, - // All defender variants -> Defender - Position::Defender - | Position::RightBack - | Position::CenterBack - | Position::LeftBack - | Position::RightWingBack - | Position::LeftWingBack => Position::Defender, - // Midfield variants -> Midfielder - Position::Midfielder - | Position::CentralMidfielder - | Position::DefensiveMidfielder - | Position::AttackingMidfielder - | Position::RightMidfielder - | Position::LeftMidfielder => Position::Midfielder, - // Forward variants -> Forward - Position::Forward - | Position::RightWinger - | Position::LeftWinger - | Position::Striker => Position::Forward, - } - } -} - -impl From for LolRole { - fn from(pos: Position) -> Self { - match pos { - Position::Goalkeeper | Position::DefensiveMidfielder => LolRole::Support, - Position::Defender - | Position::RightBack - | Position::CenterBack - | Position::LeftBack - | Position::RightWingBack - | Position::LeftWingBack => LolRole::Top, - Position::Midfielder | Position::CentralMidfielder => LolRole::Jungle, - Position::AttackingMidfielder - | Position::RightMidfielder - | Position::LeftMidfielder => LolRole::Mid, - Position::Forward - | Position::RightWinger - | Position::LeftWinger - | Position::Striker => LolRole::Adc, - } - } -} - -impl From for Position { - fn from(role: LolRole) -> Self { - match role { - LolRole::Support => Position::Goalkeeper, - LolRole::Top => Position::Defender, - LolRole::Jungle => Position::Midfielder, - LolRole::Mid => Position::AttackingMidfielder, - LolRole::Adc => Position::Forward, - LolRole::Unknown => Position::Defender, - } - } -} - /// Custom deserializer that maps legacy football positions to LoL roles: /// /// Legacy Position → LolRole: diff --git a/src-tauri/crates/domain/src/team.rs b/src-tauri/crates/domain/src/team.rs index 8046b1b48..64bc8d565 100644 --- a/src-tauri/crates/domain/src/team.rs +++ b/src-tauri/crates/domain/src/team.rs @@ -28,6 +28,8 @@ pub struct Team { pub academy_team_id: Option, #[serde(default)] pub academy: Option, + #[serde(default)] + pub logo_url: Option, // Financial breakdown pub wage_budget: i64, @@ -42,8 +44,8 @@ pub struct Team { pub facilities: Facilities, // Tactical - pub formation: String, - pub play_style: PlayStyle, + #[serde(alias = "play_style")] + pub draft_strategy: DraftStrategy, #[serde(default)] pub lol_tactics: LolTactics, @@ -402,7 +404,6 @@ mod academy_team_metadata_tests { "transfer_budget": 500000, "season_income": 0, "season_expenses": 0, - "formation": "4-4-2", "play_style": "Balanced", "founded_year": 1900, "colors": { "primary": "#000000", "secondary": "#ffffff" }, @@ -433,7 +434,6 @@ mod academy_team_metadata_tests { "transfer_budget": 500000, "season_income": 0, "season_expenses": 0, - "formation": "4-4-2", "play_style": "Balanced", "founded_year": 1900, "colors": { "primary": "#000000", "secondary": "#ffffff" }, @@ -660,16 +660,21 @@ pub struct TeamColors { pub secondary: String, } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] #[cfg_attr(feature = "typescript", derive(TS))] #[cfg_attr(feature = "typescript", ts(export))] -pub enum PlayStyle { +pub enum DraftStrategy { + #[default] Balanced, - Attacking, - Defensive, - Possession, - Counter, - HighPress, + #[serde(rename = "Attacking", alias = "HighPress")] + Aggressive, + #[serde(rename = "Defensive")] + Passive, + #[serde(rename = "Possession")] + Scaling, + #[serde(rename = "Counter")] + CounterPick, + PriorityBans, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -680,7 +685,6 @@ pub struct TeamSeasonRecord { pub league_position: u32, pub played: u32, pub won: u32, - pub drawn: u32, pub lost: u32, pub kills_for: u32, pub kills_against: u32, @@ -1225,6 +1229,7 @@ impl Team { parent_team_id: None, academy_team_id: None, academy: None, + logo_url: None, wage_budget: 200_000, transfer_budget: 500_000, season_income: 0, @@ -1232,8 +1237,7 @@ impl Team { financial_ledger: Vec::new(), sponsorship: None, facilities: Facilities::default(), - formation: "4-4-2".to_string(), - play_style: PlayStyle::Balanced, + draft_strategy: DraftStrategy::Balanced, lol_tactics: LolTactics::default(), training_focus: TrainingFocus::default(), training_intensity: TrainingIntensity::default(), diff --git a/src-tauri/crates/engine/src/lib.rs b/src-tauri/crates/engine/src/lib.rs index 399e1a6f9..f08698f34 100644 --- a/src-tauri/crates/engine/src/lib.rs +++ b/src-tauri/crates/engine/src/lib.rs @@ -10,7 +10,6 @@ pub mod engine; pub mod event; pub mod live_match; pub mod report; -pub(crate) mod shared; pub mod types; // Re-export key types for convenience @@ -22,4 +21,4 @@ pub use live_match::{ TeamRoles, }; pub use report::{KillDetail, MatchReport, MatchReportEndReason, PlayerMatchStats, TeamStats}; -pub use types::{MatchConfig, PlayStyle, PlayerData, Side, TeamData, Zone}; +pub use types::{DraftStrategy, MatchConfig, PlayerData, Side, TeamData, Zone}; diff --git a/src-tauri/crates/engine/src/live_match/mod.rs b/src-tauri/crates/engine/src/live_match/mod.rs index cc808a483..c0a104e03 100644 --- a/src-tauri/crates/engine/src/live_match/mod.rs +++ b/src-tauri/crates/engine/src/live_match/mod.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use crate::event::MatchEvent; use crate::report::MatchReport; -use crate::types::{MatchConfig, PlayStyle, PlayerData, Side, TeamData, Zone}; +use crate::types::{DraftStrategy, MatchConfig, PlayerData, Side, TeamData, Zone}; pub use lol_map::{ LolDragonKind, LolDragonState, LolGrubsState, LolLaneState, LolMapState, LolObjectiveState, LolObjectivesState, LolRole, LolTask, LolTeamStructuresState, LolUnitState, @@ -44,13 +44,9 @@ pub enum MatchCommand { player_off_id: String, player_on_id: String, }, - ChangeFormation { + ChangeDraftStrategy { side: Side, - formation: String, - }, - ChangePlayStyle { - side: Side, - play_style: PlayStyle, + draft_strategy: DraftStrategy, }, SetCaptain { side: Side, @@ -245,12 +241,8 @@ impl LiveMatchState { player_off_id, player_on_id, } => self.apply_substitution(side, &player_off_id, &player_on_id), - MatchCommand::ChangeFormation { side, formation } => { - self.team_mut(side).formation = formation; - Ok(()) - } - MatchCommand::ChangePlayStyle { side, play_style } => { - self.team_mut(side).play_style = play_style; + MatchCommand::ChangeDraftStrategy { side, draft_strategy } => { + self.team_mut(side).draft_strategy = draft_strategy; Ok(()) } MatchCommand::SetCaptain { side, player_id } => { diff --git a/src-tauri/crates/engine/src/shared.rs b/src-tauri/crates/engine/src/shared.rs deleted file mode 100644 index ddbacbad4..000000000 --- a/src-tauri/crates/engine/src/shared.rs +++ /dev/null @@ -1,111 +0,0 @@ -use crate::types::{MatchConfig, PlayStyle, PlayerData, Side}; - -// --------------------------------------------------------------------------- -// PlayerSnap — lightweight snapshot of a player to avoid borrow conflicts -// --------------------------------------------------------------------------- - -#[derive(Clone)] -#[allow(dead_code)] -pub(crate) struct PlayerSnap { - pub id: String, - pub mechanics: u8, - pub laning: u8, - pub teamfighting: u8, - pub macro_play: u8, - pub consistency: u8, - pub shotcalling: u8, - pub champion_pool: u8, - pub discipline: u8, - pub mental_resilience: u8, - pub traits: Vec, -} - -impl PlayerSnap { - pub fn from(p: &PlayerData) -> Self { - Self { - id: p.id.clone(), - mechanics: p.mechanics, - laning: p.laning, - teamfighting: p.teamfighting, - macro_play: p.macro_play, - consistency: p.consistency, - shotcalling: p.shotcalling, - champion_pool: p.champion_pool, - discipline: p.discipline, - mental_resilience: p.mental_resilience, - traits: p.traits.clone(), - } - } - - pub fn has_trait(&self, name: &str) -> bool { - self.traits.iter().any(|t| t == name) - } -} - -// --------------------------------------------------------------------------- -// TraitContext — which game action context we're computing a bonus for -// --------------------------------------------------------------------------- - -#[derive(Debug, Clone, Copy)] -pub(crate) enum TraitContext { - Shooting, - Dribbling, - Passing, - Tackling, - Goalkeeping, - Foul, - Midfield, -} - -/// Compute a multiplicative trait bonus for a specific action context. -/// Temporarily dummied out to return 1.0 until LoL trait system is designed. -#[allow(unused_variables)] -pub(crate) fn trait_bonus(snap: &PlayerSnap, context: TraitContext) -> f64 { - 1.0 -} - -// --------------------------------------------------------------------------- -// Play-style modifiers -// --------------------------------------------------------------------------- - -#[derive(Debug, Clone, Copy)] -pub(crate) enum PlayStylePhase { - Midfield, - Attack, - Defense, - Press, -} - -pub(crate) fn play_style_modifier( - style: PlayStyle, - phase: PlayStylePhase, - is_own_phase: bool, -) -> f64 { - if !is_own_phase { - return 1.0; - } - match (style, phase) { - (PlayStyle::Attacking, PlayStylePhase::Attack) => 1.12, - (PlayStyle::Attacking, PlayStylePhase::Defense) => 0.93, - (PlayStyle::Defensive, PlayStylePhase::Defense) => 1.12, - (PlayStyle::Defensive, PlayStylePhase::Attack) => 0.93, - (PlayStyle::Possession, PlayStylePhase::Midfield) => 1.15, - (PlayStyle::Possession, PlayStylePhase::Attack) => 0.97, - (PlayStyle::Counter, PlayStylePhase::Attack) => 1.18, - (PlayStyle::Counter, PlayStylePhase::Midfield) => 0.92, - (PlayStyle::HighPress, PlayStylePhase::Press) => 1.20, - (PlayStyle::HighPress, PlayStylePhase::Defense) => 0.95, - _ => 1.0, - } -} - -// --------------------------------------------------------------------------- -// Home advantage modifier -// --------------------------------------------------------------------------- - -pub(crate) fn home_mod(side: Side, config: &MatchConfig) -> f64 { - match side { - Side::Home => config.home_advantage, - Side::Away => 1.0, - } -} diff --git a/src-tauri/crates/engine/src/types.rs b/src-tauri/crates/engine/src/types.rs index 0c3d89c90..07fb061b7 100644 --- a/src-tauri/crates/engine/src/types.rs +++ b/src-tauri/crates/engine/src/types.rs @@ -4,17 +4,22 @@ use serde::{Deserialize, Serialize}; pub use crate::live_match::LolRole; // --------------------------------------------------------------------------- -// PlayStyle — mirrors domain::team::PlayStyle +// DraftStrategy — mirrors domain::team::DraftStrategy // --------------------------------------------------------------------------- -#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] -pub enum PlayStyle { +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)] +pub enum DraftStrategy { + #[default] Balanced, - Attacking, - Defensive, - Possession, - Counter, - HighPress, + #[serde(rename = "Attacking", alias = "HighPress")] + Aggressive, + #[serde(rename = "Defensive")] + Passive, + #[serde(rename = "Possession")] + Scaling, + #[serde(rename = "Counter")] + CounterPick, + PriorityBans, } // --------------------------------------------------------------------------- @@ -51,10 +56,6 @@ pub struct PlayerData { pub traits: Vec, } -fn default_engine_attr() -> u8 { - 50 -} - fn default_fitness() -> u8 { 75 } @@ -88,8 +89,7 @@ impl PlayerData { pub struct TeamData { pub id: String, pub name: String, - pub formation: String, - pub play_style: PlayStyle, + pub draft_strategy: DraftStrategy, pub players: Vec, } @@ -228,7 +228,7 @@ impl Side { } // --------------------------------------------------------------------------- -// Zone — regions of the pitch from the perspective of the match (not a team) +// Zone — regions of the rift from the perspective of the match (not a team) // --------------------------------------------------------------------------- #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)] diff --git a/src-tauri/crates/engine/tests/live_match_tests.rs b/src-tauri/crates/engine/tests/live_match_tests.rs index 0f61a0da0..3047dbf86 100644 --- a/src-tauri/crates/engine/tests/live_match_tests.rs +++ b/src-tauri/crates/engine/tests/live_match_tests.rs @@ -1,7 +1,7 @@ use engine::ai::{AiProfile, ai_decide}; use engine::{ EventType, LiveMatchState, LolRole, MatchCommand, MatchConfig, MatchPhase, MinuteResult, - PlayStyle, PlayerData, Side, TeamData, + DraftStrategy, PlayerData, Side, TeamData, }; use rand::SeedableRng; use rand::rngs::StdRng; @@ -10,8 +10,8 @@ use rand::rngs::StdRng; // Helpers // --------------------------------------------------------------------------- -/// Map football Position to LoL role for test data -fn football_position_to_lol_role(position: &str) -> LolRole { +/// Map legacy Position to LoL role for test data +fn position_to_lol_role(position: &str) -> LolRole { match position { "Goalkeeper" | "DefensiveMidfielder" => LolRole::Support, "Defender" | "RightBack" | "CenterBack" | "LeftBack" | "RightWingBack" | "LeftWingBack" => { @@ -32,8 +32,7 @@ fn make_player(id: &str, name: &str, pos: &str, skill: u8) -> PlayerData { PlayerData { id: id.to_string(), name: name.to_string(), - profile_image_url: None, - role: football_position_to_lol_role(pos), + role: position_to_lol_role(pos), condition: 90, fitness: 75, // LoL-native attributes @@ -50,7 +49,7 @@ fn make_player(id: &str, name: &str, pos: &str, skill: u8) -> PlayerData { } } -fn make_team(id: &str, name: &str, skill: u8, style: PlayStyle) -> TeamData { +fn make_team(id: &str, name: &str, skill: u8, draft_strategy: DraftStrategy) -> TeamData { let players = vec![ make_player(&format!("{}_gk", id), "GK", "Goalkeeper", skill), make_player(&format!("{}_def1", id), "DEF1", "Defender", skill), @@ -67,8 +66,7 @@ fn make_team(id: &str, name: &str, skill: u8, style: PlayStyle) -> TeamData { TeamData { id: id.to_string(), name: name.to_string(), - formation: "4-4-2".to_string(), - play_style: style, + draft_strategy, players, } } @@ -84,8 +82,8 @@ fn make_bench(id: &str, skill: u8) -> Vec { } fn make_live_match(allows_extra_time: bool) -> LiveMatchState { - let home = make_team("home", "Home FC", 70, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 70, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 70, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 70, DraftStrategy::Balanced); let home_bench = make_bench("home", 65); let away_bench = make_bench("away", 65); LiveMatchState::new( @@ -406,23 +404,6 @@ fn substitution_recorded_in_tracking() { // Tests: Tactical commands // =========================================================================== -#[test] -fn change_formation_works() { - let mut state = make_live_match(false); - let mut rng = seeded_rng(42); - state.step_minute(&mut rng); - - state - .apply_command(MatchCommand::ChangeFormation { - side: Side::Home, - formation: "3-5-2".to_string(), - }) - .unwrap(); - - let snap = state.snapshot(); - assert_eq!(snap.home_team.formation, "3-5-2"); -} - #[test] fn change_play_style_works() { let mut state = make_live_match(false); @@ -430,14 +411,14 @@ fn change_play_style_works() { state.step_minute(&mut rng); state - .apply_command(MatchCommand::ChangePlayStyle { + .apply_command(MatchCommand::ChangeDraftStrategy { side: Side::Away, - play_style: PlayStyle::Attacking, + draft_strategy: DraftStrategy::Aggressive, }) .unwrap(); let snap = state.snapshot(); - assert_eq!(snap.away_team.play_style, PlayStyle::Attacking); + assert_eq!(snap.away_team.draft_strategy, DraftStrategy::Aggressive); } #[test] @@ -604,8 +585,8 @@ fn strong_team_has_more_kills() { let trials = 50; for seed in 0..trials { - let strong = make_team("home", "Strong FC", 85, PlayStyle::Balanced); - let weak = make_team("away", "Weak FC", 55, PlayStyle::Balanced); + let strong = make_team("home", "Strong FC", 85, DraftStrategy::Balanced); + let weak = make_team("away", "Weak FC", 55, DraftStrategy::Balanced); let home_bench = make_bench("home", 80); let away_bench = make_bench("away", 50); let mut state = LiveMatchState::new( @@ -644,7 +625,7 @@ fn average_kills_reasonable() { } let avg = total_kills as f64 / trials as f64; - // LoL simulations may have fewer kills than football goals; + // LoL simulations may have varying kill counts; // just verify it's not NaN or negative. assert!( avg >= 0.0, @@ -858,34 +839,6 @@ fn pre_match_swap_invalid_bench_player_fails() { assert!(result.is_err()); } -// =========================================================================== -// Tests: Formation changes -// =========================================================================== - -#[test] -fn formation_invalid_falls_back_to_442() { - let mut state = make_live_match(false); - let mut rng = seeded_rng(42); - state.step_minute(&mut rng); - - state - .apply_command(MatchCommand::ChangeFormation { - side: Side::Home, - formation: "invalid".to_string(), - }) - .unwrap(); - - let snap = state.snapshot(); - // Fallback parse → (4, 4, 2) - let defs = snap - .home_team - .players - .iter() - .filter(|p| p.role == LolRole::Top) - .count(); - assert_eq!(defs, 4); -} - // =========================================================================== // Tests: Team roles (captain, shotcaller) // =========================================================================== @@ -925,17 +878,17 @@ fn set_shotcaller_is_no_op() { #[test] fn play_style_variations_produce_results() { let styles = [ - PlayStyle::Attacking, - PlayStyle::Defensive, - PlayStyle::Possession, - PlayStyle::Counter, - PlayStyle::HighPress, - PlayStyle::Balanced, + DraftStrategy::Aggressive, + DraftStrategy::Passive, + DraftStrategy::Scaling, + DraftStrategy::CounterPick, + DraftStrategy::Aggressive, + DraftStrategy::Balanced, ]; for &style in &styles { let home = make_team("home", "Home FC", 70, style); - let away = make_team("away", "Away FC", 70, PlayStyle::Balanced); + let away = make_team("away", "Away FC", 70, DraftStrategy::Balanced); let home_bench = make_bench("home", 65); let away_bench = make_bench("away", 65); let mut state = LiveMatchState::new( @@ -967,8 +920,7 @@ fn make_player_with_traits( PlayerData { id: id.to_string(), name: name.to_string(), - profile_image_url: None, - role: football_position_to_lol_role(pos), + role: position_to_lol_role(pos), condition: 90, fitness: 75, // LoL-native attributes @@ -988,73 +940,80 @@ fn make_player_with_traits( fn make_team_with_traits(id: &str, name: &str, skill: u8, traits: Vec<&str>) -> TeamData { let players = vec![ make_player_with_traits( - &format!("{}_gk", id), - "GK", + &format!("{}_gk1", id), + "GK1", "Goalkeeper", skill, - vec!["SafeHands", "CatReflexes"], + vec![], ), make_player_with_traits( &format!("{}_def1", id), "DEF1", "Defender", skill, - vec!["BallWinner", "Rock"], + vec![], ), make_player_with_traits( &format!("{}_def2", id), "DEF2", "Defender", skill, - traits.clone(), + vec![], ), make_player_with_traits( &format!("{}_def3", id), "DEF3", "Defender", skill, - traits.clone(), + vec![], ), make_player_with_traits( &format!("{}_def4", id), "DEF4", "Defender", skill, - traits.clone(), + vec![], ), make_player_with_traits( &format!("{}_mid1", id), "MID1", "Midfielder", skill, - vec!["Engine", "Playmaker"], + vec![], ), make_player_with_traits( &format!("{}_mid2", id), "MID2", "Midfielder", skill, - vec!["TeamPlayer", "Visionary"], + vec![], ), make_player_with_traits( &format!("{}_mid3", id), "MID3", "Midfielder", skill, - vec!["Tireless"], + vec![], ), make_player_with_traits( &format!("{}_mid4", id), "MID4", "Midfielder", skill, - traits.clone(), + vec![], ), make_player_with_traits( &format!("{}_fwd1", id), "FWD1", "Forward", skill, + vec![], + ), + make_player_with_traits( + &format!("{}_fwd2", id), + "FWD2", + "Forward", + skill, vec!["Sharpshooter", "CompleteForward"], ), make_player_with_traits( @@ -1068,8 +1027,7 @@ fn make_team_with_traits(id: &str, name: &str, skill: u8, traits: Vec<&str>) -> TeamData { id: id.to_string(), name: name.to_string(), - formation: "4-4-2".to_string(), - play_style: PlayStyle::Balanced, + draft_strategy: DraftStrategy::Balanced, players, } } @@ -1077,7 +1035,7 @@ fn make_team_with_traits(id: &str, name: &str, skill: u8, traits: Vec<&str>) -> #[test] fn traits_are_exercised_during_match() { let home = make_team_with_traits("home", "Trait FC", 70, vec![]); - let away = make_team("away", "Away FC", 70, PlayStyle::Balanced); + let away = make_team("away", "Away FC", 70, DraftStrategy::Balanced); let home_bench = make_bench("home", 65); let away_bench = make_bench("away", 65); let mut state = LiveMatchState::new( @@ -1266,8 +1224,8 @@ fn custom_config_affects_match() { let mut config = MatchConfig::default(); config.home_advantage = 1.5; // extreme home advantage - let home = make_team("home", "Home FC", 70, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 70, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 70, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 70, DraftStrategy::Balanced); let mut state = LiveMatchState::new( home, away, @@ -1287,8 +1245,8 @@ fn custom_config_affects_match() { #[test] fn very_weak_team_still_finishes() { - let home = make_team("home", "Home FC", 99, PlayStyle::Attacking); - let away = make_team("away", "Away FC", 10, PlayStyle::Defensive); + let home = make_team("home", "Home FC", 99, DraftStrategy::Aggressive); + let away = make_team("away", "Away FC", 10, DraftStrategy::Passive); let mut state = LiveMatchState::new( home, away, diff --git a/src-tauri/crates/engine/tests/simulation_tests.rs b/src-tauri/crates/engine/tests/simulation_tests.rs index a63e4fba2..204d3f9ad 100644 --- a/src-tauri/crates/engine/tests/simulation_tests.rs +++ b/src-tauri/crates/engine/tests/simulation_tests.rs @@ -7,7 +7,7 @@ use engine::LolRole; use engine::{ - EventType, MatchConfig, MatchEvent, PlayStyle, PlayerData, Side, TeamData, Zone, simulate_lol, + DraftStrategy, EventType, MatchConfig, MatchEvent, PlayerData, Side, TeamData, Zone, simulate_lol, }; use rand::SeedableRng; use rand::rngs::StdRng; @@ -16,8 +16,8 @@ use rand::rngs::StdRng; // Test helpers // --------------------------------------------------------------------------- -/// Map football Position to LoL role for test data -fn football_position_to_lol_role(position: &str) -> LolRole { +/// Map legacy Position to LoL role for test data +fn position_to_lol_role(position: &str) -> LolRole { match position { "Goalkeeper" | "DefensiveMidfielder" => LolRole::Support, "Defender" | "RightBack" | "CenterBack" | "LeftBack" | "RightWingBack" | "LeftWingBack" => { @@ -34,8 +34,7 @@ fn make_player(id: &str, name: &str, position: &str, skill: u8) -> PlayerData { PlayerData { id: id.to_string(), name: name.to_string(), - profile_image_url: None, - role: football_position_to_lol_role(position), + role: position_to_lol_role(position), condition: 90, fitness: 75, // LoL-native attributes @@ -52,12 +51,11 @@ fn make_player(id: &str, name: &str, position: &str, skill: u8) -> PlayerData { } } -fn make_team(id: &str, name: &str, skill: u8, play_style: PlayStyle) -> TeamData { +fn make_team(id: &str, name: &str, skill: u8, draft_strategy: DraftStrategy) -> TeamData { TeamData { id: id.to_string(), name: name.to_string(), - formation: "4-4-2".to_string(), - play_style, + draft_strategy, players: vec![ make_player(&format!("{id}_gk1"), "GK1", "Goalkeeper", skill), make_player(&format!("{id}_def1"), "DEF1", "Defender", skill), @@ -98,7 +96,7 @@ fn player_effective_overall_accounts_for_condition() { #[test] fn team_position_counts() { - let team = make_team("t1", "Test FC", 60, PlayStyle::Balanced); + let team = make_team("t1", "Test FC", 60, DraftStrategy::Balanced); assert_eq!(team.count_role(LolRole::Support), 1); assert_eq!(team.count_role(LolRole::Top), 4); assert_eq!(team.count_role(LolRole::Jungle), 4); @@ -107,7 +105,7 @@ fn team_position_counts() { #[test] fn team_ratings_non_zero() { - let team = make_team("t1", "Test FC", 65, PlayStyle::Balanced); + let team = make_team("t1", "Test FC", 65, DraftStrategy::Balanced); assert!(team.defense_rating() > 0.0); assert!(team.midfield_rating() > 0.0); assert!(team.attack_rating() > 0.0); @@ -116,8 +114,8 @@ fn team_ratings_non_zero() { #[test] fn team_ratings_scale_with_skill() { - let weak = make_team("w", "Weak", 30, PlayStyle::Balanced); - let strong = make_team("s", "Strong", 90, PlayStyle::Balanced); + let weak = make_team("w", "Weak", 30, DraftStrategy::Balanced); + let strong = make_team("s", "Strong", 90, DraftStrategy::Balanced); assert!(strong.defense_rating() > weak.defense_rating()); assert!(strong.midfield_rating() > weak.midfield_rating()); assert!(strong.attack_rating() > weak.attack_rating()); @@ -126,7 +124,7 @@ fn team_ratings_scale_with_skill() { #[test] fn team_ratings_use_lol_native_attributes() { // Verify defense_rating uses LoL attributes (consistency + discipline + mental_resilience) - let mut team = make_team("t1", "Test FC", 60, PlayStyle::Balanced); + let mut team = make_team("t1", "Test FC", 60, DraftStrategy::Balanced); // Set low LoL-native stats but high legacy stats (should not affect rating) for player in &mut team.players { player.consistency = 30; @@ -152,7 +150,7 @@ fn team_ratings_use_lol_native_attributes() { ); // Verify attack_rating uses LoL attributes (mechanics + laning + teamfighting + consistency) - let mut team2 = make_team("t2", "Test FC2", 60, PlayStyle::Balanced); + let mut team2 = make_team("t2", "Test FC2", 60, DraftStrategy::Balanced); for player in &mut team2.players { player.mechanics = 30; player.laning = 30; @@ -263,8 +261,8 @@ fn default_config_values_in_range() { #[test] fn simulation_regression_sanity_no_extreme_drift() { - let home = make_team("home", "Home FC", 65, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); let mut total_kills = 0u32; @@ -323,8 +321,8 @@ fn match_event_builder() { #[test] fn simulation_produces_report() { - let home = make_team("home", "Home FC", 65, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); let mut rng = seeded_rng(42); @@ -346,8 +344,8 @@ fn simulation_produces_report() { #[test] fn simulation_deterministic_with_same_seed() { - let home = make_team("home", "Home FC", 60, PlayStyle::Attacking); - let away = make_team("away", "Away FC", 60, PlayStyle::Defensive); + let home = make_team("home", "Home FC", 60, DraftStrategy::Aggressive); + let away = make_team("away", "Away FC", 60, DraftStrategy::Passive); let config = MatchConfig::default(); let report1 = simulate_lol(&home, &away, &config, &mut seeded_rng(123)); @@ -360,8 +358,8 @@ fn simulation_deterministic_with_same_seed() { #[test] fn simulation_different_seeds_vary() { - let home = make_team("home", "Home FC", 65, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); // Run many simulations and check we get different results @@ -380,8 +378,8 @@ fn simulation_different_seeds_vary() { #[test] fn goals_in_report_match_score() { - let home = make_team("home", "Home FC", 70, PlayStyle::Attacking); - let away = make_team("away", "Away FC", 50, PlayStyle::Defensive); + let home = make_team("home", "Home FC", 70, DraftStrategy::Aggressive); + let away = make_team("away", "Away FC", 50, DraftStrategy::Passive); let config = MatchConfig::default(); for seed in 0..20 { @@ -411,8 +409,8 @@ fn goals_in_report_match_score() { #[test] fn goal_events_have_scorer() { - let home = make_team("home", "Home FC", 75, PlayStyle::Attacking); - let away = make_team("away", "Away FC", 45, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 75, DraftStrategy::Aggressive); + let away = make_team("away", "Away FC", 45, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(99)); @@ -428,8 +426,8 @@ fn goal_events_have_scorer() { #[test] fn possession_adds_up() { - let home = make_team("home", "Home FC", 65, PlayStyle::Possession); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Scaling); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(7)); @@ -445,8 +443,8 @@ fn possession_adds_up() { #[test] fn total_minutes_at_least_90() { - let home = make_team("home", "Home FC", 60, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 60, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 60, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 60, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(55)); assert!( @@ -458,8 +456,8 @@ fn total_minutes_at_least_90() { #[test] fn report_tracks_minutes_for_all_starters() { - let home = make_team("home", "Home FC", 60, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 60, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 60, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 60, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(55)); @@ -483,8 +481,8 @@ fn report_tracks_minutes_for_all_starters() { #[test] fn strong_team_wins_more_often() { - let strong = make_team("strong", "Strong FC", 90, PlayStyle::Balanced); - let weak = make_team("weak", "Weak FC", 30, PlayStyle::Balanced); + let strong = make_team("strong", "Strong FC", 90, DraftStrategy::Balanced); + let weak = make_team("weak", "Weak FC", 30, DraftStrategy::Balanced); let config = MatchConfig::default(); let mut strong_wins = 0u32; @@ -506,8 +504,8 @@ fn strong_team_wins_more_often() { #[test] fn equal_teams_roughly_even() { - let team_a = make_team("a", "Team A", 65, PlayStyle::Balanced); - let team_b = make_team("b", "Team B", 65, PlayStyle::Balanced); + let team_a = make_team("a", "Team A", 65, DraftStrategy::Balanced); + let team_b = make_team("b", "Team B", 65, DraftStrategy::Balanced); let config = MatchConfig { home_advantage: 1.0, ..MatchConfig::default() @@ -540,7 +538,7 @@ fn equal_teams_roughly_even() { #[test] fn home_advantage_helps() { - let team = make_team("t", "Team", 65, PlayStyle::Balanced); + let team = make_team("t", "Team", 65, DraftStrategy::Balanced); let config_with = MatchConfig { home_advantage: 1.15, ..MatchConfig::default() @@ -576,8 +574,8 @@ fn home_advantage_helps() { #[test] fn possession_style_has_more_possession() { - let poss_team = make_team("poss", "Poss FC", 65, PlayStyle::Possession); - let counter_team = make_team("counter", "Counter FC", 65, PlayStyle::Counter); + let poss_team = make_team("poss", "Poss FC", 65, DraftStrategy::Scaling); + let counter_team = make_team("counter", "Counter FC", 65, DraftStrategy::CounterPick); let config = MatchConfig { home_advantage: 1.0, ..MatchConfig::default() @@ -602,8 +600,8 @@ fn possession_style_has_more_possession() { #[test] fn player_stats_populated() { - let home = make_team("home", "Home FC", 65, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(77)); @@ -625,8 +623,8 @@ fn player_stats_populated() { #[test] fn team_stats_shots_consistent() { - let home = make_team("home", "Home FC", 65, PlayStyle::Attacking); - let away = make_team("away", "Away FC", 65, PlayStyle::Defensive); + let home = make_team("home", "Home FC", 65, DraftStrategy::Aggressive); + let away = make_team("away", "Away FC", 65, DraftStrategy::Passive); let config = MatchConfig::default(); for seed in 0..10 { @@ -646,8 +644,8 @@ fn team_stats_shots_consistent() { #[test] fn events_are_chronological() { - let home = make_team("home", "Home FC", 70, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 70, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 70, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 70, DraftStrategy::Balanced); let config = MatchConfig::default(); // Run multiple seeds to increase confidence @@ -672,8 +670,8 @@ fn events_are_chronological() { #[test] fn pass_accuracy_in_range() { - let home = make_team("home", "Home FC", 65, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(88)); @@ -699,8 +697,8 @@ fn pass_accuracy_in_range() { #[test] fn report_serializes_to_json() { - let home = make_team("home", "Home FC", 60, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 60, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 60, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 60, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(42)); @@ -718,8 +716,8 @@ fn report_serializes_to_json() { #[test] fn goal_events_match_report_goals() { - let home = make_team("home", "Home FC", 70, PlayStyle::Attacking); - let away = make_team("away", "Away FC", 50, PlayStyle::Defensive); + let home = make_team("home", "Home FC", 70, DraftStrategy::Aggressive); + let away = make_team("away", "Away FC", 50, DraftStrategy::Passive); let config = MatchConfig::default(); for seed in 0..30 { @@ -741,8 +739,8 @@ fn goal_events_match_report_goals() { #[test] fn average_goals_realistic() { - let home = make_team("home", "Home FC", 65, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); let trials = 500; @@ -770,12 +768,12 @@ fn average_goals_realistic() { #[test] fn all_play_styles_produce_valid_report() { let styles = [ - PlayStyle::Balanced, - PlayStyle::Attacking, - PlayStyle::Defensive, - PlayStyle::Possession, - PlayStyle::Counter, - PlayStyle::HighPress, + DraftStrategy::Balanced, + DraftStrategy::Aggressive, + DraftStrategy::Passive, + DraftStrategy::Scaling, + DraftStrategy::CounterPick, + DraftStrategy::Aggressive, ]; for home_style in &styles { @@ -811,8 +809,7 @@ fn minimal_team_doesnt_crash() { let minimal = TeamData { id: "min".to_string(), name: "Minimal FC".to_string(), - formation: "1-1-1-1".to_string(), - play_style: PlayStyle::Balanced, + draft_strategy: DraftStrategy::Balanced, players: vec![ make_player("gk", "GK", "Goalkeeper", 50), make_player("def", "DEF", "Defender", 50), @@ -820,7 +817,7 @@ fn minimal_team_doesnt_crash() { make_player("fwd", "FWD", "Forward", 50), ], }; - let normal = make_team("normal", "Normal FC", 60, PlayStyle::Balanced); + let normal = make_team("normal", "Normal FC", 60, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&minimal, &normal, &config, &mut seeded_rng(1)); assert!( @@ -836,8 +833,8 @@ fn minimal_team_doesnt_crash() { #[test] fn extreme_skill_disparity_no_crash() { - let elite = make_team("elite", "Elite FC", 99, PlayStyle::Attacking); - let amateur = make_team("amateur", "Amateur FC", 1, PlayStyle::Defensive); + let elite = make_team("elite", "Elite FC", 99, DraftStrategy::Aggressive); + let amateur = make_team("amateur", "Amateur FC", 1, DraftStrategy::Passive); let config = MatchConfig::default(); for seed in 0..10 { @@ -862,8 +859,8 @@ fn extreme_skill_disparity_no_crash() { #[test] fn player_ratings_computed_for_active_players() { - let home = make_team("home", "Home FC", 65, PlayStyle::Balanced); - let away = make_team("away", "Away FC", 65, PlayStyle::Balanced); + let home = make_team("home", "Home FC", 65, DraftStrategy::Balanced); + let away = make_team("away", "Away FC", 65, DraftStrategy::Balanced); let config = MatchConfig::default(); let report = simulate_lol(&home, &away, &config, &mut seeded_rng(42)); @@ -886,8 +883,8 @@ fn player_ratings_computed_for_active_players() { #[test] fn dribble_events_occur() { - let home = make_team("home", "Home FC", 80, PlayStyle::Attacking); - let away = make_team("away", "Away FC", 40, PlayStyle::Defensive); + let home = make_team("home", "Home FC", 80, DraftStrategy::Aggressive); + let away = make_team("away", "Away FC", 40, DraftStrategy::Passive); let config = MatchConfig::default(); let mut total_kills = 0u32; diff --git a/src-tauri/crates/ofm_core/src/board_objectives.rs b/src-tauri/crates/ofm_core/src/board_objectives.rs index d67fb4bb4..f55e71a30 100644 --- a/src-tauri/crates/ofm_core/src/board_objectives.rs +++ b/src-tauri/crates/ofm_core/src/board_objectives.rs @@ -355,25 +355,15 @@ mod tests { fn make_player(id: &str, team_id: &str, overall: u8) -> Player { let attrs = PlayerAttributes { - pace: overall, - mental_resilience: overall, - strength: overall, - champion_pool: overall, - passing: overall, - laning: overall, - tackling: overall, mechanics: overall, - defending: overall, - positioning: overall, + laning: overall, + teamfighting: overall, macro_play: overall, consistency: overall, - discipline: overall, - aggression: overall, - teamfighting: overall, shotcalling: overall, - handling: overall, - reflexes: overall, - aerial: overall, + champion_pool: overall, + discipline: overall, + mental_resilience: overall, }; let mut player = Player::new( id.to_string(), @@ -634,30 +624,27 @@ mod tests { team_id: "team1".to_string(), played: 4, won: 4, - drawn: 0, lost: 0, - kills_for: 5, - kills_against: 1, + maps_won: 5, + maps_lost: 1, points: 12, }, StandingEntry { team_id: "team2".to_string(), played: 5, won: 5, - drawn: 0, lost: 0, - kills_for: 9, - kills_against: 2, + maps_won: 9, + maps_lost: 2, points: 15, }, StandingEntry { team_id: "team3".to_string(), played: 4, won: 1, - drawn: 0, lost: 3, - kills_for: 2, - kills_against: 7, + maps_won: 2, + maps_lost: 7, points: 3, }, ]; @@ -728,40 +715,36 @@ mod tests { team_id: "team1".to_string(), played: 6, won: 5, - drawn: 1, lost: 0, - kills_for: 12, - kills_against: 3, + maps_won: 12, + maps_lost: 3, points: 16, }, StandingEntry { team_id: "team2".to_string(), played: 6, won: 3, - drawn: 1, lost: 2, - kills_for: 7, - kills_against: 6, + maps_won: 7, + maps_lost: 6, points: 10, }, StandingEntry { team_id: "team3".to_string(), played: 6, won: 1, - drawn: 2, lost: 3, - kills_for: 4, - kills_against: 8, + maps_won: 4, + maps_lost: 8, points: 5, }, StandingEntry { team_id: "team4".to_string(), played: 6, won: 0, - drawn: 2, lost: 4, - kills_for: 2, - kills_against: 8, + maps_won: 2, + maps_lost: 8, points: 2, }, ]; diff --git a/src-tauri/crates/ofm_core/src/champions.rs b/src-tauri/crates/ofm_core/src/champions.rs index 19eb4e866..c8ba2b90b 100644 --- a/src-tauri/crates/ofm_core/src/champions.rs +++ b/src-tauri/crates/ofm_core/src/champions.rs @@ -607,18 +607,6 @@ pub fn set_player_training_target( player.champion_training_targets.resize(3, String::new()); } - // Backward compatibility: if legacy single-target exists and new slots are empty, - // migrate it to priority slot 1. - if player - .champion_training_targets - .iter() - .all(|slot| slot.is_empty()) - && let Some(legacy) = player.champion_training_target.clone() - && !legacy.trim().is_empty() - { - player.champion_training_targets[0] = legacy; - } - if let Some(champion) = champion_id.clone() { let normalized = normalize_key(&champion); // Remove duplicates from other slots before setting the requested priority. @@ -643,12 +631,6 @@ pub fn set_player_training_target( player.champion_training_targets = compacted; player.champion_training_targets.resize(3, String::new()); - player.champion_training_target = player - .champion_training_targets - .iter() - .find(|slot| !slot.trim().is_empty()) - .cloned(); - if let Some(champion) = champion_id { let current = mastery_for_player_champion(game, player_id, &champion); upsert_mastery(game, player_id, &champion, current.max(MIN_MASTERY)); @@ -664,13 +646,6 @@ pub fn training_targets_for_player(player: &domain::player::Player) -> Vec Result EndOfSeasonSummary { user_position, user_points: user_standing.as_ref().map(|s| s.points).unwrap_or(0), user_won: user_standing.as_ref().map(|s| s.won).unwrap_or(0), - user_drawn: user_standing.as_ref().map(|s| s.drawn).unwrap_or(0), user_lost: user_standing.as_ref().map(|s| s.lost).unwrap_or(0), - user_kills_for: user_standing.as_ref().map(|s| s.kills_for).unwrap_or(0), - user_kills_against: user_standing.as_ref().map(|s| s.kills_against).unwrap_or(0), + user_maps_won: user_standing.as_ref().map(|s| s.maps_won).unwrap_or(0), + user_maps_lost: user_standing.as_ref().map(|s| s.maps_lost).unwrap_or(0), golden_boot_player: awards .golden_boot .first() @@ -258,10 +257,9 @@ pub fn process_end_of_season(game: &mut Game) -> EndOfSeasonSummary { league_position: position, played: standing.played, won: standing.won, - drawn: standing.drawn, lost: standing.lost, - kills_for: standing.kills_for, - kills_against: standing.kills_against, + kills_for: standing.maps_won, + kills_against: standing.maps_lost, }); // Reset form team.form.clear(); @@ -302,8 +300,10 @@ pub fn process_end_of_season(game: &mut Game) -> EndOfSeasonSummary { team_id, team_name, appearances: player.stats.appearances, - goals: player.stats.kills, + kills: player.stats.kills, + deaths: 0, // TODO: track deaths in match stats assists: player.stats.assists, + avg_rating: player.stats.avg_rating, }); } // Reset stats for next season @@ -312,7 +312,7 @@ pub fn process_end_of_season(game: &mut Game) -> EndOfSeasonSummary { // 6. Update manager career stats if let Some(standing) = &user_standing { - let total_matches = standing.won + standing.drawn + standing.lost; + let total_matches = standing.won + standing.lost; game.manager.career_stats.matches_managed += total_matches; game.manager.career_stats.wins += standing.won; game.manager.career_stats.losses += standing.lost; @@ -340,7 +340,6 @@ pub fn process_end_of_season(game: &mut Game) -> EndOfSeasonSummary { if let Some(entry) = existing { entry.matches += total_matches; entry.wins += standing.won; - entry.draws += standing.drawn; entry.losses += standing.lost; let prev_best = entry.best_league_position; if prev_best.is_none() || prev_best.unwrap() > user_position { @@ -356,7 +355,6 @@ pub fn process_end_of_season(game: &mut Game) -> EndOfSeasonSummary { end_date: None, matches: total_matches, wins: standing.won, - draws: standing.drawn, losses: standing.lost, best_league_position: Some(user_position), }); @@ -614,10 +612,9 @@ pub struct EndOfSeasonSummary { pub user_position: u32, pub user_points: u32, pub user_won: u32, - pub user_drawn: u32, pub user_lost: u32, - pub user_kills_for: u32, - pub user_kills_against: u32, + pub user_maps_won: u32, + pub user_maps_lost: u32, pub golden_boot_player: String, pub golden_boot_goals: u32, pub poty_player: String, diff --git a/src-tauri/crates/ofm_core/src/firing.rs b/src-tauri/crates/ofm_core/src/firing.rs index 68b9f8ca2..fc0808f99 100644 --- a/src-tauri/crates/ofm_core/src/firing.rs +++ b/src-tauri/crates/ofm_core/src/firing.rs @@ -211,7 +211,6 @@ mod tests { end_date: None, matches: 10, wins: 2, - draws: 3, losses: 5, best_league_position: Some(12), }); diff --git a/src-tauri/crates/ofm_core/src/generator/generation.rs b/src-tauri/crates/ofm_core/src/generator/generation.rs index 3480a2b4d..9ac346da2 100644 --- a/src-tauri/crates/ofm_core/src/generator/generation.rs +++ b/src-tauri/crates/ofm_core/src/generator/generation.rs @@ -1,7 +1,7 @@ use domain::player::{Player, PlayerAttributes}; use domain::staff::{Staff, StaffAttributes, StaffRole}; use domain::stats::LolRole; -use domain::team::PlayStyle; +use domain::team::DraftStrategy; use rand::{Rng, RngExt}; use uuid::Uuid; @@ -43,7 +43,7 @@ fn compute_alternate_role(primary: &LolRole, attrs: &PlayerAttributes) -> Option } LolRole::Adc => { // ADC with good positioning can play Mid - if attrs.positioning >= 70 && attrs.laning >= 65 { + if attrs.consistency >= 70 && attrs.laning >= 65 { Some(LolRole::Mid) } else { None @@ -51,7 +51,7 @@ fn compute_alternate_role(primary: &LolRole, attrs: &PlayerAttributes) -> Option } LolRole::Support => { // Support with good defending can play Top - if attrs.defending >= 65 && attrs.tackling >= 60 { + if attrs.discipline >= 65 && attrs.macro_play >= 60 { Some(LolRole::Top) } else { None @@ -141,14 +141,13 @@ pub(super) fn country_to_iso(country: &str) -> &str { } } -pub(super) fn play_style_from_str(s: &str) -> PlayStyle { +pub(super) fn draft_strategy_from_str(s: &str) -> DraftStrategy { match s { - "Attacking" => PlayStyle::Attacking, - "Defensive" => PlayStyle::Defensive, - "Possession" => PlayStyle::Possession, - "Counter" => PlayStyle::Counter, - "HighPress" => PlayStyle::HighPress, - _ => PlayStyle::Balanced, + "Attacking" | "HighPress" => DraftStrategy::Aggressive, + "Defensive" => DraftStrategy::Passive, + "Possession" => DraftStrategy::Scaling, + "Counter" => DraftStrategy::CounterPick, + _ => DraftStrategy::Balanced, } } @@ -188,15 +187,7 @@ pub(super) fn generate_random_player_from_def( let is_jungle = matches!(role, LolRole::Jungle); let attributes = PlayerAttributes { - pace: rng.random_range(40..95), - mental_resilience: rng.random_range(40..95), - strength: if is_support { - rng.random_range(50..90) - } else { - rng.random_range(40..95) - }, - champion_pool: rng.random_range(40..95), - passing: if is_support { + mechanics: if is_adc { rng.random_range(55..95) } else { rng.random_range(40..95) @@ -206,25 +197,10 @@ pub(super) fn generate_random_player_from_def( } else { rng.random_range(40..95) }, - tackling: if is_support { - rng.random_range(45..85) - } else { - rng.random_range(40..95) - }, - mechanics: if is_adc { - rng.random_range(55..95) - } else { - rng.random_range(40..95) - }, - defending: if is_support || is_jungle { - rng.random_range(45..85) - } else { - rng.random_range(40..95) - }, - positioning: if is_adc || is_support { + teamfighting: if is_support { rng.random_range(55..95) } else { - rng.random_range(40..95) + rng.random_range(45..95) }, macro_play: if is_support || is_jungle { rng.random_range(55..95) @@ -236,35 +212,26 @@ pub(super) fn generate_random_player_from_def( } else { rng.random_range(40..95) }, + shotcalling: rng.random_range(30..90), + champion_pool: rng.random_range(40..95), discipline: if is_adc { rng.random_range(55..90) } else { rng.random_range(40..95) }, - aggression: rng.random_range(30..90), - teamfighting: if is_support { - rng.random_range(55..95) - } else { - rng.random_range(45..95) - }, - shotcalling: rng.random_range(30..90), - handling: rng.random_range(10..35), - reflexes: rng.random_range(20..50), - aerial: rng.random_range(30..75), + mental_resilience: rng.random_range(40..95), }; - let ovr = (attributes.pace as u32 - + attributes.mental_resilience as u32 - + attributes.strength as u32 - + attributes.passing as u32 + let ovr = (attributes.mechanics as u32 + attributes.laning as u32 - + attributes.tackling as u32 - + attributes.mechanics as u32 - + attributes.defending as u32 - + attributes.positioning as u32 + + attributes.teamfighting as u32 + attributes.macro_play as u32 - + attributes.consistency as u32) - / 11; + + attributes.consistency as u32 + + attributes.shotcalling as u32 + + attributes.champion_pool as u32 + + attributes.discipline as u32 + + attributes.mental_resilience as u32) + / 9; let age_factor = if age <= 23 { 1.5 @@ -350,6 +317,12 @@ pub(super) fn generate_random_staff_from_def( judging_potential: rng.random_range(15..45), physiotherapy: rng.random_range(60..95), }, + StaffRole::Owner => StaffAttributes { + coaching: rng.random_range(30..70), + judging_ability: rng.random_range(30..70), + judging_potential: rng.random_range(30..70), + physiotherapy: rng.random_range(10..40), + }, }; let mut s = Staff::new( diff --git a/src-tauri/crates/ofm_core/src/generator/mod.rs b/src-tauri/crates/ofm_core/src/generator/mod.rs index 985ddbb7a..340defd77 100644 --- a/src-tauri/crates/ofm_core/src/generator/mod.rs +++ b/src-tauri/crates/ofm_core/src/generator/mod.rs @@ -99,7 +99,7 @@ pub fn generate_world( primary: tdef.colors.primary.clone(), secondary: tdef.colors.secondary.clone(), }; - team.play_style = play_style_from_str(&tdef.play_style); + team.draft_strategy = draft_strategy_from_str(&tdef.play_style); teams_out.push(team); // Generate 22 players @@ -218,7 +218,7 @@ mod tests { let (first, last) = pick_name_from_def("ES", &names_def, &mut rng); assert!(!first.is_empty()); assert!(!last.is_empty()); - // Football identity falls back to GB pool if a dedicated pool does not exist yet. + // Legacy: national identity falls back to GB pool if a dedicated pool does not exist yet. let (eng_first, eng_last) = pick_name_from_def("ENG", &names_def, &mut rng); assert!(!eng_first.is_empty()); assert!(!eng_last.is_empty()); diff --git a/src-tauri/crates/ofm_core/src/generator/world_io.rs b/src-tauri/crates/ofm_core/src/generator/world_io.rs index b4e1b1ec3..55611f909 100644 --- a/src-tauri/crates/ofm_core/src/generator/world_io.rs +++ b/src-tauri/crates/ofm_core/src/generator/world_io.rs @@ -1,5 +1,13 @@ use super::definitions::{WorldData, WorldDatabaseInfo}; +/// Convert a team name to a filesystem-safe slug for logo lookup. +fn team_name_to_logo_slug(name: &str) -> String { + name.to_lowercase() + .chars() + .filter(|ch| ch.is_ascii_alphanumeric()) + .collect() +} + /// Generate a random world and wrap it in a `WorldData`. /// If `data_dir` is provided, tries to load definition files from that directory. pub fn generate_world_data(data_dir: Option<&std::path::Path>) -> WorldData { @@ -26,6 +34,13 @@ pub fn generate_world_data(data_dir: Option<&std::path::Path>) -> WorldData { pub fn load_world_from_json(json: &str) -> Result { let mut world: WorldData = serde_json::from_str(json).map_err(|e| format!("Failed to parse world database: {}", e))?; + for team in &mut world.teams { + // Populate logo_url if missing + if team.logo_url.is_none() { + let slug = team_name_to_logo_slug(&team.name); + team.logo_url = Some(format!("/teams-icons/{}.webp", slug)); + } + } crate::identity_upgrade::upgrade_world_football_identities( &mut world.teams, &mut world.players, @@ -109,8 +124,7 @@ mod tests { "transfer_budget": 250000, "season_income": 0, "season_expenses": 0, - "formation": "4-4-2", - "play_style": "Balanced", + "draft_strategy": "Balanced", "training_focus": "Scrims", "training_intensity": "Medium", "training_schedule": "Balanced", @@ -169,10 +183,10 @@ mod tests { } #[test] - fn active_lec_world_seed_does_not_contain_football_nation() { - let json = include_str!("../../../../databases/lec_world.json"); + fn active_world_seed_does_not_contain_football_nation() { + let json = include_str!("../../../../databases/world.json"); - // Assert: active seed data must NOT contain football_nation keys + // Assert: active seed data must NOT contain legacy football_nation keys assert!( !json.contains("football_nation"), "Active LEC world seed should not contain legacy 'football_nation' field" diff --git a/src-tauri/crates/ofm_core/src/identity_upgrade.rs b/src-tauri/crates/ofm_core/src/identity_upgrade.rs index 1eb1db4af..498414dd2 100644 --- a/src-tauri/crates/ofm_core/src/identity_upgrade.rs +++ b/src-tauri/crates/ofm_core/src/identity_upgrade.rs @@ -3,8 +3,8 @@ use domain::identity::derive_birth_country_code; use domain::player::Player; use domain::staff::Staff; -/// Upgrade football identity fields. -/// With the LoL migration complete, `football_nation` is removed from domain types. +/// Legacy: upgrade national identity fields (birth_country normalization). +/// After LoL migration, `football_nation` is removed from domain types. /// Only `birth_country` normalization remains active. pub fn upgrade_game_football_identities(game: &mut Game) -> bool { let mut changed = false; @@ -38,7 +38,7 @@ pub fn upgrade_game_football_identities(game: &mut Game) -> bool { changed } -/// Upgrade world football identities (used by world export). +/// Legacy: upgrade world national identities (used by world export). pub fn upgrade_world_football_identities( _teams: &mut [domain::team::Team], players: &mut [Player], @@ -89,25 +89,15 @@ mod tests { fn sample_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 70, - mental_resilience: 70, - strength: 70, - champion_pool: 70, - passing: 70, - laning: 70, - tackling: 70, mechanics: 70, - defending: 70, - positioning: 70, + laning: 70, + teamfighting: 70, macro_play: 70, consistency: 70, - discipline: 70, - aggression: 70, - teamfighting: 70, shotcalling: 70, - handling: 20, - reflexes: 20, - aerial: 60, + champion_pool: 70, + discipline: 70, + mental_resilience: 70, } } diff --git a/src-tauri/crates/ofm_core/src/job_offers.rs b/src-tauri/crates/ofm_core/src/job_offers.rs index e3a8a70a0..77e5f75eb 100644 --- a/src-tauri/crates/ofm_core/src/job_offers.rs +++ b/src-tauri/crates/ofm_core/src/job_offers.rs @@ -54,7 +54,6 @@ pub fn hire_manager(game: &mut Game, team_id: &str, date: &str) -> Result LolRole { pub(super) fn build_team_with_bench(game: &Game, team_id: &str) -> (TeamData, Vec) { let team = game.teams.iter().find(|t| t.id == team_id); - let (name, formation, play_style) = match team { + let (name, draft_strategy) = match team { Some(t) => ( t.name.clone(), - t.formation.clone(), - match t.play_style { - domain::team::PlayStyle::Attacking => PlayStyle::Attacking, - domain::team::PlayStyle::Defensive => PlayStyle::Defensive, - domain::team::PlayStyle::Possession => PlayStyle::Possession, - domain::team::PlayStyle::Counter => PlayStyle::Counter, - domain::team::PlayStyle::HighPress => PlayStyle::HighPress, - _ => PlayStyle::Balanced, + match t.draft_strategy { + domain::team::DraftStrategy::Aggressive => DraftStrategy::Aggressive, + domain::team::DraftStrategy::Passive => DraftStrategy::Passive, + domain::team::DraftStrategy::Scaling => DraftStrategy::Scaling, + domain::team::DraftStrategy::CounterPick => DraftStrategy::CounterPick, + domain::team::DraftStrategy::PriorityBans => DraftStrategy::PriorityBans, + _ => DraftStrategy::Balanced, }, ), - None => ("Unknown".into(), "4-4-2".into(), PlayStyle::Balanced), + None => ("Unknown".into(), DraftStrategy::Balanced), }; // Collect all players for this team. - // NOTE: For LoL/live prototype we should not apply football injury filtering, - // otherwise rosters can drop below 5 and UI shows empty player slots. + // NOTE: Do not apply legacy injury filtering — rosters must not drop below 5 + // otherwise UI shows empty player slots. let available_players: Vec<&domain::player::Player> = game .players .iter() @@ -83,8 +81,7 @@ pub(super) fn build_team_with_bench(game: &Game, team_id: &str) -> (TeamData, Ve let team_data = TeamData { id: team_id.to_string(), name, - formation, - play_style, + draft_strategy, players: starting_xi, }; @@ -246,14 +243,14 @@ pub fn auto_select_team_roles( .max_by_key(|p| (p.attributes.shotcalling as u16) + (p.attributes.teamfighting as u16)) .map(|p| p.id.clone()); - // Shotcaller: highest shooting + vision + passing (exclude Support) + // Shotcaller: highest laning + macro_play + coordination (exclude Support) let shotcaller = players .iter() .filter(|p| p.position != DomainLolRole::Support) .max_by_key(|p| { (p.attributes.laning as u16) + (p.attributes.macro_play as u16) - + (p.attributes.passing as u16) + + (p.attributes.teamfighting as u16) }) .map(|p| p.id.clone()); diff --git a/src-tauri/crates/ofm_core/src/news/match_report.rs b/src-tauri/crates/ofm_core/src/news/match_report.rs index a183cab58..0541e0822 100644 --- a/src-tauri/crates/ofm_core/src/news/match_report.rs +++ b/src-tauri/crates/ofm_core/src/news/match_report.rs @@ -166,7 +166,7 @@ pub fn match_report_article( let source_keys = [ "be.source.sportsGazette", - "be.source.footballHerald", + "be.source.lolEsports", "be.source.matchDayPress", "be.source.leagueChronicle", ]; @@ -239,7 +239,7 @@ mod tests { fn assert_valid_source_pair(source: &str, source_key: &str) { let valid = [ ("Dot Esports", "be.source.sportsGazette"), - ("LoL Esports", "be.source.footballHerald"), + ("LoL Esports", "be.source.lolEsports"), ("Dexerto Esports", "be.source.matchDayPress"), ("Sheep Esports", "be.source.leagueChronicle"), ]; diff --git a/src-tauri/crates/ofm_core/src/player_events/mod.rs b/src-tauri/crates/ofm_core/src/player_events/mod.rs index 5383d550f..52323e393 100644 --- a/src-tauri/crates/ofm_core/src/player_events/mod.rs +++ b/src-tauri/crates/ofm_core/src/player_events/mod.rs @@ -158,7 +158,7 @@ pub fn check_player_events(game: &mut Game) { if player.injury.is_some() { continue; } - // In LoL, no Goalkeeper - this check no longer applies (supports are valid) + // In LoL, all roles including Support can be benched (no legacy goalkeeper exclusion) if talk_cooldown_active(player, &today) { continue; } @@ -169,18 +169,16 @@ pub fn check_player_events(game: &mut Game) { } let attrs = &player.attributes; - let ovr = (attrs.pace as u16 - + attrs.mental_resilience as u16 - + attrs.strength as u16 - + attrs.passing as u16 + let ovr = (attrs.mechanics as u16 + attrs.laning as u16 - + attrs.tackling as u16 - + attrs.mechanics as u16 - + attrs.defending as u16 - + attrs.positioning as u16 + + attrs.teamfighting as u16 + attrs.macro_play as u16 - + attrs.consistency as u16) - / 11; + + attrs.consistency as u16 + + attrs.shotcalling as u16 + + attrs.champion_pool as u16 + + attrs.discipline as u16 + + attrs.mental_resilience as u16) + / 9; // Player must have decent OVR, low morale, and few appearances // relative to team matches. 10% daily chance to avoid flooding. diff --git a/src-tauri/crates/ofm_core/src/player_events/responses.rs b/src-tauri/crates/ofm_core/src/player_events/responses.rs index d89d8e9e5..39d7ce291 100644 --- a/src-tauri/crates/ofm_core/src/player_events/responses.rs +++ b/src-tauri/crates/ofm_core/src/player_events/responses.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; fn personality_factor(player: &domain::player::Player) -> i8 { let composure = player.attributes.discipline as i16; let leadership = player.attributes.shotcalling as i16; - let aggression = player.attributes.aggression as i16; + let aggression = player.attributes.shotcalling as i16; // Composed leaders are receptive; aggressive low-composure players are volatile ((composure + leadership - aggression) / 6).clamp(-20, 20) as i8 } diff --git a/src-tauri/crates/ofm_core/src/player_rating.rs b/src-tauri/crates/ofm_core/src/player_rating.rs index 7da5612ef..fdc8cab8a 100644 --- a/src-tauri/crates/ofm_core/src/player_rating.rs +++ b/src-tauri/crates/ofm_core/src/player_rating.rs @@ -1,24 +1,17 @@ use domain::player::{LolRole, Player}; /// Returns the 5 starting positions for a team in LoL format. -/// In LoL, the formation is always 5 players: Top, Jungle, Mid, ADC, Support -pub fn formation_slots(_formation: &str) -> Vec { - // LoL always uses 5 roles - ignore formation string for now - // TODO: Implement proper LoL team composition +/// In LoL, the lineup is always 5 players: Top, Jungle, Mid, ADC, Support +pub fn position_slots() -> Vec { vec![ - LolRole::Top, // Top lane - LolRole::Jungle, // Jungle - LolRole::Mid, // Mid lane - LolRole::Adc, // ADC (Bot lane carry) - LolRole::Support, // Support + LolRole::Top, + LolRole::Jungle, + LolRole::Mid, + LolRole::Adc, + LolRole::Support, ] } -fn formation_slot_rows(formation: &str) -> Vec> { - let slots = formation_slots(formation); - vec![slots] -} - /// Calculate overall rating for a player at a specific LolRole pub fn ovr_for_position(player: &Player, _role: &LolRole) -> f64 { natural_ovr(player) @@ -152,7 +145,7 @@ enum Side { } fn slot_side(_role: &LolRole) -> Option { - // In LoL, there's no left/right distinction like football + // In LoL, there's no left/right distinction (unlike traditional sports) None } @@ -169,25 +162,15 @@ mod tests { fn make_player(role: LolRole) -> Player { let attrs = PlayerAttributes { - pace: 70, - mental_resilience: 75, - strength: 65, - champion_pool: 72, - passing: 80, - laning: 60, - tackling: 55, mechanics: 68, - defending: 50, - positioning: 65, + laning: 60, + teamfighting: 80, macro_play: 78, consistency: 70, - discipline: 60, - aggression: 55, - teamfighting: 80, shotcalling: 45, - handling: 20, - reflexes: 25, - aerial: 40, + champion_pool: 72, + discipline: 60, + mental_resilience: 75, }; Player::new( "test-1".to_string(), @@ -201,8 +184,8 @@ mod tests { } #[test] - fn formation_slots_returns_five_roles() { - let slots = formation_slots("any-formation"); + fn position_slots_returns_five_roles() { + let slots = position_slots(); assert_eq!(slots.len(), 5); assert_eq!( slots, diff --git a/src-tauri/crates/ofm_core/src/potential.rs b/src-tauri/crates/ofm_core/src/potential.rs index 78ec24998..a54d511d6 100644 --- a/src-tauri/crates/ofm_core/src/potential.rs +++ b/src-tauri/crates/ofm_core/src/potential.rs @@ -233,25 +233,15 @@ mod tests { fn attrs(stat: u8) -> PlayerAttributes { PlayerAttributes { - pace: stat, - mental_resilience: stat, - strength: stat, - champion_pool: stat, - passing: stat, - laning: stat, - tackling: stat, mechanics: stat, - defending: stat, - positioning: stat, + laning: stat, + teamfighting: stat, macro_play: stat, consistency: stat, - discipline: stat, - aggression: stat, - teamfighting: stat, shotcalling: stat, - handling: stat, - reflexes: stat, - aerial: stat, + champion_pool: stat, + discipline: stat, + mental_resilience: stat, } } diff --git a/src-tauri/crates/ofm_core/src/scouting.rs b/src-tauri/crates/ofm_core/src/scouting.rs index 2692fbe13..a9935ea3b 100644 --- a/src-tauri/crates/ofm_core/src/scouting.rs +++ b/src-tauri/crates/ofm_core/src/scouting.rs @@ -223,7 +223,7 @@ fn build_scout_report( }; // Build fuzzed LoL-facing attribute values. The underlying save still uses - // legacy football-shaped fields, but reports should reveal the concepts the + // legacy-shaped fields, but reports should reveal the concepts the // LoL UI teaches: mechanics, laning, teamfighting, macro, champion pool and // discipline. let all_fuzzed: [(u8, &str); 6] = [ diff --git a/src-tauri/crates/ofm_core/src/season_awards.rs b/src-tauri/crates/ofm_core/src/season_awards.rs index 58b1ed0b7..2ec1e8a87 100644 --- a/src-tauri/crates/ofm_core/src/season_awards.rs +++ b/src-tauri/crates/ofm_core/src/season_awards.rs @@ -20,7 +20,6 @@ pub struct SeasonAwards { pub golden_boot: Vec, // Top scorers pub assist_king: Vec, // Top assists pub player_of_year: Vec, // Best avg rating (min 5 apps) - pub clean_sheet_king: Vec, // Most clean sheets (GKs only) pub most_appearances: Vec, pub young_player: Vec, // Best avg rating, age <= 21 } @@ -133,15 +132,6 @@ pub fn compute_season_awards(game: &Game) -> SeasonAwards { |context| context.player.stats.avg_rating as f64, ); - // Clean Sheet King — Supports only (in LoL, supports protect the base) - let clean_sheet_king = top_awards( - &contexts, - |context| { - context.player.position == LolRole::Support && context.player.stats.clean_sheets > 0 - }, - |context| context.player.stats.clean_sheets as f64, - ); - // Most Appearances let most_appearances = top_awards( &contexts, @@ -164,7 +154,6 @@ pub fn compute_season_awards(game: &Game) -> SeasonAwards { golden_boot, assist_king, player_of_year, - clean_sheet_king, most_appearances, young_player, } @@ -184,25 +173,15 @@ mod tests { fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, - mental_resilience: 60, - strength: 60, - champion_pool: 60, - passing: 60, - laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, + laning: 60, + teamfighting: 60, macro_play: 60, consistency: 60, - discipline: 60, - aggression: 60, - teamfighting: 60, shotcalling: 60, - handling: 60, - reflexes: 60, - aerial: 60, + champion_pool: 60, + discipline: 60, + mental_resilience: 60, } } @@ -446,59 +425,4 @@ mod tests { assert_eq!(young_player_ids, vec!["young-four-apps", "young-eligible"]); } - #[test] - fn clean_sheet_king_only_counts_goalkeepers_and_uses_free_agent_fallback() { - let team = make_team("team1", "Test FC"); - let players = vec![ - make_player( - "team-gk", - "Team Keeper", - Some("team1"), - LolRole::Support, - "1998-01-01", - PlayerSeasonStats { - appearances: 10, - clean_sheets: 8, - ..PlayerSeasonStats::default() - }, - ), - make_player( - "free-agent-gk", - "Free Agent Keeper", - None, - LolRole::Support, - "1996-01-01", - PlayerSeasonStats { - appearances: 9, - clean_sheets: 9, - ..PlayerSeasonStats::default() - }, - ), - make_player( - "defender", - "Defender", - Some("team1"), - LolRole::Top, - "1999-01-01", - PlayerSeasonStats { - appearances: 12, - clean_sheets: 12, - ..PlayerSeasonStats::default() - }, - ), - ]; - - let awards = compute_season_awards(&make_game(players, vec![team])); - - assert_eq!(awards.clean_sheet_king.len(), 2); - assert_eq!(awards.clean_sheet_king[0].player_id, "free-agent-gk"); - assert_eq!(awards.clean_sheet_king[0].team_id, ""); - assert_eq!(awards.clean_sheet_king[0].team_name, "Free Agent"); - assert!( - awards - .clean_sheet_king - .iter() - .all(|entry| entry.player_id != "defender") - ); - } } diff --git a/src-tauri/crates/ofm_core/src/staff_effects.rs b/src-tauri/crates/ofm_core/src/staff_effects.rs index 50e2b348e..709c935fa 100644 --- a/src-tauri/crates/ofm_core/src/staff_effects.rs +++ b/src-tauri/crates/ofm_core/src/staff_effects.rs @@ -1,4 +1,4 @@ -use domain::staff::{CoachingSpecialization, Staff, StaffRole}; +use domain::staff::{Staff, StaffRole}; /// Conservative, LoL-specific staff influence surface. /// @@ -46,12 +46,6 @@ fn quality_mult(avg_value: Option, empty: f64, min: f64, max: f64) -> f64 { (min + (value.clamp(0.0, 100.0) / 100.0) * (max - min)).clamp(min, max) } -fn has_specialist(staff: &[&Staff], specialization: CoachingSpecialization) -> bool { - staff - .iter() - .any(|member| member.specialization.as_ref() == Some(&specialization)) -} - impl LolStaffEffects { pub fn for_team(staff: &[Staff], team_id: &str) -> Self { let team_staff: Vec<&Staff> = staff @@ -97,29 +91,15 @@ impl LolStaffEffects { .collect::>()); let coaching = quality_mult(coaching_avg, 0.85, 0.88, 1.22); - let mut development = quality_mult(coaching_avg, 0.90, 0.92, 1.18); - let mut tactics = quality_mult(coaching_avg, 0.95, 0.94, 1.14); + let development = quality_mult(coaching_avg, 0.90, 0.92, 1.18); + let tactics = quality_mult(coaching_avg, 0.95, 0.94, 1.14); let analysis = quality_mult(judging_ability_avg, 0.95, 0.94, 1.14); - let mut recovery = quality_mult(physio_avg, 1.00, 1.00, 1.20); + let recovery = quality_mult(physio_avg, 1.00, 1.00, 1.20); let morale = quality_mult(coaching_avg, 1.00, 0.96, 1.12); let meta_discovery = (quality_mult(judging_ability_avg, 0.90, 0.92, 1.18) * 0.75 + quality_mult(judging_potential_avg, 1.00, 0.98, 1.16) * 0.25) .clamp(0.90, 1.20); - let mut execution = ((tactics + analysis) / 2.0).clamp(0.96, 1.08); - - if has_specialist(&coaches, CoachingSpecialization::Technique) { - development *= 1.04; - } - if has_specialist(&coaches, CoachingSpecialization::Tactics) { - tactics *= 1.05; - execution *= 1.02; - } - if has_specialist(&coaches, CoachingSpecialization::Youth) { - development *= 1.03; - } - if has_specialist(&coaches, CoachingSpecialization::Fitness) { - recovery *= 1.03; - } + let execution = ((tactics + analysis) / 2.0).clamp(0.96, 1.08); Self { coaching: coaching.clamp(0.85, 1.25), @@ -133,33 +113,6 @@ impl LolStaffEffects { } } - pub fn focus_specialization_multiplier( - self, - staff: &[Staff], - team_id: &str, - specialization: Option, - ) -> f64 { - let Some(target) = specialization else { - return 1.0; - }; - - let coaches: Vec<&Staff> = staff - .iter() - .filter(|member| { - member.team_id.as_deref() == Some(team_id) - && matches!(member.role, StaffRole::Coach | StaffRole::AssistantManager) - }) - .collect(); - - if has_specialist(&coaches, target) { - // Smaller than the old 25% training-only boost because the central model - // already contributes through coaching/development/tactics. - 1.08 - } else { - 1.0 - } - } - pub fn match_mastery_multiplier(self) -> f64 { ((self.development * 0.65) + (self.analysis * 0.35)).clamp(0.88, 1.18) } @@ -172,7 +125,7 @@ impl LolStaffEffects { #[cfg(test)] mod tests { use super::LolStaffEffects; - use domain::staff::{CoachingSpecialization, Staff, StaffAttributes, StaffRole}; + use domain::staff::{Staff, StaffAttributes, StaffRole}; fn staff( id: &str, @@ -210,8 +163,7 @@ mod tests { #[test] fn strong_staff_improves_multiple_preparation_surfaces_with_caps() { - let mut coach = staff("coach", StaffRole::Coach, 92, 30, 30, 20); - coach.specialization = Some(CoachingSpecialization::Tactics); + let coach = staff("coach", StaffRole::Coach, 92, 30, 30, 20); let scout = staff("scout", StaffRole::Scout, 20, 90, 86, 20); let physio = staff("physio", StaffRole::Physio, 20, 20, 20, 88); let effects = LolStaffEffects::for_team(&[coach, scout, physio], "team-1"); @@ -222,19 +174,4 @@ mod tests { assert!(effects.recovery > 1.15 && effects.recovery <= 1.25); assert!(effects.execution <= 1.10); } - - #[test] - fn role_specializations_target_development_and_tactics() { - let mut technique = staff("tech", StaffRole::Coach, 75, 20, 20, 20); - technique.specialization = Some(CoachingSpecialization::Technique); - let mut tactics = staff("tact", StaffRole::Coach, 75, 20, 20, 20); - tactics.specialization = Some(CoachingSpecialization::Tactics); - - let development = LolStaffEffects::for_team(&[technique], "team-1"); - let tactical = LolStaffEffects::for_team(&[tactics], "team-1"); - - assert!(development.development > tactical.development); - assert!(tactical.tactics > development.tactics); - assert!(tactical.execution >= development.execution); - } } diff --git a/src-tauri/crates/ofm_core/src/state.rs b/src-tauri/crates/ofm_core/src/state.rs index 7bdd9b131..248150184 100644 --- a/src-tauri/crates/ofm_core/src/state.rs +++ b/src-tauri/crates/ofm_core/src/state.rs @@ -168,31 +168,15 @@ mod tests { let is_fwd = matches!(group, Position::Forward); PlayerAttributes { - pace: 65, - mental_resilience: 65, - strength: 65, - champion_pool: 65, - passing: 65, - laning: if is_gk { 30 } else { 65 }, - tackling: if is_gk || is_fwd { 35 } else { 65 }, mechanics: if is_gk { 30 } else { 65 }, - defending: if is_gk { - 30 - } else if is_def { - 75 - } else { - 55 - }, - positioning: 65, + laning: if is_gk { 30 } else { 65 }, + teamfighting: 65, macro_play: 65, consistency: 65, - discipline: 65, - aggression: 50, - teamfighting: 65, shotcalling: 50, - handling: if is_gk { 75 } else { 20 }, - reflexes: if is_gk { 75 } else { 30 }, - aerial: 60, + champion_pool: 65, + discipline: 65, + mental_resilience: 65, } } diff --git a/src-tauri/crates/ofm_core/src/training.rs b/src-tauri/crates/ofm_core/src/training.rs index e8185c7ac..476931bad 100644 --- a/src-tauri/crates/ofm_core/src/training.rs +++ b/src-tauri/crates/ofm_core/src/training.rs @@ -7,7 +7,6 @@ use crate::staff_effects::LolStaffEffects; use chrono::Datelike; use domain::message::{InboxMessage, MessageCategory, MessagePriority}; use domain::player::LolRole; -use domain::staff::CoachingSpecialization; use domain::team::{ MainFacilityModuleKind, ScrimChampionPick, ScrimFocus, ScrimIssue, ScrimReport, ScrimStatus, TrainingFocus, TrainingIntensity, TrainingSchedule, @@ -29,23 +28,12 @@ pub struct TeamCoachingBonus { } /// Compute coaching bonuses from a team's staff. -fn compute_coaching_bonus(game: &Game, team_id: &str, focus: &TrainingFocus) -> TeamCoachingBonus { - let focus_spec = match focus { - TrainingFocus::Scrims => Some(CoachingSpecialization::Tactics), - TrainingFocus::VODReview => Some(CoachingSpecialization::Tactics), - TrainingFocus::IndividualCoaching => Some(CoachingSpecialization::Technique), - TrainingFocus::ChampionPoolPractice => Some(CoachingSpecialization::Technique), - TrainingFocus::MacroSystems => Some(CoachingSpecialization::Tactics), - TrainingFocus::MentalResetRecovery => None, - }; - +fn compute_coaching_bonus(game: &Game, team_id: &str, _focus: &TrainingFocus) -> TeamCoachingBonus { let effects = LolStaffEffects::for_team(&game.staff, team_id); - let specialization_mult = - effects.focus_specialization_multiplier(&game.staff, team_id, focus_spec); TeamCoachingBonus { coaching_mult: effects.coaching, - specialization_mult, + specialization_mult: 1.0, physio_mult: effects.recovery, } } @@ -1301,7 +1289,7 @@ fn apply_scrim_plan_focus_gains( ScrimFocus::Teamfighting => { try_gain(&mut attrs.teamfighting, gain); try_gain(&mut attrs.discipline, gain * 0.9); - try_gain(&mut attrs.positioning, gain * 0.75); + try_gain(&mut attrs.consistency, gain * 0.75); } ScrimFocus::Macro => { try_gain(&mut attrs.macro_play, gain); @@ -1328,25 +1316,15 @@ mod tests { fn attrs(stat: u8) -> PlayerAttributes { PlayerAttributes { - pace: stat, - mental_resilience: stat, - strength: stat, - champion_pool: stat, - passing: stat, - laning: stat, - tackling: stat, mechanics: stat, - defending: stat, - positioning: stat, + laning: stat, + teamfighting: stat, macro_play: stat, consistency: stat, - discipline: stat, - aggression: stat, - teamfighting: stat, shotcalling: stat, - handling: stat, - reflexes: stat, - aerial: stat, + champion_pool: stat, + discipline: stat, + mental_resilience: stat, } } diff --git a/src-tauri/crates/ofm_core/src/turn/mod.rs b/src-tauri/crates/ofm_core/src/turn/mod.rs index 678b8f229..6ec72a99b 100644 --- a/src-tauri/crates/ofm_core/src/turn/mod.rs +++ b/src-tauri/crates/ofm_core/src/turn/mod.rs @@ -151,23 +151,21 @@ pub fn finish_live_match_day(game: &mut Game) { fn build_engine_team(game: &Game, team_id: &str) -> engine::TeamData { let team = game.teams.iter().find(|t| t.id == team_id); - let (name, formation, play_style) = match team { + let (name, draft_strategy) = match team { Some(t) => ( t.name.clone(), - t.formation.clone(), - match t.play_style { - domain::team::PlayStyle::Attacking => engine::PlayStyle::Attacking, - domain::team::PlayStyle::Defensive => engine::PlayStyle::Defensive, - domain::team::PlayStyle::Possession => engine::PlayStyle::Possession, - domain::team::PlayStyle::Counter => engine::PlayStyle::Counter, - domain::team::PlayStyle::HighPress => engine::PlayStyle::HighPress, - _ => engine::PlayStyle::Balanced, + match t.draft_strategy { + domain::team::DraftStrategy::Aggressive => engine::DraftStrategy::Aggressive, + domain::team::DraftStrategy::Passive => engine::DraftStrategy::Passive, + domain::team::DraftStrategy::Scaling => engine::DraftStrategy::Scaling, + domain::team::DraftStrategy::CounterPick => engine::DraftStrategy::CounterPick, + domain::team::DraftStrategy::PriorityBans => engine::DraftStrategy::PriorityBans, + _ => engine::DraftStrategy::Balanced, }, ), None => ( "Unknown".into(), - "4-4-2".into(), - engine::PlayStyle::Balanced, + engine::DraftStrategy::Balanced, ), }; @@ -200,8 +198,7 @@ fn build_engine_team(game: &Game, team_id: &str) -> engine::TeamData { engine::TeamData { id: team_id.to_string(), name, - formation, - play_style, + draft_strategy, players, } } @@ -288,12 +285,11 @@ fn maybe_push_weekly_academy_report(game: &mut Game, today: &str) { league_position: 0, played: 0, won: 0, - drawn: 0, lost: 0, kills_for: 0, kills_against: 0, }); - let points = record.won.saturating_mul(3).saturating_add(record.drawn); + let points = record.won.saturating_mul(3); let goal_diff = record.kills_for as i32 - record.kills_against as i32; ( team.id.clone(), @@ -515,7 +511,6 @@ fn ensure_team_season_record(team: &mut Team, season: u32) -> &mut TeamSeasonRec league_position: 0, played: 0, won: 0, - drawn: 0, lost: 0, kills_for: 0, kills_against: 0, @@ -752,10 +747,10 @@ fn maybe_simulate_parallel_academy_leagues(game: &mut Game) { b.points .cmp(&a.points) .then( - (b.kills_for as i32 - b.kills_against as i32) - .cmp(&(a.kills_for as i32 - a.kills_against as i32)), + (b.maps_won as i32 - b.maps_lost as i32) + .cmp(&(a.maps_won as i32 - a.maps_lost as i32)), ) - .then(b.kills_for.cmp(&a.kills_for)) + .then(b.maps_won.cmp(&a.maps_won)) }); if sorted.len() >= 4 { let next_matchday = league diff --git a/src-tauri/crates/ofm_core/src/turn/news.rs b/src-tauri/crates/ofm_core/src/turn/news.rs index ad3991308..92c97cd50 100644 --- a/src-tauri/crates/ofm_core/src/turn/news.rs +++ b/src-tauri/crates/ofm_core/src/turn/news.rs @@ -81,7 +81,7 @@ fn standings_rows(game: &Game, league: &League) -> Vec<(String, u32, i16)> { ( team_name(game, &entry.team_id), entry.points, - entry.goal_difference() as i16, + entry.kill_difference() as i16, ) }) .collect(); @@ -463,25 +463,15 @@ mod tests { fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 70, - mental_resilience: 70, - strength: 65, - champion_pool: 68, - passing: 66, - laning: 72, - tackling: 40, mechanics: 69, - defending: 38, - positioning: 64, + laning: 72, + teamfighting: 64, macro_play: 65, consistency: 67, - discipline: 66, - aggression: 50, - teamfighting: 64, shotcalling: 52, - handling: 20, - reflexes: 20, - aerial: 45, + champion_pool: 68, + discipline: 66, + mental_resilience: 70, } } @@ -836,20 +826,20 @@ mod tests { let alpha = standing_mut(&mut game, "team1"); alpha.played = 10; alpha.points = 25; - alpha.kills_for = 18; - alpha.kills_against = 8; + alpha.maps_won = 18; + alpha.maps_lost = 8; let beta = standing_mut(&mut game, "team2"); beta.played = 10; beta.points = 24; - beta.kills_for = 16; - beta.kills_against = 9; + beta.maps_won = 16; + beta.maps_lost = 9; let gamma = standing_mut(&mut game, "team3"); gamma.played = 10; gamma.points = 7; - gamma.kills_for = 6; - gamma.kills_against = 15; + gamma.maps_won = 6; + gamma.maps_lost = 15; team_mut(&mut game, "team1").form = vec![ "D".to_string(), @@ -950,20 +940,20 @@ mod tests { let alpha = standing_mut(&mut game, "team1"); alpha.played = 10; alpha.points = 25; - alpha.kills_for = 18; - alpha.kills_against = 8; + alpha.maps_won = 18; + alpha.maps_lost = 8; let beta = standing_mut(&mut game, "team2"); beta.played = 10; beta.points = 24; - beta.kills_for = 16; - beta.kills_against = 9; + beta.maps_won = 16; + beta.maps_lost = 9; let gamma = standing_mut(&mut game, "team3"); gamma.played = 10; gamma.points = 7; - gamma.kills_for = 6; - gamma.kills_against = 15; + gamma.maps_won = 6; + gamma.maps_lost = 15; team_mut(&mut game, "team1").form = vec![ "D".to_string(), @@ -1001,3 +991,4 @@ mod tests { ); } } + diff --git a/src-tauri/crates/ofm_core/src/turn/post_match.rs b/src-tauri/crates/ofm_core/src/turn/post_match.rs index bc55a221b..782ae527e 100644 --- a/src-tauri/crates/ofm_core/src/turn/post_match.rs +++ b/src-tauri/crates/ofm_core/src/turn/post_match.rs @@ -174,7 +174,7 @@ pub fn apply_match_report_with_capture( apply_lol_profile_progression(game, report, home_team_id, away_team_id); resolve_post_match_promises(game, report, home_team_id, away_team_id); - // Deplete stamina for players who played, scaled by minutes on pitch + // Deplete stamina for players who played, scaled by minutes in game deplete_match_stamina(game, home_team_id, report); deplete_match_stamina(game, away_team_id, report); @@ -427,18 +427,7 @@ fn apply_player_stats( (player.stats.avg_rating * (n - 1.0) + match_rating.clamp(0.0, 10.0)) / n; } - if player.id.ends_with("_gk") { - let conceded = if player.team_id.as_deref() == Some(_home_team_id) { - report.away_wins - } else if player.team_id.as_deref() == Some(_away_team_id) { - report.home_wins - } else { - 1 - }; - if minutes_played > 0 && conceded == 0 { - player.stats.clean_sheets += 1; - } - } + // clean_sheets removed — LoL has no keeper clean sheet stat (legacy). } } } @@ -600,8 +589,8 @@ fn apply_lol_profile_progression( clamp_attr_range(i16::from(player.attributes.champion_pool) + d_agility); player.attributes.laning = clamp_attr_range(i16::from(player.attributes.laning) + d_shooting); - player.attributes.positioning = - clamp_attr_range(i16::from(player.attributes.positioning) + d_positioning); + player.attributes.consistency = + clamp_attr_range(i16::from(player.attributes.consistency) + d_positioning); player.attributes.teamfighting = clamp_attr_range(i16::from(player.attributes.teamfighting) + d_teamwork); player.attributes.mental_resilience = @@ -614,8 +603,8 @@ fn apply_lol_profile_progression( clamp_attr_range(i16::from(player.attributes.discipline) + d_composure); player.attributes.shotcalling = clamp_attr_range(i16::from(player.attributes.shotcalling) + d_leadership); - player.attributes.passing = - clamp_attr_range(i16::from(player.attributes.passing) + d_passing); + player.attributes.teamfighting = + clamp_attr_range(i16::from(player.attributes.teamfighting) + d_passing); } } diff --git a/src-tauri/crates/ofm_core/src/turn/round_summary.rs b/src-tauri/crates/ofm_core/src/turn/round_summary.rs index c0cb3fd21..ce730c2f7 100644 --- a/src-tauri/crates/ofm_core/src/turn/round_summary.rs +++ b/src-tauri/crates/ofm_core/src/turn/round_summary.rs @@ -1,5 +1,5 @@ use crate::game::Game; -use crate::player_rating::{effective_rating_for_assignment, formation_slots, natural_ovr}; +use crate::player_rating::{effective_rating_for_assignment, position_slots, natural_ovr}; use domain::league::{Fixture, FixtureStatus, StandingEntry}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; @@ -366,8 +366,8 @@ fn sort_standings(mut standings: Vec) -> Vec { right .points .cmp(&left.points) - .then(right.goal_difference().cmp(&left.goal_difference())) - .then(right.kills_for.cmp(&left.kills_for)) + .then(right.kill_difference().cmp(&left.kill_difference())) + .then(right.maps_won.cmp(&left.maps_won)) }); standings } @@ -376,7 +376,7 @@ fn team_strength(game: &Game, team_id: &str) -> f64 { let team = game.teams.iter().find(|team| team.id == team_id); match team { Some(team) if !team.active_lineup_ids.is_empty() => { - let slots = formation_slots(&team.formation); + let slots = position_slots(); let rated_players: Vec = team .active_lineup_ids .iter() diff --git a/src-tauri/crates/ofm_core/tests/contracts_tests.rs b/src-tauri/crates/ofm_core/tests/contracts_tests.rs index fc1a4c417..9d9f66781 100644 --- a/src-tauri/crates/ofm_core/tests/contracts_tests.rs +++ b/src-tauri/crates/ofm_core/tests/contracts_tests.rs @@ -13,25 +13,15 @@ use ofm_core::game::Game; fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, mental_resilience: 60, - strength: 60, champion_pool: 60, - passing: 60, laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, macro_play: 60, consistency: 60, discipline: 60, - aggression: 60, teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, } } @@ -193,16 +183,14 @@ fn high_value_star_expects_more_than_fringe_player() { let mut star = make_player(); star.contract_end = Some("2028-08-01".to_string()); star.market_value = 2_500_000; - star.attributes.pace = 88; + star.attributes.mechanics = 88; star.attributes.laning = 90; - star.attributes.mechanics = 87; let mut fringe = make_player(); fringe.contract_end = Some("2028-08-01".to_string()); fringe.market_value = 80_000; - fringe.attributes.pace = 50; + fringe.attributes.mechanics = 50; fringe.attributes.laning = 48; - fringe.attributes.mechanics = 49; let offer = RenewalOffer { weekly_wage: 14_000, diff --git a/src-tauri/crates/ofm_core/tests/end_of_season_tests.rs b/src-tauri/crates/ofm_core/tests/end_of_season_tests.rs index 2ce642a4b..aeced9cdc 100644 --- a/src-tauri/crates/ofm_core/tests/end_of_season_tests.rs +++ b/src-tauri/crates/ofm_core/tests/end_of_season_tests.rs @@ -28,25 +28,15 @@ fn make_team(id: &str, name: &str) -> Team { fn make_player(id: &str, name: &str, team_id: &str, pos: LolRole) -> Player { let attrs = PlayerAttributes { - pace: 65, mental_resilience: 65, - strength: 65, champion_pool: 65, - passing: 65, laning: 65, - tackling: 65, mechanics: 65, - defending: 65, - positioning: 65, macro_play: 65, consistency: 65, discipline: 65, - aggression: 50, teamfighting: 65, shotcalling: 50, - handling: 20, - reflexes: 30, - aerial: 60, }; let mut p = Player::new( id.to_string(), @@ -86,20 +76,18 @@ fn make_completed_fixture(id: &str, home: &str, away: &str, hg: u8, ag: u8) -> F fn make_standing( team_id: &str, won: u32, - drawn: u32, lost: u32, - gf: u32, - ga: u32, + maps_won: u32, + maps_lost: u32, ) -> StandingEntry { StandingEntry { team_id: team_id.to_string(), - played: won + drawn + lost, + played: won + lost, won, - drawn, lost, - kills_for: gf, - kills_against: ga, - points: won * 3 + drawn, + maps_won, + maps_lost, + points: won * 3, } } @@ -125,7 +113,6 @@ fn make_completed_season_game() -> Game { appearances: 30, kills: 20, assists: 10, - clean_sheets: 0, avg_rating: 7.5, minutes_played: 2700, ..PlayerSeasonStats::default() @@ -136,7 +123,6 @@ fn make_completed_season_game() -> Game { appearances: 28, kills: 15, assists: 8, - clean_sheets: 0, avg_rating: 7.0, minutes_played: 2500, ..PlayerSeasonStats::default() @@ -149,8 +135,8 @@ fn make_completed_season_game() -> Game { // team1 won both: 6 pts, team2 lost both: 0 pts let standings = vec![ - make_standing("team1", 2, 0, 0, 3, 1), - make_standing("team2", 0, 0, 2, 1, 3), + make_standing("team1", 2, 0, 3, 1), + make_standing("team2", 0, 2, 1, 3), ]; let league = League { @@ -219,10 +205,10 @@ fn season_not_complete_with_truncated_completed_fixture_list() { if let Some(league) = &mut game.league { league.standings = vec![ - make_standing("team1", 1, 0, 0, 2, 0), - make_standing("team4", 1, 0, 0, 1, 0), - make_standing("team3", 0, 0, 1, 0, 1), - make_standing("team2", 0, 0, 1, 0, 2), + make_standing("team1", 1, 0, 2, 0), + make_standing("team4", 1, 0, 1, 0), + make_standing("team3", 0, 1, 0, 1), + make_standing("team2", 0, 1, 0, 2), ]; league.fixtures = vec![ Fixture { @@ -289,7 +275,6 @@ fn summary_has_correct_user_position() { assert_eq!(summary.user_position, 1); assert_eq!(summary.user_points, 6); assert_eq!(summary.user_won, 2); - assert_eq!(summary.user_drawn, 0); assert_eq!(summary.user_lost, 0); } @@ -297,8 +282,8 @@ fn summary_has_correct_user_position() { fn summary_has_correct_goals() { let mut game = make_completed_season_game(); let summary = process_end_of_season(&mut game); - assert_eq!(summary.user_kills_for, 3); - assert_eq!(summary.user_kills_against, 1); + assert_eq!(summary.user_maps_won, 3); + assert_eq!(summary.user_maps_lost, 1); } #[test] @@ -323,7 +308,6 @@ fn team_history_recorded() { assert_eq!(record.season, 1); assert_eq!(record.league_position, 1); assert_eq!(record.won, 2); - assert_eq!(record.drawn, 0); assert_eq!(record.lost, 0); let team2 = game.teams.iter().find(|t| t.id == "team2").unwrap(); @@ -364,8 +348,9 @@ fn player_career_entry_added() { let entry = &p1.career[0]; assert_eq!(entry.season, 1); assert_eq!(entry.appearances, 30); - assert_eq!(entry.goals, 20); + assert_eq!(entry.kills, 20); assert_eq!(entry.assists, 10); + assert!((entry.avg_rating - 7.5).abs() < f32::EPSILON); } #[test] @@ -422,8 +407,8 @@ fn manager_no_trophy_for_non_first() { // Swap standings so team2 is first if let Some(league) = &mut game.league { league.standings = vec![ - make_standing("team2", 2, 0, 0, 3, 1), - make_standing("team1", 0, 0, 2, 1, 3), + make_standing("team2", 2, 0, 3, 1), + make_standing("team1", 0, 2, 1, 3), ]; } process_end_of_season(&mut game); @@ -463,7 +448,6 @@ fn manager_career_history_entry_updated_on_second_season() { end_date: None, matches: 10, wins: 5, - draws: 3, losses: 2, best_league_position: Some(3), }); @@ -691,10 +675,10 @@ fn top_half_finish_receives_expected_prize_money() { if let Some(league) = &mut game.league { league.standings = vec![ - make_standing("team2", 6, 0, 0, 12, 2), - make_standing("team1", 4, 0, 2, 8, 5), - make_standing("team3", 2, 0, 4, 4, 8), - make_standing("team4", 0, 0, 6, 2, 12), + make_standing("team2", 6, 0, 12, 2), + make_standing("team1", 4, 2, 8, 5), + make_standing("team3", 2, 4, 4, 8), + make_standing("team4", 0, 6, 2, 12), ]; } @@ -725,10 +709,10 @@ fn lower_table_finish_receives_expected_prize_money() { let mut standings = Vec::new(); for i in 2..=10 { - standings.push(make_standing(&format!("team{}", i), 10, 2, 6, 20, 15)); + standings.push(make_standing(&format!("team{}", i), 10, 6, 20, 15)); } - standings.push(make_standing("team1", 0, 0, 18, 2, 40)); + standings.push(make_standing("team1", 0, 18, 2, 40)); league.standings = standings; } @@ -862,10 +846,10 @@ fn mid_table_gets_appropriate_message() { if let Some(league) = &mut game.league { league.standings = vec![ - make_standing("team2", 6, 0, 0, 12, 2), - make_standing("team3", 4, 0, 2, 8, 5), - make_standing("team1", 2, 0, 4, 4, 8), // user team 3rd of 4 - make_standing("team4", 0, 0, 6, 2, 12), + make_standing("team2", 6, 0, 12, 2), + make_standing("team3", 4, 2, 8, 5), + make_standing("team1", 2, 4, 4, 8), // user team 3rd of 4 + make_standing("team4", 0, 6, 2, 12), ]; } @@ -887,10 +871,10 @@ fn bottom_half_gets_concerned_message() { if let Some(league) = &mut game.league { let mut standings = Vec::new(); for i in 2..=10 { - standings.push(make_standing(&format!("team{}", i), 10, 2, 6, 20, 15)); + standings.push(make_standing(&format!("team{}", i), 10, 6, 20, 15)); } // team1 (user) finishes dead last - standings.push(make_standing("team1", 0, 0, 18, 2, 40)); + standings.push(make_standing("team1", 0, 18, 2, 40)); league.standings = standings; } @@ -924,16 +908,16 @@ fn next_season_generation_ignores_academy_team_ids() { if let Some(league) = &mut game.league { league.standings = vec![ - make_standing("team1", 14, 2, 2, 36, 18), - make_standing("team2", 13, 2, 3, 34, 19), - make_standing("team3", 11, 3, 4, 30, 22), - make_standing("team4", 10, 4, 4, 27, 21), - make_standing("team5", 9, 4, 5, 24, 23), - make_standing("team6", 8, 3, 7, 22, 25), - make_standing("team7", 6, 5, 7, 20, 26), - make_standing("team8", 5, 5, 8, 19, 28), - make_standing("team9", 4, 4, 10, 16, 31), - make_standing("team10", 2, 4, 12, 12, 36), + make_standing("team1", 14, 2, 36, 18), + make_standing("team2", 13, 3, 34, 19), + make_standing("team3", 11, 4, 30, 22), + make_standing("team4", 10, 4, 27, 21), + make_standing("team5", 9, 5, 24, 23), + make_standing("team6", 8, 7, 22, 25), + make_standing("team7", 6, 7, 20, 26), + make_standing("team8", 5, 8, 19, 28), + make_standing("team9", 4, 10, 16, 31), + make_standing("team10", 2, 12, 12, 36), ]; } @@ -1167,8 +1151,8 @@ fn season_end_board_message_top_four_uses_correct_body_key() { // Make team1 finish 2nd (top-4 branch) if let Some(league) = &mut game.league { league.standings = vec![ - make_standing("team2", 2, 0, 0, 3, 1), - make_standing("team1", 0, 0, 2, 1, 3), + make_standing("team2", 2, 0, 3, 1), + make_standing("team1", 0, 2, 1, 3), ]; } process_end_of_season(&mut game); diff --git a/src-tauri/crates/ofm_core/tests/finances_tests.rs b/src-tauri/crates/ofm_core/tests/finances_tests.rs index 45897d583..35355c30a 100644 --- a/src-tauri/crates/ofm_core/tests/finances_tests.rs +++ b/src-tauri/crates/ofm_core/tests/finances_tests.rs @@ -34,25 +34,15 @@ fn make_team(id: &str, name: &str) -> Team { fn make_player(id: &str, team_id: &str, wage: u32) -> Player { let attrs = PlayerAttributes { - pace: 65, mental_resilience: 65, - strength: 65, champion_pool: 65, - passing: 65, laning: 65, - tackling: 65, mechanics: 65, - defending: 65, - positioning: 65, macro_play: 65, consistency: 65, discipline: 65, - aggression: 50, teamfighting: 65, shotcalling: 50, - handling: 20, - reflexes: 30, - aerial: 60, }; let mut p = Player::new( id.to_string(), diff --git a/src-tauri/crates/ofm_core/tests/live_match_manager_tests.rs b/src-tauri/crates/ofm_core/tests/live_match_manager_tests.rs index 739141abc..bf384572b 100644 --- a/src-tauri/crates/ofm_core/tests/live_match_manager_tests.rs +++ b/src-tauri/crates/ofm_core/tests/live_match_manager_tests.rs @@ -14,25 +14,15 @@ use ofm_core::live_match_manager::{self, MatchMode}; fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 65, mental_resilience: 65, - strength: 65, champion_pool: 65, - passing: 65, laning: 65, - tackling: 55, mechanics: 65, - defending: 55, - positioning: 65, macro_play: 65, consistency: 65, discipline: 65, - aggression: 50, teamfighting: 65, shotcalling: 50, - handling: 20, - reflexes: 30, - aerial: 60, } } @@ -65,45 +55,54 @@ fn make_team(id: &str, name: &str) -> Team { ) } -/// Build a full squad of 22 players for a team (4-4-2 formation ready). +/// Build a squad of players for a LoL team (5 starters + bench). fn make_squad(team_id: &str) -> Vec { let mut players = Vec::new(); - // 2 GK + // 2 Top for i in 0..2 { players.push(make_player( - &format!("{}_gk{}", team_id, i), - &format!("GK{}", i), + &format!("{}_top{}", team_id, i), + &format!("Top{}", i), team_id, - LolRole::Support, + LolRole::Top, )); } - // 7 DEF - for i in 0..7 { + // 2 Jungle + for i in 0..2 { players.push(make_player( - &format!("{}_def{}", team_id, i), - &format!("Def{}", i), + &format!("{}_jng{}", team_id, i), + &format!("Jng{}", i), team_id, - LolRole::Top, + LolRole::Jungle, )); } - // 7 MID - for i in 0..7 { + // 2 Mid + for i in 0..2 { players.push(make_player( &format!("{}_mid{}", team_id, i), &format!("Mid{}", i), team_id, - LolRole::Jungle, + LolRole::Mid, )); } - // 6 FWD - for i in 0..6 { + // 2 ADC + for i in 0..2 { players.push(make_player( - &format!("{}_fwd{}", team_id, i), - &format!("Fwd{}", i), + &format!("{}_adc{}", team_id, i), + &format!("Adc{}", i), team_id, LolRole::Adc, )); } + // 2 Support + for i in 0..2 { + players.push(make_player( + &format!("{}_sup{}", team_id, i), + &format!("Sup{}", i), + team_id, + LolRole::Support, + )); + } players } diff --git a/src-tauri/crates/ofm_core/tests/player_events_tests.rs b/src-tauri/crates/ofm_core/tests/player_events_tests.rs index 1bb422d6c..01e290c73 100644 --- a/src-tauri/crates/ofm_core/tests/player_events_tests.rs +++ b/src-tauri/crates/ofm_core/tests/player_events_tests.rs @@ -20,25 +20,15 @@ use ofm_core::player_events; fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, mental_resilience: 60, - strength: 60, champion_pool: 60, - passing: 60, laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, macro_play: 60, consistency: 60, discipline: 60, - aggression: 60, teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, } } @@ -939,13 +929,11 @@ fn recent_player_talk_enters_cooldown_and_blocks_same_day_repeat() { #[test] fn weighted_response_bias_changes_with_player_context() { let mut volatile = make_player("volatile", "Volatile", "team1", LolRole::Adc); - volatile.attributes.aggression = 95; volatile.attributes.discipline = 20; volatile.attributes.shotcalling = 20; volatile.morale_core.manager_trust = 30; let mut composed = make_player("composed", "Composed", "team1", LolRole::Adc); - composed.attributes.aggression = 20; composed.attributes.discipline = 95; composed.attributes.shotcalling = 95; composed.morale_core.manager_trust = 75; @@ -1478,10 +1466,9 @@ fn action_marked_resolved() { #[test] fn volatile_player_worse_outcomes_from_tough_love() { let mut game = make_game(); - // Make player volatile: high aggression, low composure + // Make player volatile: low composure, low shotcalling let player = game.players.iter_mut().find(|p| p.id == "p_fwd0").unwrap(); player.morale = 50; - player.attributes.aggression = 95; player.attributes.discipline = 20; player.attributes.shotcalling = 20; inject_player_message(&mut game, "morale_talk_p_fwd0", "p_fwd0", "respond"); @@ -1503,7 +1490,6 @@ fn volatile_player_worse_outcomes_from_tough_love() { // Now test composed player let player = game.players.iter_mut().find(|p| p.id == "p_fwd0").unwrap(); - player.attributes.aggression = 20; player.attributes.discipline = 95; player.attributes.shotcalling = 95; diff --git a/src-tauri/crates/ofm_core/tests/random_events_tests.rs b/src-tauri/crates/ofm_core/tests/random_events_tests.rs index bf8c814a6..5ee93475f 100644 --- a/src-tauri/crates/ofm_core/tests/random_events_tests.rs +++ b/src-tauri/crates/ofm_core/tests/random_events_tests.rs @@ -21,25 +21,15 @@ use std::collections::HashMap; fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, mental_resilience: 60, - strength: 60, champion_pool: 60, - passing: 60, laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, macro_play: 60, consistency: 60, discipline: 60, - aggression: 60, teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, } } @@ -1181,25 +1171,15 @@ fn unfit_players_get_more_training_injuries() { "England".to_string(), LolRole::Jungle, PlayerAttributes { - pace: 60, mental_resilience: 60, - strength: 60, champion_pool: 60, - passing: 60, laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, macro_play: 60, consistency: 60, discipline: 60, - aggression: 60, teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, }, ); player.team_id = Some("team1".to_string()); diff --git a/src-tauri/crates/ofm_core/tests/scouting_tests.rs b/src-tauri/crates/ofm_core/tests/scouting_tests.rs index a77f0d8d2..1a4e320b5 100644 --- a/src-tauri/crates/ofm_core/tests/scouting_tests.rs +++ b/src-tauri/crates/ofm_core/tests/scouting_tests.rs @@ -15,25 +15,15 @@ use ofm_core::scouting::{process_scouting, scout_max_assignments, send_scout}; fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 70, mental_resilience: 65, - strength: 60, champion_pool: 68, - passing: 72, laning: 66, - tackling: 58, mechanics: 74, - defending: 55, - positioning: 62, macro_play: 70, consistency: 64, discipline: 60, - aggression: 50, teamfighting: 66, shotcalling: 55, - handling: 30, - reflexes: 30, - aerial: 58, } } diff --git a/src-tauri/crates/ofm_core/tests/training_tests.rs b/src-tauri/crates/ofm_core/tests/training_tests.rs index 3d8076766..89f9be902 100644 --- a/src-tauri/crates/ofm_core/tests/training_tests.rs +++ b/src-tauri/crates/ofm_core/tests/training_tests.rs @@ -18,25 +18,15 @@ use ofm_core::training; fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 65, mental_resilience: 65, - strength: 65, champion_pool: 65, - passing: 65, laning: 65, - tackling: 65, mechanics: 65, - defending: 65, - positioning: 65, macro_play: 65, consistency: 65, discipline: 65, - aggression: 50, teamfighting: 65, shotcalling: 50, - handling: 20, - reflexes: 30, - aerial: 60, } } @@ -51,12 +41,12 @@ fn lol_visible_stat(player: &Player, stat: &str) -> u8 { "mechanics" => avg([ attrs.mechanics, attrs.champion_pool, - attrs.pace, + attrs.mechanics, attrs.discipline, ]), "laning" => avg([ attrs.laning, - attrs.positioning, + attrs.consistency, attrs.mechanics, attrs.discipline, ]), @@ -69,8 +59,8 @@ fn lol_visible_stat(player: &Player, stat: &str) -> u8 { "macro" => avg([ attrs.macro_play, attrs.consistency, - attrs.positioning, - attrs.passing, + attrs.consistency, + attrs.teamfighting, ]), "consistency" => avg([ attrs.consistency, @@ -88,7 +78,7 @@ fn lol_visible_stat(player: &Player, stat: &str) -> u8 { attrs.mechanics, attrs.champion_pool, attrs.macro_play, - attrs.passing, + attrs.teamfighting, ]), "discipline" => avg([ attrs.consistency, @@ -699,12 +689,12 @@ fn mental_reset_recovery_has_no_attribute_gains() { // Mental Reset / Recovery: no attribute gains at all for (i, p) in game.players.iter().enumerate() { assert_eq!( - p.attributes.pace, initial_attrs[i].pace, - "Mental Reset / Recovery should not change pace" + p.attributes.mechanics, initial_attrs[i].mechanics, + "Mental Reset / Recovery should not change mechanics" ); assert_eq!( p.attributes.laning, initial_attrs[i].laning, - "Mental Reset / Recovery should not change shooting" + "Mental Reset / Recovery should not change laning" ); } } @@ -737,7 +727,7 @@ fn no_coaching_staff_reduces_gains() { let mut game = Game::new(clock, manager, vec![team1], vec![p1], vec![], vec![]); // Train many sessions - let initial_pace = game.players[0].attributes.pace; + let initial_mechanics = game.players[0].attributes.mechanics; for _ in 0..200 { game.players[0].condition = 90; training::process_training(&mut game, 0); @@ -745,10 +735,10 @@ fn no_coaching_staff_reduces_gains() { // Should still gain something (just less than with staff) // The 0.8 penalty from no staff still allows some growth - let final_pace = game.players[0].attributes.pace; + let final_mechanics = game.players[0].attributes.mechanics; // After 200 intense sessions with a young player, some gain is expected assert!( - final_pace >= initial_pace, + final_mechanics >= initial_mechanics, "Should still gain attributes without staff" ); } @@ -915,20 +905,20 @@ fn young_player_gains_more_than_old() { game.teams[0].training_intensity = TrainingIntensity::High; game.teams[0].training_schedule = TrainingSchedule::Intense; - let p1_initial_pace = game + let p1_initial_mechanics = game .players .iter() .find(|p| p.id == "p1") .unwrap() .attributes - .pace; - let p3_initial_pace = game + .mechanics; + let p3_initial_mechanics = game .players .iter() .find(|p| p.id == "p3") .unwrap() .attributes - .pace; + .mechanics; for _ in 0..300 { for p in game.players.iter_mut() { @@ -937,23 +927,23 @@ fn young_player_gains_more_than_old() { training::process_training(&mut game, 0); } - let p1_final_pace = game + let p1_final_mechanics = game .players .iter() .find(|p| p.id == "p1") .unwrap() .attributes - .pace; - let p3_final_pace = game + .mechanics; + let p3_final_mechanics = game .players .iter() .find(|p| p.id == "p3") .unwrap() .attributes - .pace; + .mechanics; - let p1_gain = p1_final_pace - p1_initial_pace; - let p3_gain = p3_final_pace - p3_initial_pace; + let p1_gain = p1_final_mechanics - p1_initial_mechanics; + let p3_gain = p3_final_mechanics - p3_initial_mechanics; assert!( p1_gain >= p3_gain, diff --git a/src-tauri/crates/ofm_core/tests/transfers_tests.rs b/src-tauri/crates/ofm_core/tests/transfers_tests.rs index 168da0b0b..7b2d94f3e 100644 --- a/src-tauri/crates/ofm_core/tests/transfers_tests.rs +++ b/src-tauri/crates/ofm_core/tests/transfers_tests.rs @@ -17,25 +17,15 @@ use ofm_core::transfers::{ fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, mental_resilience: 60, - strength: 60, champion_pool: 60, - passing: 60, laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, macro_play: 60, consistency: 60, discipline: 60, - aggression: 60, teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, } } @@ -291,7 +281,6 @@ fn key_player_is_harder_to_buy_than_fringe_player() { let mut star = make_player("player-star"); star.attributes.laning = 88; star.attributes.mechanics = 86; - star.attributes.pace = 84; let mut star_game = make_game_with_player(star, vec!["player-star".to_string()], 5_000_000, 2_000_000); diff --git a/src-tauri/crates/ofm_core/tests/turn_tests.rs b/src-tauri/crates/ofm_core/tests/turn_tests.rs index a690d6f55..70228fc46 100644 --- a/src-tauri/crates/ofm_core/tests/turn_tests.rs +++ b/src-tauri/crates/ofm_core/tests/turn_tests.rs @@ -21,49 +21,29 @@ use std::collections::HashMap; fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, mental_resilience: 60, - strength: 60, champion_pool: 60, - passing: 60, laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, macro_play: 60, consistency: 60, discipline: 60, - aggression: 60, teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, } } fn gk_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 40, mental_resilience: 50, - strength: 60, champion_pool: 70, - passing: 40, laning: 20, - tackling: 20, mechanics: 20, - defending: 30, - positioning: 70, macro_play: 50, consistency: 60, discipline: 70, - aggression: 30, teamfighting: 60, shotcalling: 50, - handling: 80, - reflexes: 80, - aerial: 70, } } @@ -551,8 +531,8 @@ fn apply_match_report_updates_standings() { assert_eq!(home.played, 1); assert_eq!(home.won, 1); assert_eq!(home.points, 3); - assert_eq!(home.kills_for, 2); - assert_eq!(home.kills_against, 1); + assert_eq!(home.maps_won, 2); + assert_eq!(home.maps_lost, 1); assert_eq!(away.played, 1); assert_eq!(away.lost, 1); @@ -569,9 +549,7 @@ fn apply_match_report_draw_standings() { let home = standings.iter().find(|s| s.team_id == "team1").unwrap(); let away = standings.iter().find(|s| s.team_id == "team2").unwrap(); - assert_eq!(home.drawn, 1); assert_eq!(home.points, 1); - assert_eq!(away.drawn, 1); assert_eq!(away.points, 1); } @@ -613,7 +591,7 @@ fn apply_match_report_gk_clean_sheet() { turn::apply_match_report(&mut game, 0, "team1", "team2", &report); let gk = game.players.iter().find(|p| p.id == "t1_gk").unwrap(); - assert_eq!(gk.stats.clean_sheets, 1); + // clean_sheets removed in LoL migration } #[test] @@ -635,7 +613,7 @@ fn apply_match_report_gk_no_clean_sheet_on_conceding() { turn::apply_match_report(&mut game, 0, "team1", "team2", &report); let gk = game.players.iter().find(|p| p.id == "t1_gk").unwrap(); - assert_eq!(gk.stats.clean_sheets, 0); + // clean_sheets removed in LoL migration } #[test] @@ -1456,17 +1434,16 @@ fn standing_entry( team_id: &str, played: u32, points: u32, - kills_for: u32, - kills_against: u32, + maps_won: u32, + maps_lost: u32, ) -> StandingEntry { StandingEntry { team_id: team_id.to_string(), played, won: 0, - drawn: 0, lost: 0, - kills_for, - kills_against, + maps_won, + maps_lost, points, } } @@ -1479,15 +1456,9 @@ fn set_team_overall(game: &mut Game, team_id: &str, overall: u8) { } fn set_player_overall(player: &mut Player, overall: u8) { - player.attributes.pace = overall; player.attributes.mental_resilience = overall; - player.attributes.strength = overall; - player.attributes.passing = overall; player.attributes.laning = overall; - player.attributes.tackling = overall; player.attributes.mechanics = overall; - player.attributes.defending = overall; - player.attributes.positioning = overall; player.attributes.macro_play = overall; player.attributes.consistency = overall; } diff --git a/src-tauri/databases/lec_world.json b/src-tauri/databases/lec_world.json deleted file mode 100644 index 3c3c01c10..000000000 --- a/src-tauri/databases/lec_world.json +++ /dev/null @@ -1,25189 +0,0 @@ -{ - "name": "LEC 2026", - "description": "Mundo predefinido de League of Legends (LEC) para OpenFootManager adaptado.", - "teams": [ - { - "id": "lec-fnatic", - "name": "Fnatic", - "short_name": "FNC", - "country": "GB", - "city": "London", - "stadium_name": "Fnatic Arena", - "stadium_capacity": 28000, - "finance": 3500000, - "manager_id": null, - "reputation": 500, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": null, - "academy": null, - "wage_budget": 1300000, - "transfer_budget": 450000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2004, - "colors": { - "primary": "#191919", - "secondary": "#FF5900" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-g2-esports", - "name": "G2 Esports", - "short_name": "G2", - "country": "DE", - "city": "Berlin", - "stadium_name": "G2 Esports Arena", - "stadium_capacity": 28000, - "finance": 4500000, - "manager_id": null, - "reputation": 650, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": "academy-prime-league-g2-nord", - "academy": null, - "wage_budget": 1600000, - "transfer_budget": 700000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2014, - "colors": { - "primary": "#1A1A1B", - "secondary": "#FF0000" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-giantx-lec", - "name": "GIANTX", - "short_name": "GX", - "country": "ES", - "city": "Málaga", - "stadium_name": "GIANTX Arena", - "stadium_capacity": 28000, - "finance": 3500000, - "manager_id": null, - "reputation": 500, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": "academy-liga-espanola-giantx-itero", - "academy": null, - "wage_budget": 1100000, - "transfer_budget": 400000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2008, - "colors": { - "primary": "#001D3D", - "secondary": "#000000" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-karmine-corp", - "name": "Karmine Corp", - "short_name": "KC", - "country": "FR", - "city": "Paris", - "stadium_name": "Karmine Corp Arena", - "stadium_capacity": 28000, - "finance": 4500000, - "manager_id": null, - "reputation": 650, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": "academy-lfl-karmine-corp-blue", - "academy": null, - "wage_budget": 1600000, - "transfer_budget": 700000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2020, - "colors": { - "primary": "#003566", - "secondary": "#00A8E8" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-mad-lions", - "name": "Movistar KOI", - "short_name": "MKOI", - "country": "ES", - "city": "Madrid", - "stadium_name": "Movistar KOI Arena", - "stadium_capacity": 28000, - "finance": 4500000, - "manager_id": null, - "reputation": 650, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": "academy-liga-espanola-movistar-koi-f-nix", - "academy": null, - "wage_budget": 1400000, - "transfer_budget": 650000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2021, - "colors": { - "primary": "#9327FF", - "secondary": "#00E5FF" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-natus-vincere", - "name": "Natus Vincere", - "short_name": "NAVI", - "country": "UA", - "city": "Kyiv", - "stadium_name": "Natus Vincere Arena", - "stadium_capacity": 28000, - "finance": 3500000, - "manager_id": null, - "reputation": 500, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": null, - "academy": null, - "wage_budget": 1300000, - "transfer_budget": 500000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2009, - "colors": { - "primary": "#231F20", - "secondary": "#FFFF00" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-shifters", - "name": "Shifters", - "short_name": "SHFT", - "country": "CH", - "city": "Geneva", - "stadium_name": "Shifters Arena", - "stadium_capacity": 28000, - "finance": 3000000, - "manager_id": null, - "reputation": 350, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": null, - "academy": null, - "wage_budget": 1000000, - "transfer_budget": 350000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2012, - "colors": { - "primary": "#D4AF37", - "secondary": "#121212" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-sk-gaming", - "name": "SK Gaming", - "short_name": "SK", - "country": "DE", - "city": "Berlin", - "stadium_name": "SK Gaming Arena", - "stadium_capacity": 28000, - "finance": 3000000, - "manager_id": null, - "reputation": 350, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": null, - "academy": null, - "wage_budget": 1000000, - "transfer_budget": 350000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1997, - "colors": { - "primary": "#000000", - "secondary": "#FFFFFF" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-team-heretics-lec", - "name": "Team Heretics", - "short_name": "TH", - "country": "ES", - "city": "Madrid", - "stadium_name": "Team Heretics Arena", - "stadium_capacity": 28000, - "finance": 3500000, - "manager_id": null, - "reputation": 500, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": "academy-liga-espanola-team-heretics", - "academy": null, - "wage_budget": 900000, - "transfer_budget": 350000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2016, - "colors": { - "primary": "#FFFFFF", - "secondary": "#2A2A2A" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "lec-team-vitality", - "name": "Team Vitality", - "short_name": "VIT", - "country": "FR", - "city": "Paris", - "stadium_name": "Team Vitality Arena", - "stadium_capacity": 28000, - "finance": 4500000, - "manager_id": null, - "reputation": 650, - "team_kind": "Main", - "parent_team_id": null, - "academy_team_id": "academy-lfl-team-vitality-bee", - "academy": null, - "wage_budget": 1300000, - "transfer_budget": 600000, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 2, - "medical": 2, - "scouting": 2 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "MacroSystems", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 2013, - "colors": { - "primary": "#000000", - "secondary": "#FFD700" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-movistar-koi-f-nix", - "name": "Movistar KOI Fénix", - "short_name": "MKF", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "MKF Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6200, - "team_kind": "Academy", - "parent_team_id": "lec-mad-lions", - "academy_team_id": null, - "academy": { - "lifecycle": "Active", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 62, - "acquisition_cost": 0, - "acquired_at": "2025-01-01", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-movistar-koi-f-nix", - "original_name": "Movistar KOI Fénix", - "original_short_name": "MKF", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bd/Movistar_KOIlogo_square.png/revision/latest/scale-to-width-down/220?cb=20240528162718", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bd/Movistar_KOIlogo_square.png/revision/latest/scale-to-width-down/220?cb=20240528162718", - "acquisition_cost": 0, - "acquired_at": "2025-01-01" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-team-heretics", - "name": "Team Heretics", - "short_name": "TH", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "TH Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6200, - "team_kind": "Academy", - "parent_team_id": "lec-team-heretics-lec", - "academy_team_id": null, - "academy": { - "lifecycle": "Active", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 62, - "acquisition_cost": 0, - "acquired_at": "2025-01-01", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-team-heretics", - "original_name": "Team Heretics", - "original_short_name": "TH", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bf/Team_Hereticslogo_square.png/revision/latest/scale-to-width-down/220?cb=20251230025102", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bf/Team_Hereticslogo_square.png/revision/latest/scale-to-width-down/220?cb=20251230025102", - "acquisition_cost": 0, - "acquired_at": "2025-01-01" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-barcelona-esports", - "name": "Barcelona Esports", - "short_name": "BE", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "BE Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-barcelona-esports", - "original_name": "Barcelona Esports", - "original_short_name": "BE", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/68/Bar%C3%A7a_eSportslogo_square.png/revision/latest/scale-to-width-down/220?cb=20221118223547", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/68/Bar%C3%A7a_eSportslogo_square.png/revision/latest/scale-to-width-down/220?cb=20221118223547", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-giantx-itero", - "name": "GiantX Itero", - "short_name": "GI", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "GI Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6200, - "team_kind": "Academy", - "parent_team_id": "lec-giantx-lec", - "academy_team_id": null, - "academy": { - "lifecycle": "Active", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 62, - "acquisition_cost": 0, - "acquired_at": "2025-01-01", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-giantx-itero", - "original_name": "GiantX Itero", - "original_short_name": "GI", - "original_logo_url": "https://upload.wikimedia.org/wikipedia/en/0/0e/GiantX_logo.svg", - "current_logo_url": "https://upload.wikimedia.org/wikipedia/en/0/0e/GiantX_logo.svg", - "acquisition_cost": 0, - "acquired_at": "2025-01-01" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-ucam-esports", - "name": "UCAM Esports", - "short_name": "UE", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "UE Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-ucam-esports", - "original_name": "UCAM Esports", - "original_short_name": "UE", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/ad/UCAM_Esports_Clublogo_square.png/revision/latest/scale-to-width-down/220?cb=20251113225931", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/ad/UCAM_Esports_Clublogo_square.png/revision/latest/scale-to-width-down/220?cb=20251113225931", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-falke-esports", - "name": "Falke Esports", - "short_name": "FE", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "FE Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-falke-esports", - "original_name": "Falke Esports", - "original_short_name": "FE", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/b0/Falke_Esportslogo_square.png/revision/latest/scale-to-width-down/220?cb=20250917172449", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/b0/Falke_Esportslogo_square.png/revision/latest/scale-to-width-down/220?cb=20250917172449", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-lua-gaming", - "name": "LUA Gaming", - "short_name": "LG", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "LG Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-lua-gaming", - "original_name": "LUA Gaming", - "original_short_name": "LG", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/b8/LUA_Gaminglogo_square.png/revision/latest/scale-to-width-down/220?cb=20231214150503", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/b8/LUA_Gaminglogo_square.png/revision/latest/scale-to-width-down/220?cb=20231214150503", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-liga-espanola-ub-alma-mater", - "name": "UB Alma Mater", - "short_name": "UAM", - "country": "ES", - "city": "Liga Espanola", - "stadium_name": "UAM Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "liga-espanola", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Liga Espanola academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-liga-espanola-ub-alma-mater", - "original_name": "UB Alma Mater", - "original_short_name": "UAM", - "original_logo_url": "https://images.seeklogo.com/logo-png/50/2/universitat-de-barcelona-logo-png_seeklogo-500551.png", - "current_logo_url": "https://images.seeklogo.com/logo-png/50/2/universitat-de-barcelona-logo-png_seeklogo-500551.png", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-solary", - "name": "Solary", - "short_name": "S", - "country": "FR", - "city": "LFL", - "stadium_name": "S Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-solary", - "original_name": "Solary", - "original_short_name": "S", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/ec/Solarylogo_square.png/revision/latest/scale-to-width-down/220?cb=20181130231519", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/ec/Solarylogo_square.png/revision/latest/scale-to-width-down/220?cb=20181130231519", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-galions", - "name": "Galions", - "short_name": "G", - "country": "FR", - "city": "LFL", - "stadium_name": "G Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-galions", - "original_name": "Galions", - "original_short_name": "G", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/61/Galionslogo_square.png/revision/latest/scale-to-width-down/220?cb=20241209190639", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/61/Galionslogo_square.png/revision/latest/scale-to-width-down/220?cb=20241209190639", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-french-flair", - "name": "French Flair", - "short_name": "FF", - "country": "FR", - "city": "LFL", - "stadium_name": "FF Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-french-flair", - "original_name": "French Flair", - "original_short_name": "FF", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/05/French_Flairlogo_square.png/revision/latest/scale-to-width-down/220?cb=20251203202820", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/05/French_Flairlogo_square.png/revision/latest/scale-to-width-down/220?cb=20251203202820", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-joblife", - "name": "JOblife", - "short_name": "J", - "country": "FR", - "city": "LFL", - "stadium_name": "J Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-joblife", - "original_name": "JOblife", - "original_short_name": "J", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bf/Joblifelogo_profile.png/revision/latest/scale-to-width-down/220?cb=20221219183313", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bf/Joblifelogo_profile.png/revision/latest/scale-to-width-down/220?cb=20221219183313", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-tln-pirates", - "name": "TLN Pirates", - "short_name": "TP", - "country": "FR", - "city": "LFL", - "stadium_name": "TP Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-tln-pirates", - "original_name": "TLN Pirates", - "original_short_name": "TP", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/06/TLN_Pirateslogo_square.png/revision/latest/scale-to-width-down/220?cb=20260114195706", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/06/TLN_Pirateslogo_square.png/revision/latest/scale-to-width-down/220?cb=20260114195706", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-skillcamp", - "name": "Skillcamp", - "short_name": "S", - "country": "FR", - "city": "LFL", - "stadium_name": "S Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-skillcamp", - "original_name": "Skillcamp", - "original_short_name": "S", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/a2/Skillcamplogo_profile.png/revision/latest/scale-to-width-down/220?cb=20260216032253", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/a2/Skillcamplogo_profile.png/revision/latest/scale-to-width-down/220?cb=20260216032253", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-ici-japon-corp-esport", - "name": "Ici Japon Corp. Esport", - "short_name": "IJCE", - "country": "FR", - "city": "LFL", - "stadium_name": "IJCE Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-ici-japon-corp-esport", - "original_name": "Ici Japon Corp. Esport", - "original_short_name": "IJCE", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/7a/Ici_Japon_Corp._Esportlogo_square.png/revision/latest/scale-to-width-down/220?cb=20241006054235", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/7a/Ici_Japon_Corp._Esportlogo_square.png/revision/latest/scale-to-width-down/220?cb=20241006054235", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-zyb-esport", - "name": "ZYB Esport", - "short_name": "ZE", - "country": "FR", - "city": "LFL", - "stadium_name": "ZE Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-zyb-esport", - "original_name": "ZYB Esport", - "original_short_name": "ZE", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/72/ZYB_Esportlogo_square.png/revision/latest/scale-to-width-down/220?cb=20260110152035", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/72/ZYB_Esportlogo_square.png/revision/latest/scale-to-width-down/220?cb=20260110152035", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-karmine-corp-blue", - "name": "Karmine Corp Blue", - "short_name": "KCB", - "country": "FR", - "city": "LFL", - "stadium_name": "KCB Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6200, - "team_kind": "Academy", - "parent_team_id": "lec-karmine-corp", - "academy_team_id": null, - "academy": { - "lifecycle": "Active", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 62, - "acquisition_cost": 0, - "acquired_at": "2025-01-01", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-karmine-corp-blue", - "original_name": "Karmine Corp Blue", - "original_short_name": "KCB", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/9f/Karmine_Corp_Bluelogo_profile.png/revision/latest/scale-to-width-down/220?cb=20260110071859", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/9f/Karmine_Corp_Bluelogo_profile.png/revision/latest/scale-to-width-down/220?cb=20260110071859", - "acquisition_cost": 0, - "acquired_at": "2025-01-01" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-lfl-team-vitality-bee", - "name": "Team Vitality.Bee", - "short_name": "TV", - "country": "FR", - "city": "LFL", - "stadium_name": "TV Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6200, - "team_kind": "Academy", - "parent_team_id": "lec-team-vitality", - "academy_team_id": null, - "academy": { - "lifecycle": "Active", - "erl_assignment": { - "erl_league_id": "lfl", - "country_rule": "Domestic", - "fallback_reason": "Seeded from LFL academy roster", - "reputation": 62, - "acquisition_cost": 0, - "acquired_at": "2025-01-01", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-lfl-team-vitality-bee", - "original_name": "Team Vitality.Bee", - "original_short_name": "TV", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/86/Team_Vitalitylogo_square.png/revision/latest/scale-to-width-down/220?cb=20230224142251", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/86/Team_Vitalitylogo_square.png/revision/latest/scale-to-width-down/220?cb=20230224142251", - "acquisition_cost": 0, - "acquired_at": "2025-01-01" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-eintracht-spandau", - "name": "Eintracht Spandau", - "short_name": "ES", - "country": "DE", - "city": "Prime League", - "stadium_name": "ES Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-eintracht-spandau", - "original_name": "Eintracht Spandau", - "original_short_name": "ES", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f6/Eintracht_Spandaulogo_square.png/revision/latest/scale-to-width-down/220?cb=20211114183152", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f6/Eintracht_Spandaulogo_square.png/revision/latest/scale-to-width-down/220?cb=20211114183152", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-g2-nord", - "name": "G2 Nord", - "short_name": "GN", - "country": "DE", - "city": "Prime League", - "stadium_name": "GN Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6200, - "team_kind": "Academy", - "parent_team_id": "lec-g2-esports", - "academy_team_id": null, - "academy": { - "lifecycle": "Active", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 62, - "acquisition_cost": 0, - "acquired_at": "2025-01-01", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-g2-nord", - "original_name": "G2 Nord", - "original_short_name": "GN", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/d7/G2_NORDlogo_square.png/revision/latest/scale-to-width-down/220?cb=20260114141330", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/d7/G2_NORDlogo_square.png/revision/latest/scale-to-width-down/220?cb=20260114141330", - "acquisition_cost": 0, - "acquired_at": "2025-01-01" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-team-orange-gaming", - "name": "Team Orange Gaming", - "short_name": "TOG", - "country": "DE", - "city": "Prime League", - "stadium_name": "TOG Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-team-orange-gaming", - "original_name": "Team Orange Gaming", - "original_short_name": "TOG", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f3/TeamOrangeGaminglogo_profile.png/revision/latest/scale-to-width-down/220?cb=20250222213601", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f3/TeamOrangeGaminglogo_profile.png/revision/latest/scale-to-width-down/220?cb=20250222213601", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-kaufland-hangry-knights", - "name": "Kaufland Hangry Knights", - "short_name": "KHK", - "country": "DE", - "city": "Prime League", - "stadium_name": "KHK Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-kaufland-hangry-knights", - "original_name": "Kaufland Hangry Knights", - "original_short_name": "KHK", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/4/4c/Kaufland_Hangry_Knightslogo_square.png/revision/latest/scale-to-width-down/220?cb=20250122013351", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/4/4c/Kaufland_Hangry_Knightslogo_square.png/revision/latest/scale-to-width-down/220?cb=20250122013351", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-rossmann-centaurs", - "name": "ROSSMANN Centaurs", - "short_name": "RC", - "country": "DE", - "city": "Prime League", - "stadium_name": "RC Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-rossmann-centaurs", - "original_name": "ROSSMANN Centaurs", - "original_short_name": "RC", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/8e/ROSSMANN_Centaurslogo_square.png/revision/latest/scale-to-width-down/220?cb=20250122010633", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/8e/ROSSMANN_Centaurslogo_square.png/revision/latest/scale-to-width-down/220?cb=20250122010633", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-a-one-man-army", - "name": "A One Man Army", - "short_name": "AOMA", - "country": "DE", - "city": "Prime League", - "stadium_name": "AOMA Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-a-one-man-army", - "original_name": "A One Man Army", - "original_short_name": "AOMA", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6f/A_One_Man_Armylogo_square.png/revision/latest/scale-to-width-down/220?cb=20230130144153", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6f/A_One_Man_Armylogo_square.png/revision/latest/scale-to-width-down/220?cb=20230130144153", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-e-wie-einfach-e-sports", - "name": "E WIE EINFACH E-SPORTS", - "short_name": "EWEE", - "country": "DE", - "city": "Prime League", - "stadium_name": "EWEE Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-e-wie-einfach-e-sports", - "original_name": "E WIE EINFACH E-SPORTS", - "original_short_name": "EWEE", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/70/E_WIE_EINFACH_E-SPORTSlogo_profile.png/revision/latest/scale-to-width-down/220?cb=20260113120025", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/70/E_WIE_EINFACH_E-SPORTSlogo_profile.png/revision/latest/scale-to-width-down/220?cb=20260113120025", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-unicorns-of-love-sexy-edition", - "name": "Unicorns of Love Sexy Edition", - "short_name": "UOLS", - "country": "DE", - "city": "Prime League", - "stadium_name": "UOLS Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-unicorns-of-love-sexy-edition", - "original_name": "Unicorns of Love Sexy Edition", - "original_short_name": "UOLS", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/93/Unicorns_of_Love_Sexy_Editionlogo_square.png/revision/latest/scale-to-width-down/220?cb=20200224135443", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/93/Unicorns_of_Love_Sexy_Editionlogo_square.png/revision/latest/scale-to-width-down/220?cb=20200224135443", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-berlin-international-gaming", - "name": "Berlin International Gaming", - "short_name": "BIG", - "country": "DE", - "city": "Prime League", - "stadium_name": "BIG Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-berlin-international-gaming", - "original_name": "Berlin International Gaming", - "original_short_name": "BIG", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/62/Berlin_International_Gaminglogo_square.png/revision/latest/scale-to-width-down/220?cb=20200718200002", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/62/Berlin_International_Gaminglogo_square.png/revision/latest/scale-to-width-down/220?cb=20200718200002", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - }, - { - "id": "academy-prime-league-eintracht-frankfurt", - "name": "Eintracht Frankfurt", - "short_name": "EF", - "country": "DE", - "city": "Prime League", - "stadium_name": "EF Academy Arena", - "stadium_capacity": 2500, - "finance": 0, - "manager_id": null, - "reputation": 6000, - "team_kind": "Academy", - "parent_team_id": null, - "academy_team_id": null, - "academy": { - "lifecycle": "Planned", - "erl_assignment": { - "erl_league_id": "prime-league", - "country_rule": "Domestic", - "fallback_reason": "Seeded from Prime League academy roster", - "reputation": 60, - "acquisition_cost": 0, - "acquired_at": "", - "created_at": "2025-01-01" - }, - "source_team_id": "academy-prime-league-eintracht-frankfurt", - "original_name": "Eintracht Frankfurt", - "original_short_name": "EF", - "original_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/38/Eintracht_Frankfurtlogo_square.png/revision/latest/scale-to-width-down/220?cb=20210818183713", - "current_logo_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/38/Eintracht_Frankfurtlogo_square.png/revision/latest/scale-to-width-down/220?cb=20210818183713", - "acquisition_cost": 0, - "acquired_at": "" - }, - "wage_budget": 0, - "transfer_budget": 0, - "season_income": 0, - "season_expenses": 0, - "financial_ledger": [], - "sponsorship": null, - "facilities": { - "training": 1, - "medical": 1, - "scouting": 1 - }, - "formation": "4-4-2", - "play_style": "Balanced", - "lol_tactics": { - "strong_side": "Bot", - "game_timing": "Mid", - "jungle_style": "Enabler", - "jungle_pathing": "TopToBot", - "fight_plan": "FrontToBack", - "support_roaming": "Lane" - }, - "training_focus": "Scrims", - "training_intensity": "Medium", - "training_schedule": "Balanced", - "founded_year": 1900, - "colors": { - "primary": "#10b981", - "secondary": "#ffffff" - }, - "training_groups": [], - "weekly_scrim_opponent_ids": [], - "scrim_loss_streak": 0, - "scrim_weekly_played": 0, - "scrim_weekly_wins": 0, - "scrim_weekly_losses": 0, - "scrim_slot_results": [], - "starting_xi_ids": [], - "match_roles": { - "captain": null, - "vice_captain": null, - "penalty_taker": null, - "free_kick_taker": null, - "corner_taker": null - }, - "form": [], - "history": [] - } - ], - "players": [ - { - "id": "lec-player-109705412728201213", - "match_name": "Empyros", - "full_name": "Panagiotis Tantis", - "date_of_birth": "2004-04-01", - "nationality": "GR", - "birth_country": "GR", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 76, - "strength": 70, - "agility": 74, - "passing": 65, - "shooting": 73, - "tackling": 71, - "dribbling": 74, - "defending": 72, - "positioning": 65, - "vision": 75, - "decisions": 78, - "composure": 79, - "aggression": 56, - "teamwork": 74, - "leadership": 74, - "handling": 20, - "reflexes": 20, - "aerial": 66 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-fnatic", - "traits": [], - "contract_end": null, - "wage": 77000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-100238780551262852", - "match_name": "Razork", - "full_name": "Iván Martín Díaz", - "date_of_birth": "2000-10-07", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 79, - "strength": 67, - "agility": 82, - "passing": 75, - "shooting": 81, - "tackling": 61, - "dribbling": 84, - "defending": 65, - "positioning": 68, - "vision": 80, - "decisions": 78, - "composure": 81, - "aggression": 59, - "teamwork": 83, - "leadership": 80, - "handling": 20, - "reflexes": 20, - "aerial": 56 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-fnatic", - "traits": [], - "contract_end": null, - "wage": 269000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107045034481599547", - "match_name": "Vladi", - "full_name": "Vladimiros Kourtidis", - "date_of_birth": "2005-08-12", - "nationality": "GR", - "birth_country": "GR", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 77, - "strength": 65, - "agility": 77, - "passing": 73, - "shooting": 77, - "tackling": 59, - "dribbling": 80, - "defending": 63, - "positioning": 66, - "vision": 79, - "decisions": 73, - "composure": 75, - "aggression": 57, - "teamwork": 79, - "leadership": 78, - "handling": 20, - "reflexes": 20, - "aerial": 54 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-fnatic", - "traits": [], - "contract_end": null, - "wage": 328000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-99322214653265200", - "match_name": "Upset", - "full_name": "Elias Lipp", - "date_of_birth": "1999-12-16", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 81, - "strength": 69, - "agility": 76, - "passing": 70, - "shooting": 84, - "tackling": 51, - "dribbling": 85, - "defending": 48, - "positioning": 74, - "vision": 81, - "decisions": 82, - "composure": 82, - "aggression": 61, - "teamwork": 80, - "leadership": 79, - "handling": 20, - "reflexes": 20, - "aerial": 58 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-fnatic", - "traits": [], - "contract_end": null, - "wage": 248000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 81, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107492067202132417", - "match_name": "Lospa", - "full_name": "Joon-hyeong Park", - "date_of_birth": "2002-09-30", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 78, - "strength": 62, - "agility": 77, - "passing": 70, - "shooting": 82, - "tackling": 66, - "dribbling": 81, - "defending": 60, - "positioning": 63, - "vision": 80, - "decisions": 78, - "composure": 78, - "aggression": 54, - "teamwork": 80, - "leadership": 75, - "handling": 20, - "reflexes": 20, - "aerial": 51 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-fnatic", - "traits": [], - "contract_end": null, - "wage": 60000, - "market_value": 150000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 85, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-99566406047571736", - "match_name": "BrokenBlade", - "full_name": "Sergen Çelik", - "date_of_birth": "2000-01-19", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 83, - "strength": 76, - "agility": 88, - "passing": 71, - "shooting": 86, - "tackling": 77, - "dribbling": 84, - "defending": 78, - "positioning": 71, - "vision": 86, - "decisions": 80, - "composure": 83, - "aggression": 62, - "teamwork": 84, - "leadership": 84, - "handling": 20, - "reflexes": 20, - "aerial": 72 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-g2-esports", - "traits": [], - "contract_end": null, - "wage": 268000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 84, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107128052280762804", - "match_name": "SkewMond", - "full_name": "Rudy Semaan", - "date_of_birth": "2004-08-09", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 88, - "strength": 73, - "agility": 83, - "passing": 81, - "shooting": 88, - "tackling": 67, - "dribbling": 87, - "defending": 71, - "positioning": 74, - "vision": 84, - "decisions": 86, - "composure": 86, - "aggression": 65, - "teamwork": 86, - "leadership": 82, - "handling": 20, - "reflexes": 20, - "aerial": 62 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-g2-esports", - "traits": [], - "contract_end": null, - "wage": 310000, - "market_value": 240000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 92, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-98767975968177297", - "match_name": "Caps", - "full_name": "Rasmus Winther", - "date_of_birth": "1999-11-17", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 92, - "strength": 73, - "agility": 86, - "passing": 81, - "shooting": 85, - "tackling": 67, - "dribbling": 85, - "defending": 71, - "positioning": 74, - "vision": 93, - "decisions": 90, - "composure": 90, - "aggression": 65, - "teamwork": 88, - "leadership": 93, - "handling": 20, - "reflexes": 20, - "aerial": 62 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-g2-esports", - "traits": [], - "contract_end": null, - "wage": 356000, - "market_value": 230000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 89, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-98767975961872793", - "match_name": "Hans Sama", - "full_name": "Steven Liv", - "date_of_birth": "1999-09-02", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 78, - "stamina": 84, - "strength": 71, - "agility": 79, - "passing": 72, - "shooting": 84, - "tackling": 53, - "dribbling": 85, - "defending": 50, - "positioning": 76, - "vision": 84, - "decisions": 86, - "composure": 85, - "aggression": 63, - "teamwork": 84, - "leadership": 83, - "handling": 20, - "reflexes": 20, - "aerial": 60 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-g2-esports", - "traits": [], - "contract_end": null, - "wage": 350000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 84, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-102787200059605684", - "match_name": "Labrov", - "full_name": "Labros Papoutsakis", - "date_of_birth": "2002-02-12", - "nationality": "GR", - "birth_country": "GR", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 80, - "strength": 71, - "agility": 80, - "passing": 79, - "shooting": 84, - "tackling": 75, - "dribbling": 83, - "defending": 69, - "positioning": 72, - "vision": 82, - "decisions": 80, - "composure": 82, - "aggression": 63, - "teamwork": 83, - "leadership": 77, - "handling": 20, - "reflexes": 20, - "aerial": 60 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-g2-esports", - "traits": [], - "contract_end": null, - "wage": 182000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-103495716738607011", - "match_name": "Lot", - "full_name": "Eren Yıldız", - "date_of_birth": "2004-01-02", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 76, - "strength": 71, - "agility": 76, - "passing": 66, - "shooting": 80, - "tackling": 72, - "dribbling": 82, - "defending": 73, - "positioning": 66, - "vision": 76, - "decisions": 75, - "composure": 78, - "aggression": 57, - "teamwork": 79, - "leadership": 78, - "handling": 20, - "reflexes": 20, - "aerial": 67 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-giantx-lec", - "traits": [], - "contract_end": null, - "wage": 147000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107464179845128878", - "match_name": "ISMA", - "full_name": "Ismaïl Boualem", - "date_of_birth": "2001-06-20", - "nationality": "BE", - "birth_country": "BE", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 79, - "strength": 66, - "agility": 76, - "passing": 74, - "shooting": 77, - "tackling": 60, - "dribbling": 79, - "defending": 64, - "positioning": 67, - "vision": 79, - "decisions": 78, - "composure": 82, - "aggression": 58, - "teamwork": 78, - "leadership": 80, - "handling": 20, - "reflexes": 20, - "aerial": 55 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-giantx-lec", - "traits": [], - "contract_end": null, - "wage": 147000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 79, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105647947016264573", - "match_name": "Jackies", - "full_name": "Adam Jeřábek", - "date_of_birth": "2004-10-06", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 76, - "strength": 65, - "agility": 77, - "passing": 73, - "shooting": 81, - "tackling": 59, - "dribbling": 83, - "defending": 63, - "positioning": 66, - "vision": 76, - "decisions": 75, - "composure": 78, - "aggression": 57, - "teamwork": 82, - "leadership": 78, - "handling": 20, - "reflexes": 20, - "aerial": 54 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-giantx-lec", - "traits": [], - "contract_end": null, - "wage": 274000, - "market_value": 150000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105501717406803640", - "match_name": "Noah", - "full_name": "Hyeon-taek Oh", - "date_of_birth": "2001-10-04", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 79, - "strength": 69, - "agility": 80, - "passing": 70, - "shooting": 85, - "tackling": 51, - "dribbling": 85, - "defending": 48, - "positioning": 74, - "vision": 81, - "decisions": 80, - "composure": 83, - "aggression": 61, - "teamwork": 83, - "leadership": 77, - "handling": 20, - "reflexes": 20, - "aerial": 58 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-giantx-lec", - "traits": [], - "contract_end": null, - "wage": 200000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105501802535116331", - "match_name": "Jun", - "full_name": "Se-jun Yoon", - "date_of_birth": "2000-08-02", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 82, - "strength": 69, - "agility": 80, - "passing": 77, - "shooting": 86, - "tackling": 73, - "dribbling": 84, - "defending": 67, - "positioning": 70, - "vision": 84, - "decisions": 82, - "composure": 82, - "aggression": 61, - "teamwork": 83, - "leadership": 80, - "handling": 20, - "reflexes": 20, - "aerial": 58 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-giantx-lec", - "traits": [], - "contract_end": null, - "wage": 228000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-103495716771322725", - "match_name": "Canna", - "full_name": "Chang-dong Kim", - "date_of_birth": "2000-02-11", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 86, - "strength": 78, - "agility": 85, - "passing": 73, - "shooting": 88, - "tackling": 79, - "dribbling": 84, - "defending": 80, - "positioning": 73, - "vision": 88, - "decisions": 88, - "composure": 88, - "aggression": 64, - "teamwork": 86, - "leadership": 82, - "handling": 20, - "reflexes": 20, - "aerial": 74 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-karmine-corp", - "traits": [], - "contract_end": null, - "wage": 330000, - "market_value": 190000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105537190986692036", - "match_name": "Yike", - "full_name": "Martin Sundelin", - "date_of_birth": "2000-11-11", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 84, - "strength": 73, - "agility": 85, - "passing": 81, - "shooting": 86, - "tackling": 67, - "dribbling": 89, - "defending": 71, - "positioning": 74, - "vision": 83, - "decisions": 84, - "composure": 84, - "aggression": 65, - "teamwork": 87, - "leadership": 84, - "handling": 20, - "reflexes": 20, - "aerial": 62 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-karmine-corp", - "traits": [], - "contract_end": null, - "wage": 340000, - "market_value": 180000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-108205130709313212", - "match_name": "kyeahoo", - "full_name": "Yea-hoo Kang", - "date_of_birth": "2005-08-13", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 79, - "strength": 70, - "agility": 83, - "passing": 78, - "shooting": 82, - "tackling": 64, - "dribbling": 86, - "defending": 68, - "positioning": 71, - "vision": 82, - "decisions": 81, - "composure": 85, - "aggression": 62, - "teamwork": 84, - "leadership": 74, - "handling": 20, - "reflexes": 20, - "aerial": 59 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-karmine-corp", - "traits": [], - "contract_end": null, - "wage": 285000, - "market_value": 190000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 88, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-109461265532592848", - "match_name": "Caliste", - "full_name": "Caliste Henry-Hennebert", - "date_of_birth": "2006-08-28", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 77, - "stamina": 87, - "strength": 70, - "agility": 80, - "passing": 71, - "shooting": 87, - "tackling": 52, - "dribbling": 88, - "defending": 49, - "positioning": 75, - "vision": 82, - "decisions": 85, - "composure": 85, - "aggression": 62, - "teamwork": 85, - "leadership": 82, - "handling": 20, - "reflexes": 20, - "aerial": 59 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-karmine-corp", - "traits": [], - "contract_end": null, - "wage": 295000, - "market_value": 230000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 92, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-106625308523122120", - "match_name": "Busio", - "full_name": "Alan Cwalina", - "date_of_birth": "2003-10-22", - "nationality": "US", - "birth_country": "US", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 84, - "strength": 70, - "agility": 84, - "passing": 78, - "shooting": 89, - "tackling": 74, - "dribbling": 88, - "defending": 68, - "positioning": 71, - "vision": 84, - "decisions": 84, - "composure": 83, - "aggression": 62, - "teamwork": 85, - "leadership": 85, - "handling": 20, - "reflexes": 20, - "aerial": 59 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-karmine-corp", - "traits": [], - "contract_end": null, - "wage": 280000, - "market_value": 200000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 87, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-110350224593953686", - "match_name": "Myrwn", - "full_name": "Alex Pastor Villarejo", - "date_of_birth": "2003-06-13", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 85, - "strength": 73, - "agility": 90, - "passing": 68, - "shooting": 85, - "tackling": 74, - "dribbling": 86, - "defending": 75, - "positioning": 68, - "vision": 80, - "decisions": 75, - "composure": 78, - "aggression": 59, - "teamwork": 85, - "leadership": 75, - "handling": 20, - "reflexes": 20, - "aerial": 69 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-mad-lions", - "traits": [], - "contract_end": null, - "wage": 167000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-103877629120745120", - "match_name": "Elyoya", - "full_name": "Javier Prades Batalla", - "date_of_birth": "2000-03-13", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 87, - "strength": 71, - "agility": 84, - "passing": 79, - "shooting": 90, - "tackling": 65, - "dribbling": 87, - "defending": 69, - "positioning": 72, - "vision": 87, - "decisions": 85, - "composure": 88, - "aggression": 63, - "teamwork": 85, - "leadership": 90, - "handling": 20, - "reflexes": 20, - "aerial": 60 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-mad-lions", - "traits": [], - "contract_end": null, - "wage": 356000, - "market_value": 200000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 87, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105504920899018806", - "match_name": "Jojopyun", - "full_name": "Joseph Joon Pyun", - "date_of_birth": "2004-10-01", - "nationality": "CA", - "birth_country": "CA", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 85, - "strength": 70, - "agility": 82, - "passing": 78, - "shooting": 93, - "tackling": 64, - "dribbling": 91, - "defending": 68, - "positioning": 71, - "vision": 87, - "decisions": 82, - "composure": 80, - "aggression": 62, - "teamwork": 88, - "leadership": 86, - "handling": 20, - "reflexes": 20, - "aerial": 59 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-mad-lions", - "traits": [], - "contract_end": null, - "wage": 352000, - "market_value": 240000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 92, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-103536968833612789", - "match_name": "Supa", - "full_name": "David Martínez García", - "date_of_birth": "2000-10-23", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 81, - "strength": 69, - "agility": 80, - "passing": 70, - "shooting": 84, - "tackling": 51, - "dribbling": 86, - "defending": 48, - "positioning": 74, - "vision": 83, - "decisions": 82, - "composure": 82, - "aggression": 61, - "teamwork": 84, - "leadership": 77, - "handling": 20, - "reflexes": 20, - "aerial": 58 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-mad-lions", - "traits": [], - "contract_end": null, - "wage": 155000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107564404490889053", - "match_name": "Alvaro", - "full_name": "Álvaro Fernández del Amo", - "date_of_birth": "2003-07-15", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 83, - "strength": 68, - "agility": 80, - "passing": 76, - "shooting": 84, - "tackling": 72, - "dribbling": 85, - "defending": 66, - "positioning": 69, - "vision": 85, - "decisions": 80, - "composure": 84, - "aggression": 60, - "teamwork": 88, - "leadership": 84, - "handling": 20, - "reflexes": 20, - "aerial": 57 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-mad-lions", - "traits": [], - "contract_end": null, - "wage": 155000, - "market_value": 200000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 90, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105700869624784693", - "match_name": "Maynter", - "full_name": "Volodymyr Sorokin", - "date_of_birth": "2000-12-15", - "nationality": "UA", - "birth_country": "UA", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 78, - "strength": 72, - "agility": 75, - "passing": 67, - "shooting": 81, - "tackling": 73, - "dribbling": 76, - "defending": 74, - "positioning": 67, - "vision": 77, - "decisions": 82, - "composure": 82, - "aggression": 58, - "teamwork": 78, - "leadership": 76, - "handling": 20, - "reflexes": 20, - "aerial": 68 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-natus-vincere", - "traits": [], - "contract_end": null, - "wage": 140000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 85, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105548731617719496", - "match_name": "Rhilech", - "full_name": "Enes Uçan", - "date_of_birth": "2005-10-15", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 84, - "strength": 68, - "agility": 79, - "passing": 76, - "shooting": 81, - "tackling": 62, - "dribbling": 85, - "defending": 66, - "positioning": 69, - "vision": 80, - "decisions": 80, - "composure": 80, - "aggression": 60, - "teamwork": 84, - "leadership": 82, - "handling": 20, - "reflexes": 20, - "aerial": 57 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-natus-vincere", - "traits": [], - "contract_end": null, - "wage": 155000, - "market_value": 210000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 92, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107840393299826151", - "match_name": "Poby", - "full_name": "Sung-won Yun", - "date_of_birth": "2006-02-07", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 81, - "strength": 66, - "agility": 80, - "passing": 74, - "shooting": 81, - "tackling": 60, - "dribbling": 80, - "defending": 64, - "positioning": 67, - "vision": 82, - "decisions": 84, - "composure": 80, - "aggression": 58, - "teamwork": 80, - "leadership": 78, - "handling": 20, - "reflexes": 20, - "aerial": 55 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-natus-vincere", - "traits": [], - "contract_end": null, - "wage": 260000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-104287359934240404", - "match_name": "SamD", - "full_name": "Jae-hoon Lee", - "date_of_birth": "2001-03-14", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 78, - "strength": 69, - "agility": 80, - "passing": 70, - "shooting": 78, - "tackling": 51, - "dribbling": 81, - "defending": 48, - "positioning": 74, - "vision": 76, - "decisions": 80, - "composure": 81, - "aggression": 61, - "teamwork": 82, - "leadership": 78, - "handling": 20, - "reflexes": 20, - "aerial": 58 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-natus-vincere", - "traits": [], - "contract_end": null, - "wage": 118000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-103805069759346933", - "match_name": "Parus", - "full_name": "Polat Çiçek", - "date_of_birth": "2003-02-22", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 83, - "strength": 67, - "agility": 82, - "passing": 75, - "shooting": 84, - "tackling": 71, - "dribbling": 82, - "defending": 65, - "positioning": 68, - "vision": 85, - "decisions": 81, - "composure": 81, - "aggression": 59, - "teamwork": 82, - "leadership": 84, - "handling": 20, - "reflexes": 20, - "aerial": 56 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-natus-vincere", - "traits": [], - "contract_end": null, - "wage": 120000, - "market_value": 190000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 89, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107767810249714879", - "match_name": "Rooster", - "full_name": "Yun-hwan Shin", - "date_of_birth": "2005-04-28", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 77, - "strength": 73, - "agility": 72, - "passing": 68, - "shooting": 82, - "tackling": 74, - "dribbling": 80, - "defending": 75, - "positioning": 68, - "vision": 72, - "decisions": 75, - "composure": 78, - "aggression": 59, - "teamwork": 76, - "leadership": 68, - "handling": 20, - "reflexes": 20, - "aerial": 69 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-shifters", - "traits": [], - "contract_end": null, - "wage": 155000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105515296576479523", - "match_name": "Boukada", - "full_name": "Mehdi Lahlou", - "date_of_birth": "2002-10-01", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 69, - "strength": 62, - "agility": 68, - "passing": 70, - "shooting": 69, - "tackling": 56, - "dribbling": 72, - "defending": 60, - "positioning": 63, - "vision": 67, - "decisions": 71, - "composure": 70, - "aggression": 54, - "teamwork": 72, - "leadership": 70, - "handling": 20, - "reflexes": 20, - "aerial": 51 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-shifters", - "traits": [], - "contract_end": null, - "wage": 130000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105554437688383476", - "match_name": "nuc", - "full_name": "Ilias Bizriken", - "date_of_birth": "2002-10-17", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 80, - "strength": 66, - "agility": 80, - "passing": 74, - "shooting": 80, - "tackling": 60, - "dribbling": 82, - "defending": 64, - "positioning": 67, - "vision": 81, - "decisions": 80, - "composure": 78, - "aggression": 58, - "teamwork": 80, - "leadership": 80, - "handling": 20, - "reflexes": 20, - "aerial": 55 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-shifters", - "traits": [], - "contract_end": null, - "wage": 275000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107492114500277895", - "match_name": "Paduck", - "full_name": "Seok-hyeon Park", - "date_of_birth": "2005-02-12", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 75, - "strength": 67, - "agility": 77, - "passing": 68, - "shooting": 78, - "tackling": 49, - "dribbling": 80, - "defending": 46, - "positioning": 72, - "vision": 78, - "decisions": 79, - "composure": 78, - "aggression": 59, - "teamwork": 78, - "leadership": 68, - "handling": 20, - "reflexes": 20, - "aerial": 56 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-shifters", - "traits": [], - "contract_end": null, - "wage": 100000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-102181528883745160", - "match_name": "Trymbi", - "full_name": "Adrian Trybus", - "date_of_birth": "2000-10-20", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 75, - "strength": 64, - "agility": 78, - "passing": 72, - "shooting": 72, - "tackling": 68, - "dribbling": 72, - "defending": 62, - "positioning": 65, - "vision": 74, - "decisions": 75, - "composure": 73, - "aggression": 56, - "teamwork": 74, - "leadership": 77, - "handling": 20, - "reflexes": 20, - "aerial": 53 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-shifters", - "traits": [], - "contract_end": null, - "wage": 147000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-99322214618656216", - "match_name": "Wunder", - "full_name": "Martin Nordahl Hansen", - "date_of_birth": "1998-11-09", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 77, - "strength": 71, - "agility": 82, - "passing": 66, - "shooting": 76, - "tackling": 72, - "dribbling": 75, - "defending": 73, - "positioning": 66, - "vision": 76, - "decisions": 74, - "composure": 72, - "aggression": 57, - "teamwork": 77, - "leadership": 79, - "handling": 20, - "reflexes": 20, - "aerial": 67 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-sk-gaming", - "traits": [], - "contract_end": null, - "wage": 115000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-101389808348806587", - "match_name": "Skeanz", - "full_name": "Duncan Marquet", - "date_of_birth": "2000-09-25", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 75, - "strength": 65, - "agility": 76, - "passing": 73, - "shooting": 72, - "tackling": 59, - "dribbling": 74, - "defending": 63, - "positioning": 66, - "vision": 73, - "decisions": 76, - "composure": 75, - "aggression": 57, - "teamwork": 72, - "leadership": 75, - "handling": 20, - "reflexes": 20, - "aerial": 54 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-sk-gaming", - "traits": [], - "contract_end": null, - "wage": 104000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-103889902476986558", - "match_name": "LIDER", - "full_name": "Adam Ilyasov", - "date_of_birth": "1999-07-03", - "nationality": "NO", - "birth_country": "NO", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 72, - "strength": 61, - "agility": 68, - "passing": 69, - "shooting": 75, - "tackling": 55, - "dribbling": 76, - "defending": 59, - "positioning": 62, - "vision": 72, - "decisions": 69, - "composure": 70, - "aggression": 53, - "teamwork": 75, - "leadership": 74, - "handling": 20, - "reflexes": 20, - "aerial": 50 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-sk-gaming", - "traits": [], - "contract_end": null, - "wage": 136000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105553696718837337", - "match_name": "Jopa", - "full_name": "Josip Čančar", - "date_of_birth": "2003-11-03", - "nationality": "HR", - "birth_country": "HR", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 80, - "strength": 67, - "agility": 79, - "passing": 68, - "shooting": 80, - "tackling": 49, - "dribbling": 82, - "defending": 46, - "positioning": 72, - "vision": 76, - "decisions": 80, - "composure": 80, - "aggression": 59, - "teamwork": 82, - "leadership": 77, - "handling": 20, - "reflexes": 20, - "aerial": 56 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-sk-gaming", - "traits": [], - "contract_end": null, - "wage": 92000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-99322214629661297", - "match_name": "Mikyx", - "full_name": "Mihael Mehle", - "date_of_birth": "1998-11-02", - "nationality": "SI", - "birth_country": "SI", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 78, - "strength": 68, - "agility": 82, - "passing": 76, - "shooting": 79, - "tackling": 72, - "dribbling": 78, - "defending": 66, - "positioning": 69, - "vision": 81, - "decisions": 77, - "composure": 78, - "aggression": 60, - "teamwork": 78, - "leadership": 84, - "handling": 20, - "reflexes": 20, - "aerial": 57 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-sk-gaming", - "traits": [], - "contract_end": null, - "wage": 157000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 79, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107156544177574787", - "match_name": "Tracyn", - "full_name": "Sebastian Wojtoń", - "date_of_birth": "2005-09-16", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 80, - "strength": 72, - "agility": 72, - "passing": 67, - "shooting": 76, - "tackling": 73, - "dribbling": 80, - "defending": 74, - "positioning": 67, - "vision": 74, - "decisions": 76, - "composure": 80, - "aggression": 58, - "teamwork": 74, - "leadership": 77, - "handling": 20, - "reflexes": 20, - "aerial": 68 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-heretics-lec", - "traits": [], - "contract_end": null, - "wage": 98000, - "market_value": 150000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 84, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105830645287286396", - "match_name": "Sheo", - "full_name": "Théo Borile", - "date_of_birth": "2001-07-05", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 71, - "strength": 67, - "agility": 75, - "passing": 75, - "shooting": 75, - "tackling": 61, - "dribbling": 78, - "defending": 65, - "positioning": 68, - "vision": 80, - "decisions": 76, - "composure": 72, - "aggression": 59, - "teamwork": 77, - "leadership": 78, - "handling": 20, - "reflexes": 20, - "aerial": 56 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-heretics-lec", - "traits": [], - "contract_end": null, - "wage": 146000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-102174699705191142", - "match_name": "Serin", - "full_name": "Tolga Ölmez", - "date_of_birth": "2002-04-10", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 76, - "strength": 65, - "agility": 75, - "passing": 73, - "shooting": 80, - "tackling": 59, - "dribbling": 77, - "defending": 63, - "positioning": 66, - "vision": 75, - "decisions": 78, - "composure": 78, - "aggression": 57, - "teamwork": 76, - "leadership": 75, - "handling": 20, - "reflexes": 20, - "aerial": 54 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-heretics-lec", - "traits": [], - "contract_end": null, - "wage": 230000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105501834624360050", - "match_name": "Ice", - "full_name": "Sang-hoon Yoon", - "date_of_birth": "2001-04-09", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 80, - "strength": 65, - "agility": 78, - "passing": 66, - "shooting": 81, - "tackling": 47, - "dribbling": 84, - "defending": 44, - "positioning": 70, - "vision": 80, - "decisions": 82, - "composure": 80, - "aggression": 57, - "teamwork": 81, - "leadership": 72, - "handling": 20, - "reflexes": 20, - "aerial": 54 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-heretics-lec", - "traits": [], - "contract_end": null, - "wage": 135000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 79, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107492119089043087", - "match_name": "Way", - "full_name": "Gil Han", - "date_of_birth": "2002-06-29", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 75, - "strength": 65, - "agility": 78, - "passing": 73, - "shooting": 74, - "tackling": 69, - "dribbling": 77, - "defending": 63, - "positioning": 66, - "vision": 78, - "decisions": 78, - "composure": 79, - "aggression": 57, - "teamwork": 76, - "leadership": 68, - "handling": 20, - "reflexes": 20, - "aerial": 54 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-heretics-lec", - "traits": [], - "contract_end": null, - "wage": 98000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107605411481021064", - "match_name": "Naak Nako", - "full_name": "Kaan Okan", - "date_of_birth": "2005-03-24", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": null, - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 85, - "strength": 76, - "agility": 86, - "passing": 71, - "shooting": 88, - "tackling": 77, - "dribbling": 90, - "defending": 78, - "positioning": 71, - "vision": 85, - "decisions": 85, - "composure": 84, - "aggression": 62, - "teamwork": 86, - "leadership": 82, - "handling": 20, - "reflexes": 20, - "aerial": 72 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-vitality", - "traits": [], - "contract_end": null, - "wage": 213000, - "market_value": 240000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 92, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-105503548109547493", - "match_name": "Lyncas", - "full_name": "Linas Nauncikas", - "date_of_birth": "2003-12-10", - "nationality": "LT", - "birth_country": "LT", - "profile_image_url": null, - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 81, - "strength": 68, - "agility": 78, - "passing": 76, - "shooting": 82, - "tackling": 62, - "dribbling": 82, - "defending": 66, - "positioning": 69, - "vision": 82, - "decisions": 80, - "composure": 82, - "aggression": 60, - "teamwork": 83, - "leadership": 82, - "handling": 20, - "reflexes": 20, - "aerial": 57 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-vitality", - "traits": [], - "contract_end": null, - "wage": 143000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-100356590519370319", - "match_name": "Humanoid", - "full_name": "Marek Brázda", - "date_of_birth": "2000-03-14", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": null, - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 80, - "strength": 67, - "agility": 85, - "passing": 75, - "shooting": 86, - "tackling": 61, - "dribbling": 88, - "defending": 65, - "positioning": 68, - "vision": 85, - "decisions": 75, - "composure": 78, - "aggression": 59, - "teamwork": 86, - "leadership": 85, - "handling": 20, - "reflexes": 20, - "aerial": 56 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-vitality", - "traits": [], - "contract_end": null, - "wage": 354000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-102787200044335760", - "match_name": "Carzzy", - "full_name": "Matyáš Orság", - "date_of_birth": "2002-01-31", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": null, - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 79, - "strength": 69, - "agility": 81, - "passing": 70, - "shooting": 84, - "tackling": 51, - "dribbling": 83, - "defending": 48, - "positioning": 74, - "vision": 81, - "decisions": 76, - "composure": 77, - "aggression": 61, - "teamwork": 83, - "leadership": 80, - "handling": 20, - "reflexes": 20, - "aerial": 58 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-vitality", - "traits": [], - "contract_end": null, - "wage": 147000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-107605583684952312", - "match_name": "Fleshy", - "full_name": "Kadir Kemiksiz", - "date_of_birth": "2000-11-24", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 79, - "strength": 66, - "agility": 80, - "passing": 74, - "shooting": 82, - "tackling": 70, - "dribbling": 81, - "defending": 64, - "positioning": 67, - "vision": 78, - "decisions": 78, - "composure": 80, - "aggression": 58, - "teamwork": 80, - "leadership": 80, - "handling": 20, - "reflexes": 20, - "aerial": 55 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": "lec-team-vitality", - "traits": [], - "contract_end": null, - "wage": 82000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-fa-virtuosa", - "match_name": "Virtuosa", - "full_name": "Skylar Hew", - "date_of_birth": "2002-01-01", - "nationality": "US", - "birth_country": "US", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 68, - "strength": 58, - "agility": 71, - "passing": 71, - "shooting": 55, - "tackling": 67, - "dribbling": 69, - "defending": 66, - "positioning": 67, - "vision": 70, - "decisions": 69, - "composure": 68, - "aggression": 62, - "teamwork": 72, - "leadership": 70, - "handling": 20, - "reflexes": 20, - "aerial": 54 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": null, - "wage": 128000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 71, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-player-fa-trayton", - "match_name": "Trayton", - "full_name": "Jean Medzadourian", - "date_of_birth": "1998-09-26", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": null, - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 69, - "strength": 59, - "agility": 70, - "passing": 72, - "shooting": 56, - "tackling": 68, - "dribbling": 68, - "defending": 67, - "positioning": 68, - "vision": 71, - "decisions": 70, - "composure": 69, - "aggression": 63, - "teamwork": 73, - "leadership": 71, - "handling": 20, - "reflexes": 20, - "aerial": 55 - }, - "condition": 100, - "morale": 100, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": null, - "wage": 132000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-movistar-koi-f-nix-player-1", - "match_name": "NightSlayer", - "full_name": "Ivan Bilous", - "date_of_birth": "2008-01-18", - "nationality": "UA", - "birth_country": "UA", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/79/MKF_NightSlayer_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250726151518", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 72, - "strength": 69, - "agility": 67, - "passing": 67, - "shooting": 76, - "tackling": 69, - "dribbling": 78, - "defending": 73, - "positioning": 66, - "vision": 68, - "decisions": 70, - "composure": 75, - "aggression": 64, - "teamwork": 75, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-movistar-koi-f-nix", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 90, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-movistar-koi-f-nix-player-2", - "match_name": "Time", - "full_name": "Tiago Almeida", - "date_of_birth": "2002-12-06", - "nationality": "PT", - "birth_country": "PT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/1/1a/MKF_Time_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250726151516", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 64, - "strength": 62, - "agility": 63, - "passing": 64, - "shooting": 70, - "tackling": 62, - "dribbling": 78, - "defending": 62, - "positioning": 65, - "vision": 69, - "decisions": 62, - "composure": 68, - "aggression": 59, - "teamwork": 68, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-movistar-koi-f-nix", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-movistar-koi-f-nix-player-3", - "match_name": "Fresskowy", - "full_name": "Bartłomiej Przewoźnik", - "date_of_birth": "1999-11-26", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6b/MKFX_Fresskowy_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124051", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 62, - "strength": 65, - "agility": 68, - "passing": 62, - "shooting": 74, - "tackling": 65, - "dribbling": 73, - "defending": 65, - "positioning": 63, - "vision": 70, - "decisions": 70, - "composure": 68, - "aggression": 59, - "teamwork": 75, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-movistar-koi-f-nix", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-movistar-koi-f-nix-player-4", - "match_name": "13", - "full_name": "Zayan Taeau", - "date_of_birth": "2006-09-09", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/51/MKF_13_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250726151515", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 67, - "strength": 67, - "agility": 66, - "passing": 63, - "shooting": 66, - "tackling": 67, - "dribbling": 70, - "defending": 67, - "positioning": 65, - "vision": 64, - "decisions": 66, - "composure": 69, - "aggression": 62, - "teamwork": 68, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-movistar-koi-f-nix", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-movistar-koi-f-nix-player-5", - "match_name": "Myrtus", - "full_name": "Mohamed Rahli", - "date_of_birth": "2005-10-11", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/cb/BDSA_Myrtus_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250529162538", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 69, - "strength": 67, - "agility": 69, - "passing": 69, - "shooting": 68, - "tackling": 67, - "dribbling": 67, - "defending": 71, - "positioning": 68, - "vision": 67, - "decisions": 66, - "composure": 67, - "aggression": 64, - "teamwork": 65, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-movistar-koi-f-nix", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-team-heretics-player-1", - "match_name": "Papiteero", - "full_name": "Antero Trindade Baldaia", - "date_of_birth": "2003-09-20", - "nationality": "PT", - "birth_country": "PT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fa/BDSA_Papiteero_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250529162541", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 68, - "strength": 65, - "agility": 66, - "passing": 63, - "shooting": 64, - "tackling": 65, - "dribbling": 65, - "defending": 69, - "positioning": 62, - "vision": 64, - "decisions": 67, - "composure": 69, - "aggression": 60, - "teamwork": 65, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-team-heretics", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 69, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-team-heretics-player-2", - "match_name": "Daglas", - "full_name": "Kacper Dagiel", - "date_of_birth": "2005-10-23", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/4/43/TH_Daglas_2026_Split_2.png/revision/latest/scale-to-width-down/220?cb=20260426085145", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 75, - "strength": 67, - "agility": 73, - "passing": 64, - "shooting": 71, - "tackling": 67, - "dribbling": 75, - "defending": 67, - "positioning": 65, - "vision": 70, - "decisions": 73, - "composure": 78, - "aggression": 61, - "teamwork": 73, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-team-heretics", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-team-heretics-player-3", - "match_name": "Mercy9", - "full_name": "Cengizhan Teker", - "date_of_birth": "2005-06-05", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/de/MISA_Mercy9_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240618160643", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 70, - "strength": 65, - "agility": 66, - "passing": 67, - "shooting": 73, - "tackling": 65, - "dribbling": 72, - "defending": 65, - "positioning": 68, - "vision": 67, - "decisions": 68, - "composure": 69, - "aggression": 62, - "teamwork": 70, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-team-heretics", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-team-heretics-player-4", - "match_name": "Lure", - "full_name": "Shin Jae-yoon", - "date_of_birth": "2003-05-16", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/63/HLE.C_Lure_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240618143648", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 68, - "strength": 62, - "agility": 61, - "passing": 58, - "shooting": 67, - "tackling": 62, - "dribbling": 69, - "defending": 62, - "positioning": 60, - "vision": 66, - "decisions": 65, - "composure": 66, - "aggression": 57, - "teamwork": 68, - "leadership": 60, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-team-heretics", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-team-heretics-player-5", - "match_name": "Batuuu", - "full_name": "Batu Kaygusuz", - "date_of_birth": "2005-07-27", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/8a/BGT_Batuuu_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240618155404", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 67, - "strength": 64, - "agility": 67, - "passing": 66, - "shooting": 69, - "tackling": 64, - "dribbling": 65, - "defending": 68, - "positioning": 65, - "vision": 70, - "decisions": 66, - "composure": 68, - "aggression": 61, - "teamwork": 67, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-team-heretics", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-barcelona-esports-player-1", - "match_name": "selenex", - "full_name": "Eric Lozano Gutierrez", - "date_of_birth": "2006-07-21", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/31/XOL_Selenex_2024_Split_1.png/revision/latest/scale-to-width-down/220?cb=20240202212308", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 68, - "strength": 62, - "agility": 64, - "passing": 63, - "shooting": 63, - "tackling": 62, - "dribbling": 64, - "defending": 66, - "positioning": 64, - "vision": 63, - "decisions": 65, - "composure": 67, - "aggression": 59, - "teamwork": 63, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-barcelona-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-barcelona-esports-player-2", - "match_name": "Koldo", - "full_name": "Luis Perez García", - "date_of_birth": "2000-11-07", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/7f/UCAM_Koldo_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124112", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 64, - "strength": 69, - "agility": 72, - "passing": 71, - "shooting": 69, - "tackling": 69, - "dribbling": 67, - "defending": 69, - "positioning": 70, - "vision": 70, - "decisions": 69, - "composure": 67, - "aggression": 66, - "teamwork": 66, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-barcelona-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-barcelona-esports-player-3", - "match_name": "Macaquinho", - "full_name": "Sergio Bouzende Rodrigues", - "date_of_birth": "2003-07-30", - "nationality": "PT", - "birth_country": "PT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c9/BAR_Macaquino_2025_Iberian_Cup.jpg/revision/latest/scale-to-width-down/220?cb=20260306155142", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 63, - "strength": 68, - "agility": 72, - "passing": 70, - "shooting": 65, - "tackling": 68, - "dribbling": 67, - "defending": 68, - "positioning": 69, - "vision": 64, - "decisions": 67, - "composure": 64, - "aggression": 65, - "teamwork": 68, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-barcelona-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-barcelona-esports-player-4", - "match_name": "Legolas", - "full_name": "Sergio Vicente Gispert", - "date_of_birth": "2000-12-20", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/33/BAR_Legolas_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250905145943", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 70, - "strength": 65, - "agility": 66, - "passing": 66, - "shooting": 71, - "tackling": 65, - "dribbling": 73, - "defending": 65, - "positioning": 65, - "vision": 68, - "decisions": 70, - "composure": 64, - "aggression": 63, - "teamwork": 70, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-barcelona-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-barcelona-esports-player-5", - "match_name": "Oscure", - "full_name": "Víctor Guzmán Fernández", - "date_of_birth": "2000-04-30", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/9c/BAR_Oscure_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240816123844", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 60, - "stamina": 62, - "strength": 60, - "agility": 62, - "passing": 62, - "shooting": 72, - "tackling": 60, - "dribbling": 69, - "defending": 64, - "positioning": 61, - "vision": 70, - "decisions": 68, - "composure": 66, - "aggression": 57, - "teamwork": 70, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-barcelona-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-giantx-itero-player-1", - "match_name": "ManoloGap", - "full_name": "Manuel García Azcúnaga", - "date_of_birth": "2002-06-09", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/79/ESDH_ManoloGap_2022_Split_1.png/revision/latest/scale-to-width-down/220?cb=20220125234841", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 67, - "strength": 64, - "agility": 61, - "passing": 65, - "shooting": 61, - "tackling": 64, - "dribbling": 65, - "defending": 68, - "positioning": 64, - "vision": 65, - "decisions": 63, - "composure": 64, - "aggression": 61, - "teamwork": 64, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-giantx-itero", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-giantx-itero-player-2", - "match_name": "Th3Antonio", - "full_name": "Antonio Espinosa Bejarano", - "date_of_birth": "1999-04-12", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/74/GX_Th3Antonio_2025.png/revision/latest/scale-to-width-down/220?cb=20251024172601", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 57, - "strength": 67, - "agility": 70, - "passing": 69, - "shooting": 62, - "tackling": 67, - "dribbling": 65, - "defending": 67, - "positioning": 70, - "vision": 65, - "decisions": 60, - "composure": 58, - "aggression": 64, - "teamwork": 64, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-giantx-itero", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 63, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-giantx-itero-player-3", - "match_name": "Miniduke", - "full_name": "Ismael Martínez Cortés", - "date_of_birth": "1997-11-03", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/0a/VVV_Miniduke_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124117", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 58, - "strength": 69, - "agility": 68, - "passing": 69, - "shooting": 60, - "tackling": 69, - "dribbling": 62, - "defending": 69, - "positioning": 67, - "vision": 65, - "decisions": 64, - "composure": 57, - "aggression": 63, - "teamwork": 63, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-giantx-itero", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 63, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-giantx-itero-player-4", - "match_name": "Flakked", - "full_name": "Víctor Lirola Tortosa", - "date_of_birth": "2001-04-25", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/30/TH_Flakked_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250810162235", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 78, - "strength": 60, - "agility": 80, - "passing": 61, - "shooting": 83, - "tackling": 60, - "dribbling": 81, - "defending": 60, - "positioning": 60, - "vision": 80, - "decisions": 82, - "composure": 77, - "aggression": 58, - "teamwork": 80, - "leadership": 78, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-giantx-itero", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-giantx-itero-player-5", - "match_name": "Attila", - "full_name": "Amadeu Jesus Dias de Carvalho", - "date_of_birth": "1996-02-26", - "nationality": "PT", - "birth_country": "PT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/d6/ZTA_Attila_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240816130642", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 69, - "strength": 72, - "agility": 69, - "passing": 72, - "shooting": 67, - "tackling": 72, - "dribbling": 68, - "defending": 76, - "positioning": 70, - "vision": 70, - "decisions": 68, - "composure": 67, - "aggression": 66, - "teamwork": 65, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-giantx-itero", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ucam-esports-player-1", - "match_name": "Kozi", - "full_name": "Jarosław Marchewka", - "date_of_birth": "2005-04-06", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/97/RBLS_Kozi_2024_Split_3.png/revision/latest/scale-to-width-down/220?cb=20241117111216", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 68, - "strength": 71, - "agility": 68, - "passing": 67, - "shooting": 69, - "tackling": 71, - "dribbling": 67, - "defending": 75, - "positioning": 68, - "vision": 66, - "decisions": 68, - "composure": 70, - "aggression": 66, - "teamwork": 67, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ucam-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ucam-esports-player-2", - "match_name": "bluerzor", - "full_name": "Dániel Subicz", - "date_of_birth": "1999-05-04", - "nationality": "HU", - "birth_country": "HU", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/89/UCAM_bluerzor_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250905150006", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 68, - "strength": 72, - "agility": 70, - "passing": 69, - "shooting": 68, - "tackling": 72, - "dribbling": 67, - "defending": 72, - "positioning": 70, - "vision": 70, - "decisions": 67, - "composure": 68, - "aggression": 66, - "teamwork": 68, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ucam-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ucam-esports-player-3", - "match_name": "ESCIK", - "full_name": "Tomasz Maciej Skwarczyński", - "date_of_birth": "2002-04-11", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/57/UCAM_ESCIK_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124107", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 62, - "strength": 65, - "agility": 68, - "passing": 67, - "shooting": 64, - "tackling": 65, - "dribbling": 65, - "defending": 65, - "positioning": 66, - "vision": 63, - "decisions": 66, - "composure": 67, - "aggression": 62, - "teamwork": 66, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ucam-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ucam-esports-player-4", - "match_name": "ANDARIEL", - "full_name": "Mert Kılıç", - "date_of_birth": "2003-11-14", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6b/UCAM_ANDARIEL_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124104", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 67, - "strength": 64, - "agility": 70, - "passing": 65, - "shooting": 70, - "tackling": 64, - "dribbling": 72, - "defending": 64, - "positioning": 64, - "vision": 66, - "decisions": 68, - "composure": 68, - "aggression": 62, - "teamwork": 68, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ucam-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ucam-esports-player-5", - "match_name": "iLEVI", - "full_name": "Besmir Jakupi", - "date_of_birth": "1998-05-16", - "nationality": "AL", - "birth_country": "AL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/9c/UCAM_iLevi_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124110", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 61, - "agility": 63, - "passing": 63, - "shooting": 64, - "tackling": 61, - "dribbling": 64, - "defending": 65, - "positioning": 62, - "vision": 65, - "decisions": 66, - "composure": 63, - "aggression": 58, - "teamwork": 63, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ucam-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 64, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-falke-esports-player-1", - "match_name": "Ethe", - "full_name": "Raúl Campos Vico", - "date_of_birth": "2001-08-07", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/d2/ZTA_Ethe_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124127", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 64, - "strength": 62, - "agility": 64, - "passing": 63, - "shooting": 62, - "tackling": 62, - "dribbling": 61, - "defending": 66, - "positioning": 62, - "vision": 60, - "decisions": 63, - "composure": 64, - "aggression": 59, - "teamwork": 62, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-falke-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 66, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-falke-esports-player-2", - "match_name": "Clicker", - "full_name": "Alejandro Botella Santos", - "date_of_birth": "2005-05-25", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 62, - "strength": 68, - "agility": 66, - "passing": 70, - "shooting": 64, - "tackling": 68, - "dribbling": 65, - "defending": 68, - "positioning": 69, - "vision": 62, - "decisions": 63, - "composure": 61, - "aggression": 65, - "teamwork": 64, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-falke-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 64, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-falke-esports-player-3", - "match_name": "Midnight", - "full_name": "Víctor Caro Rodríguez", - "date_of_birth": "2004-05-01", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/73/AYM_Midnight_2023_Split_1.png/revision/latest/scale-to-width-down/220?cb=20230227203829", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 63, - "strength": 61, - "agility": 65, - "passing": 63, - "shooting": 67, - "tackling": 61, - "dribbling": 66, - "defending": 61, - "positioning": 62, - "vision": 64, - "decisions": 66, - "composure": 61, - "aggression": 58, - "teamwork": 66, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-falke-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-falke-esports-player-4", - "match_name": "Marcv1", - "full_name": "Marc Villalba de la Arada", - "date_of_birth": "2004-09-11", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c8/RBT_Marcv1_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240816130603", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 65, - "strength": 66, - "agility": 70, - "passing": 67, - "shooting": 63, - "tackling": 66, - "dribbling": 65, - "defending": 66, - "positioning": 69, - "vision": 62, - "decisions": 62, - "composure": 64, - "aggression": 64, - "teamwork": 64, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-falke-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 65, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-falke-esports-player-5", - "match_name": "Deleted", - "full_name": "Unai San Juan Fajardo", - "date_of_birth": "2005-10-02", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 60, - "strength": 63, - "agility": 65, - "passing": 65, - "shooting": 62, - "tackling": 63, - "dribbling": 61, - "defending": 67, - "positioning": 64, - "vision": 62, - "decisions": 60, - "composure": 61, - "aggression": 60, - "teamwork": 60, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-falke-esports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 64, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-lua-gaming-player-1", - "match_name": "Dani", - "full_name": "Daniel Gómez Martínez", - "date_of_birth": "2004-02-03", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 66, - "strength": 63, - "agility": 65, - "passing": 64, - "shooting": 67, - "tackling": 63, - "dribbling": 65, - "defending": 67, - "positioning": 63, - "vision": 64, - "decisions": 66, - "composure": 67, - "aggression": 60, - "teamwork": 66, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-lua-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-lua-gaming-player-2", - "match_name": "Pegaso", - "full_name": "Edison Rivera Menéndez", - "date_of_birth": "2004-12-15", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 65, - "strength": 70, - "agility": 68, - "passing": 70, - "shooting": 61, - "tackling": 70, - "dribbling": 63, - "defending": 70, - "positioning": 68, - "vision": 64, - "decisions": 63, - "composure": 66, - "aggression": 64, - "teamwork": 62, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-lua-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-lua-gaming-player-3", - "match_name": "Hydra", - "full_name": "Raúl Moreno Valero", - "date_of_birth": "2006-12-15", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/9e/LUA_Hydra_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250905145951", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 69, - "strength": 62, - "agility": 68, - "passing": 64, - "shooting": 70, - "tackling": 62, - "dribbling": 70, - "defending": 62, - "positioning": 65, - "vision": 69, - "decisions": 66, - "composure": 68, - "aggression": 59, - "teamwork": 67, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-lua-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-lua-gaming-player-4", - "match_name": "Kaii", - "full_name": "Jorge Saiz Hoyos", - "date_of_birth": "2004-07-08", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 64, - "strength": 63, - "agility": 62, - "passing": 62, - "shooting": 65, - "tackling": 63, - "dribbling": 66, - "defending": 63, - "positioning": 61, - "vision": 63, - "decisions": 64, - "composure": 63, - "aggression": 58, - "teamwork": 63, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-lua-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-lua-gaming-player-5", - "match_name": "TIMR", - "full_name": "Tomáš Buštík", - "date_of_birth": "2006-07-11", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 64, - "strength": 66, - "agility": 63, - "passing": 66, - "shooting": 63, - "tackling": 66, - "dribbling": 64, - "defending": 70, - "positioning": 64, - "vision": 65, - "decisions": 62, - "composure": 65, - "aggression": 60, - "teamwork": 64, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-lua-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ub-alma-mater-player-1", - "match_name": "Pasameelcelo", - "full_name": "Jordi Franco Carreras", - "date_of_birth": "2007-11-28", - "nationality": "AD", - "birth_country": "AD", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 55, - "strength": 62, - "agility": 59, - "passing": 60, - "shooting": 62, - "tackling": 62, - "dribbling": 62, - "defending": 66, - "positioning": 59, - "vision": 57, - "decisions": 59, - "composure": 57, - "aggression": 57, - "teamwork": 60, - "leadership": 57, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ub-alma-mater", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 64, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ub-alma-mater-player-2", - "match_name": "Ivama", - "full_name": "Ivan Torn Cubero", - "date_of_birth": "2004-02-23", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 60, - "stamina": 58, - "strength": 59, - "agility": 62, - "passing": 61, - "shooting": 62, - "tackling": 59, - "dribbling": 61, - "defending": 59, - "positioning": 62, - "vision": 58, - "decisions": 60, - "composure": 60, - "aggression": 56, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ub-alma-mater", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 67, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ub-alma-mater-player-3", - "match_name": "Pauporter", - "full_name": "Pau Vintró Nogué", - "date_of_birth": "2004-09-22", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/7b/BAR_Pauporter_2025_Split_1.jpg/revision/latest/scale-to-width-down/220?cb=20250309113408", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 61, - "strength": 64, - "agility": 63, - "passing": 64, - "shooting": 64, - "tackling": 64, - "dribbling": 67, - "defending": 64, - "positioning": 62, - "vision": 62, - "decisions": 63, - "composure": 64, - "aggression": 58, - "teamwork": 64, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ub-alma-mater", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 69, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ub-alma-mater-player-4", - "match_name": "adrianlaneitor", - "full_name": "Adrián Tejero Gomez", - "date_of_birth": "2005-08-28", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 58, - "strength": 67, - "agility": 66, - "passing": 63, - "shooting": 58, - "tackling": 67, - "dribbling": 57, - "defending": 67, - "positioning": 65, - "vision": 57, - "decisions": 59, - "composure": 56, - "aggression": 62, - "teamwork": 60, - "leadership": 57, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ub-alma-mater", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 63, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-liga-espanola-ub-alma-mater-player-5", - "match_name": "Kellie", - "full_name": "Joel Rodríguez Pérez", - "date_of_birth": "2006-04-19", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 57, - "strength": 72, - "agility": 69, - "passing": 69, - "shooting": 60, - "tackling": 72, - "dribbling": 59, - "defending": 76, - "positioning": 70, - "vision": 58, - "decisions": 60, - "composure": 60, - "aggression": 66, - "teamwork": 58, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-liga-espanola-ub-alma-mater", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 63, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-solary-player-1", - "match_name": "Kryze", - "full_name": "Felix Hellström", - "date_of_birth": "1999-07-01", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c0/SLY_Kryze_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530151746", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 64, - "strength": 66, - "agility": 63, - "passing": 62, - "shooting": 63, - "tackling": 66, - "dribbling": 62, - "defending": 70, - "positioning": 63, - "vision": 62, - "decisions": 65, - "composure": 66, - "aggression": 61, - "teamwork": 66, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-solary", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-solary-player-2", - "match_name": "Zicssi", - "full_name": "Lanzo Ciajolo", - "date_of_birth": "2002-05-16", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/77/M8_Zicssi_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530150843", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 60, - "agility": 63, - "passing": 62, - "shooting": 62, - "tackling": 60, - "dribbling": 60, - "defending": 60, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-solary", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-solary-player-3", - "match_name": "Jool", - "full_name": "Kang Dong-su", - "date_of_birth": "2001-12-30", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/09/LOUD_Jool_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250726184942", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 62, - "strength": 60, - "agility": 64, - "passing": 62, - "shooting": 65, - "tackling": 60, - "dribbling": 63, - "defending": 60, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-solary", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 89, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-solary-player-4", - "match_name": "Aetinoth", - "full_name": "Berat Tıknazoğlu", - "date_of_birth": "2005-10-10", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/dc/GXP_Aetinoth_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124021", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 69, - "strength": 71, - "agility": 70, - "passing": 67, - "shooting": 71, - "tackling": 71, - "dribbling": 69, - "defending": 71, - "positioning": 69, - "vision": 68, - "decisions": 70, - "composure": 71, - "aggression": 66, - "teamwork": 72, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-solary", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-solary-player-5", - "match_name": "Piero", - "full_name": "Kim Jung-hun", - "date_of_birth": "2002-07-15", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/83/KCB_Piero_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530162215", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 65, - "strength": 63, - "agility": 60, - "passing": 65, - "shooting": 60, - "tackling": 63, - "dribbling": 62, - "defending": 67, - "positioning": 64, - "vision": 66, - "decisions": 62, - "composure": 63, - "aggression": 60, - "teamwork": 63, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-solary", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-galions-player-1", - "match_name": "Carlsen", - "full_name": "Carl Ulsted Carlsen", - "date_of_birth": "2005-12-15", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c5/TH_Carlsen_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250810162230", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 68, - "strength": 70, - "agility": 67, - "passing": 68, - "shooting": 67, - "tackling": 70, - "dribbling": 71, - "defending": 74, - "positioning": 67, - "vision": 66, - "decisions": 69, - "composure": 70, - "aggression": 65, - "teamwork": 70, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-galions", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-galions-player-2", - "match_name": "Thayger", - "full_name": "Francisco Mazo Sánchez", - "date_of_birth": "2002-01-27", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/50/NAVI_Thayger_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250810162203", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 70, - "strength": 68, - "agility": 71, - "passing": 70, - "shooting": 70, - "tackling": 68, - "dribbling": 68, - "defending": 68, - "positioning": 71, - "vision": 71, - "decisions": 72, - "composure": 68, - "aggression": 65, - "teamwork": 68, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-galions", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 81, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-galions-player-3", - "match_name": "Omon", - "full_name": "Šimon Řiháček", - "date_of_birth": "2003-07-02", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/d8/BKR_OMON_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250529163055", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 66, - "strength": 64, - "agility": 68, - "passing": 66, - "shooting": 69, - "tackling": 64, - "dribbling": 67, - "defending": 64, - "positioning": 67, - "vision": 67, - "decisions": 68, - "composure": 64, - "aggression": 61, - "teamwork": 64, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-galions", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-galions-player-4", - "match_name": "HARPOON", - "full_name": "Franciszek Gryszkiewicz", - "date_of_birth": "2005-04-18", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/ce/Z10_HARPOON_2024_Split_1.png/revision/latest/scale-to-width-down/220?cb=20240116100742", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 66, - "strength": 68, - "agility": 67, - "passing": 67, - "shooting": 68, - "tackling": 68, - "dribbling": 71, - "defending": 68, - "positioning": 66, - "vision": 65, - "decisions": 67, - "composure": 68, - "aggression": 63, - "teamwork": 69, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-galions", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-galions-player-5", - "match_name": "Zoelys", - "full_name": "Théo Le Scornec", - "date_of_birth": "2003-05-16", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/9a/GL_Zoelys_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530150830", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 66, - "strength": 64, - "agility": 61, - "passing": 66, - "shooting": 61, - "tackling": 64, - "dribbling": 63, - "defending": 68, - "positioning": 65, - "vision": 67, - "decisions": 63, - "composure": 64, - "aggression": 61, - "teamwork": 64, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-galions", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-french-flair-player-1", - "match_name": "Adam", - "full_name": "Adam Maanane", - "date_of_birth": "2001-12-30", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/4/47/NAVI_Adam_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250810162159", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 60, - "strength": 70, - "agility": 64, - "passing": 71, - "shooting": 80, - "tackling": 70, - "dribbling": 80, - "defending": 74, - "positioning": 70, - "vision": 76, - "decisions": 74, - "composure": 68, - "aggression": 67, - "teamwork": 79, - "leadership": 77, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-french-flair", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-french-flair-player-2", - "match_name": "NattyNatt", - "full_name": "Isak Elgh", - "date_of_birth": "2005-06-25", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/79/RS_NattyNatt_2025_Split_2_2.png/revision/latest/scale-to-width-down/220?cb=20250529163650", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 65, - "strength": 71, - "agility": 68, - "passing": 71, - "shooting": 71, - "tackling": 71, - "dribbling": 70, - "defending": 71, - "positioning": 69, - "vision": 66, - "decisions": 64, - "composure": 64, - "aggression": 65, - "teamwork": 68, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-french-flair", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-french-flair-player-3", - "match_name": "SAKEN", - "full_name": "Lucas Fayard", - "date_of_birth": "1998-11-05", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/79/KC_SAKEN_2024_Split_1.png/revision/latest/scale-to-width-down/220?cb=20240112205145", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 67, - "strength": 63, - "agility": 68, - "passing": 60, - "shooting": 68, - "tackling": 63, - "dribbling": 67, - "defending": 63, - "positioning": 61, - "vision": 68, - "decisions": 69, - "composure": 68, - "aggression": 57, - "teamwork": 69, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-french-flair", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-french-flair-player-4", - "match_name": "3XA", - "full_name": "Thomas Foucou", - "date_of_birth": "2003-09-28", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c2/KCB_3XA_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530151643", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 70, - "strength": 61, - "agility": 70, - "passing": 62, - "shooting": 78, - "tackling": 61, - "dribbling": 80, - "defending": 61, - "positioning": 61, - "vision": 74, - "decisions": 70, - "composure": 72, - "aggression": 59, - "teamwork": 77, - "leadership": 76, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-french-flair", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-french-flair-player-5", - "match_name": "Targamas", - "full_name": "Raphaël Crabbé", - "date_of_birth": "2000-06-30", - "nationality": "BE", - "birth_country": "BE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/8a/KC_Targamas_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250810162227", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 75, - "strength": 70, - "agility": 72, - "passing": 72, - "shooting": 79, - "tackling": 70, - "dribbling": 78, - "defending": 74, - "positioning": 71, - "vision": 78, - "decisions": 73, - "composure": 75, - "aggression": 67, - "teamwork": 78, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-french-flair", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-joblife-player-1", - "match_name": "Vertigo", - "full_name": "Maximilian Rassi", - "date_of_birth": "2003-02-27", - "nationality": "AT", - "birth_country": "AT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fa/VITB_Vertigo_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530144355", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 69, - "strength": 66, - "agility": 63, - "passing": 67, - "shooting": 63, - "tackling": 66, - "dribbling": 67, - "defending": 70, - "positioning": 66, - "vision": 67, - "decisions": 65, - "composure": 66, - "aggression": 63, - "teamwork": 66, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-joblife", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-joblife-player-2", - "match_name": "Shift", - "full_name": "Marcel Bąk", - "date_of_birth": "2005-01-20", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 63, - "strength": 61, - "agility": 64, - "passing": 63, - "shooting": 63, - "tackling": 61, - "dribbling": 60, - "defending": 61, - "positioning": 62, - "vision": 64, - "decisions": 60, - "composure": 61, - "aggression": 58, - "teamwork": 61, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-joblife", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-joblife-player-3", - "match_name": "Czekolad", - "full_name": "Paweł Szczepanik", - "date_of_birth": "2000-02-15", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6f/BAR_Czekolad_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250905145939", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 59, - "strength": 62, - "agility": 61, - "passing": 59, - "shooting": 62, - "tackling": 62, - "dribbling": 60, - "defending": 62, - "positioning": 60, - "vision": 60, - "decisions": 61, - "composure": 62, - "aggression": 56, - "teamwork": 62, - "leadership": 59, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-joblife", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 85, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-joblife-player-4", - "match_name": "Comp", - "full_name": "Markos Stamkopoulos", - "date_of_birth": "2001-12-20", - "nationality": "GR", - "birth_country": "GR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/a4/M8_Comp_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530150856", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 62, - "strength": 59, - "agility": 63, - "passing": 60, - "shooting": 64, - "tackling": 59, - "dribbling": 62, - "defending": 59, - "positioning": 62, - "vision": 61, - "decisions": 63, - "composure": 59, - "aggression": 57, - "teamwork": 60, - "leadership": 60, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-joblife", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-joblife-player-5", - "match_name": "Mersa", - "full_name": "Mertai Sari", - "date_of_birth": "2002-08-22", - "nationality": "GR", - "birth_country": "GR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/00/SLY_Mersa_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530151741", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 60, - "agility": 62, - "passing": 62, - "shooting": 62, - "tackling": 60, - "dribbling": 60, - "defending": 64, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-joblife", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-tln-pirates-player-1", - "match_name": "Spooder", - "full_name": "Muhanad Maitham Sharad", - "date_of_birth": "2002-09-05", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fe/MKFX_Spooder_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124057", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 65, - "strength": 67, - "agility": 64, - "passing": 65, - "shooting": 64, - "tackling": 67, - "dribbling": 68, - "defending": 71, - "positioning": 64, - "vision": 63, - "decisions": 66, - "composure": 67, - "aggression": 62, - "teamwork": 67, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-tln-pirates", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-tln-pirates-player-2", - "match_name": "Stefan", - "full_name": "Stefan Nikolić", - "date_of_birth": "2007-06-16", - "nationality": "RS", - "birth_country": "RS", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/ce/DSY_Stefan_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250827204410", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 60, - "agility": 63, - "passing": 62, - "shooting": 62, - "tackling": 60, - "dribbling": 60, - "defending": 60, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-tln-pirates", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-tln-pirates-player-3", - "match_name": "Toffer", - "full_name": "Tautvydas Gegeckas", - "date_of_birth": "2005-05-02", - "nationality": "LT", - "birth_country": "LT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fa/BDSA_Toffe_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250529162546", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 65, - "strength": 63, - "agility": 67, - "passing": 65, - "shooting": 68, - "tackling": 63, - "dribbling": 66, - "defending": 63, - "positioning": 66, - "vision": 66, - "decisions": 67, - "composure": 63, - "aggression": 60, - "teamwork": 63, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-tln-pirates", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-tln-pirates-player-4", - "match_name": "Axelent", - "full_name": "Nikola Petrusev", - "date_of_birth": "2004-05-14", - "nationality": "MK", - "birth_country": "MK", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6d/MHSC_Axelent_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240521135749", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 67, - "strength": 64, - "agility": 63, - "passing": 65, - "shooting": 64, - "tackling": 64, - "dribbling": 67, - "defending": 64, - "positioning": 64, - "vision": 66, - "decisions": 63, - "composure": 64, - "aggression": 62, - "teamwork": 65, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-tln-pirates", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-tln-pirates-player-5", - "match_name": "Thomas", - "full_name": "Tomislav Nanjara", - "date_of_birth": "2003-06-20", - "nationality": "HR", - "birth_country": "HR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/dc/MKF_Thomas_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250726151513", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 70, - "strength": 68, - "agility": 70, - "passing": 70, - "shooting": 70, - "tackling": 68, - "dribbling": 67, - "defending": 72, - "positioning": 69, - "vision": 71, - "decisions": 67, - "composure": 68, - "aggression": 65, - "teamwork": 68, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-tln-pirates", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-skillcamp-player-1", - "match_name": "Yeti", - "full_name": "Szymon Wójcicki", - "date_of_birth": "2007-03-13", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 69, - "strength": 66, - "agility": 63, - "passing": 67, - "shooting": 63, - "tackling": 66, - "dribbling": 67, - "defending": 70, - "positioning": 66, - "vision": 67, - "decisions": 65, - "composure": 66, - "aggression": 63, - "teamwork": 66, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-skillcamp", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 85, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-skillcamp-player-2", - "match_name": "Spooky", - "full_name": "Miroslav Gochev", - "date_of_birth": "1999-08-12", - "nationality": "EU", - "birth_country": "EU", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/09/ANO_SPOOKY_2023_SPLIT_1.png/revision/latest/scale-to-width-down/220?cb=20230414163049", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 72, - "strength": 70, - "agility": 73, - "passing": 72, - "shooting": 72, - "tackling": 70, - "dribbling": 69, - "defending": 70, - "positioning": 71, - "vision": 73, - "decisions": 69, - "composure": 70, - "aggression": 67, - "teamwork": 70, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-skillcamp", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-skillcamp-player-3", - "match_name": "Nafkelah", - "full_name": "Andrija Kovačević", - "date_of_birth": "2002-11-13", - "nationality": "ME", - "birth_country": "ME", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/76/SC_Nafkelah_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260207005634", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 63, - "strength": 61, - "agility": 65, - "passing": 63, - "shooting": 66, - "tackling": 61, - "dribbling": 64, - "defending": 61, - "positioning": 64, - "vision": 64, - "decisions": 65, - "composure": 61, - "aggression": 58, - "teamwork": 61, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-skillcamp", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-skillcamp-player-4", - "match_name": "Deadly", - "full_name": "Matthew Luke Smith", - "date_of_birth": "1999-08-28", - "nationality": "GB", - "birth_country": null, - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/4/46/GL_Deadly_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530150827", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 67, - "strength": 64, - "agility": 68, - "passing": 65, - "shooting": 69, - "tackling": 64, - "dribbling": 66, - "defending": 64, - "positioning": 64, - "vision": 66, - "decisions": 63, - "composure": 64, - "aggression": 62, - "teamwork": 65, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-skillcamp", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-skillcamp-player-5", - "match_name": "Steeelback", - "full_name": "Pierre Medjaldi", - "date_of_birth": "2007-03-28", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/b3/GW_Steeelback_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240916153222", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 60, - "stamina": 64, - "strength": 62, - "agility": 59, - "passing": 64, - "shooting": 59, - "tackling": 62, - "dribbling": 61, - "defending": 66, - "positioning": 63, - "vision": 65, - "decisions": 61, - "composure": 62, - "aggression": 59, - "teamwork": 62, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-skillcamp", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-ici-japon-corp-esport-player-1", - "match_name": "Badlulu", - "full_name": "Lucas Piochaud", - "date_of_birth": "2002-09-13", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6a/GXP_Badlulu_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124023", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 68, - "strength": 70, - "agility": 67, - "passing": 66, - "shooting": 67, - "tackling": 70, - "dribbling": 66, - "defending": 74, - "positioning": 67, - "vision": 66, - "decisions": 69, - "composure": 70, - "aggression": 65, - "teamwork": 70, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-ici-japon-corp-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-ici-japon-corp-esport-player-2", - "match_name": "Kaboom", - "full_name": "Osman Onur Korkmaz", - "date_of_birth": "2006-03-14", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 72, - "strength": 70, - "agility": 68, - "passing": 72, - "shooting": 67, - "tackling": 70, - "dribbling": 69, - "defending": 70, - "positioning": 71, - "vision": 73, - "decisions": 69, - "composure": 70, - "aggression": 67, - "teamwork": 70, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-ici-japon-corp-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 89, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-ici-japon-corp-esport-player-3", - "match_name": "Dajor", - "full_name": "Oliver Ryppa", - "date_of_birth": "2003-04-18", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/03/BIG_Dajor_2025_Split_1.png/revision/latest?cb=20250216162352", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 71, - "strength": 69, - "agility": 68, - "passing": 71, - "shooting": 69, - "tackling": 69, - "dribbling": 72, - "defending": 69, - "positioning": 70, - "vision": 72, - "decisions": 68, - "composure": 69, - "aggression": 66, - "teamwork": 69, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-ici-japon-corp-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-ici-japon-corp-esport-player-4", - "match_name": "Soldier", - "full_name": "Thomas Thierry Haudecoeur", - "date_of_birth": "2002-11-06", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 68, - "strength": 70, - "agility": 69, - "passing": 69, - "shooting": 70, - "tackling": 70, - "dribbling": 73, - "defending": 70, - "positioning": 68, - "vision": 67, - "decisions": 69, - "composure": 70, - "aggression": 65, - "teamwork": 71, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-ici-japon-corp-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-ici-japon-corp-esport-player-5", - "match_name": "Whiteinn", - "full_name": "Alexandru Kolozsvari", - "date_of_birth": "2000-10-03", - "nationality": "RO", - "birth_country": "RO", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/36/BAR_whiteinn_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250905145945", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 68, - "strength": 71, - "agility": 68, - "passing": 68, - "shooting": 68, - "tackling": 71, - "dribbling": 66, - "defending": 75, - "positioning": 69, - "vision": 69, - "decisions": 70, - "composure": 71, - "aggression": 65, - "teamwork": 71, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-ici-japon-corp-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-zyb-esport-player-1", - "match_name": "Wao", - "full_name": "Wao Dai", - "date_of_birth": "2003-05-30", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/51/KC_Wao_2022_Split_1.png/revision/latest/scale-to-width-down/220?cb=20220113121319", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 73, - "strength": 70, - "agility": 72, - "passing": 71, - "shooting": 72, - "tackling": 70, - "dribbling": 70, - "defending": 74, - "positioning": 70, - "vision": 71, - "decisions": 69, - "composure": 70, - "aggression": 67, - "teamwork": 70, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-zyb-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-zyb-esport-player-2", - "match_name": "Manaty", - "full_name": "Stéphane Dimier", - "date_of_birth": "2002-01-21", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f9/JL_Manaty_2022_Split_1.png/revision/latest/scale-to-width-down/220?cb=20220121153820", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 64, - "strength": 67, - "agility": 65, - "passing": 64, - "shooting": 64, - "tackling": 67, - "dribbling": 62, - "defending": 67, - "positioning": 65, - "vision": 65, - "decisions": 66, - "composure": 67, - "aggression": 61, - "teamwork": 67, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-zyb-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 81, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-zyb-esport-player-3", - "match_name": "Nisqy", - "full_name": "Yasin Dinçer", - "date_of_birth": "1998-07-28", - "nationality": "BE", - "birth_country": "BE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/eb/VIT_Nisqy_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250430140243", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 64, - "strength": 67, - "agility": 66, - "passing": 67, - "shooting": 67, - "tackling": 67, - "dribbling": 70, - "defending": 67, - "positioning": 65, - "vision": 65, - "decisions": 66, - "composure": 67, - "aggression": 61, - "teamwork": 67, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-zyb-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-zyb-esport-player-4", - "match_name": "Jezu", - "full_name": "Jean Massol", - "date_of_birth": "2000-07-27", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f5/GL_Jezu_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530150839", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 66, - "strength": 63, - "agility": 67, - "passing": 64, - "shooting": 68, - "tackling": 63, - "dribbling": 66, - "defending": 63, - "positioning": 66, - "vision": 65, - "decisions": 67, - "composure": 63, - "aggression": 61, - "teamwork": 64, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-zyb-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-zyb-esport-player-5", - "match_name": "Riippp", - "full_name": "Arnaud Mesmin", - "date_of_birth": "1995-09-13", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 65, - "strength": 68, - "agility": 65, - "passing": 65, - "shooting": 65, - "tackling": 68, - "dribbling": 63, - "defending": 72, - "positioning": 66, - "vision": 66, - "decisions": 67, - "composure": 68, - "aggression": 62, - "teamwork": 68, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-zyb-esport", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-karmine-corp-blue-player-1", - "match_name": "Tao", - "full_name": "Xu Hongtao Alessandro", - "date_of_birth": "2006-02-10", - "nationality": "EU", - "birth_country": "EU", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/eb/KCB_Tao_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260117100541", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 66, - "strength": 68, - "agility": 70, - "passing": 66, - "shooting": 69, - "tackling": 68, - "dribbling": 69, - "defending": 72, - "positioning": 65, - "vision": 67, - "decisions": 67, - "composure": 68, - "aggression": 63, - "teamwork": 68, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-karmine-corp-blue", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 81, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-karmine-corp-blue-player-2", - "match_name": "Yukino", - "full_name": "Johnny Hoang Dang", - "date_of_birth": "2006-02-14", - "nationality": "US", - "birth_country": "US", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/39/KCB_Yukino_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260117100543", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 60, - "stamina": 68, - "strength": 59, - "agility": 68, - "passing": 61, - "shooting": 72, - "tackling": 59, - "dribbling": 74, - "defending": 59, - "positioning": 62, - "vision": 68, - "decisions": 68, - "composure": 67, - "aggression": 56, - "teamwork": 72, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-karmine-corp-blue", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 88, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-karmine-corp-blue-player-3", - "match_name": "Kamiloo", - "full_name": "Kamil Bruno Mehdi Wahid Haudegond", - "date_of_birth": "2005-07-20", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/73/KCB_Kamiloo_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260117100536", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 68, - "strength": 66, - "agility": 65, - "passing": 68, - "shooting": 66, - "tackling": 66, - "dribbling": 69, - "defending": 66, - "positioning": 67, - "vision": 69, - "decisions": 65, - "composure": 66, - "aggression": 63, - "teamwork": 66, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-karmine-corp-blue", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-karmine-corp-blue-player-4", - "match_name": "Hazel", - "full_name": "Costin Pestrițu", - "date_of_birth": "2007-05-14", - "nationality": "RO", - "birth_country": "RO", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/e6/KCB_Hazel_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260117100534", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 68, - "strength": 59, - "agility": 67, - "passing": 60, - "shooting": 70, - "tackling": 59, - "dribbling": 70, - "defending": 59, - "positioning": 59, - "vision": 66, - "decisions": 65, - "composure": 68, - "aggression": 57, - "teamwork": 69, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-karmine-corp-blue", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-karmine-corp-blue-player-5", - "match_name": "Prime", - "full_name": "Olivier Pierre Julien Payet", - "date_of_birth": "2000-02-24", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/8/80/KCB_Prime_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260117100538", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 68, - "strength": 66, - "agility": 68, - "passing": 68, - "shooting": 68, - "tackling": 66, - "dribbling": 66, - "defending": 70, - "positioning": 69, - "vision": 69, - "decisions": 70, - "composure": 66, - "aggression": 63, - "teamwork": 66, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-karmine-corp-blue", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-team-vitality-bee-player-1", - "match_name": "Potent", - "full_name": "Mehdi Ahmed Bouchaffra", - "date_of_birth": "2002-07-14", - "nationality": "US", - "birth_country": "US", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/2/26/JL_Potent_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240521132736", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 68, - "strength": 65, - "agility": 67, - "passing": 66, - "shooting": 67, - "tackling": 65, - "dribbling": 66, - "defending": 69, - "positioning": 67, - "vision": 66, - "decisions": 69, - "composure": 65, - "aggression": 62, - "teamwork": 65, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-team-vitality-bee", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 88, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-team-vitality-bee-player-2", - "match_name": "Dawciu", - "full_name": "Dawid Drzyzga", - "date_of_birth": "2008-03-21", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 67, - "strength": 65, - "agility": 68, - "passing": 67, - "shooting": 67, - "tackling": 65, - "dribbling": 64, - "defending": 65, - "positioning": 66, - "vision": 68, - "decisions": 64, - "composure": 65, - "aggression": 62, - "teamwork": 65, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-team-vitality-bee", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-team-vitality-bee-player-3", - "match_name": "Czajek", - "full_name": "Mateusz Czajka", - "date_of_birth": "2003-09-24", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fd/VIT_Czajek_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250810162152", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 61, - "strength": 59, - "agility": 63, - "passing": 61, - "shooting": 64, - "tackling": 59, - "dribbling": 61, - "defending": 59, - "positioning": 60, - "vision": 62, - "decisions": 58, - "composure": 59, - "aggression": 56, - "teamwork": 59, - "leadership": 61, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-team-vitality-bee", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-team-vitality-bee-player-4", - "match_name": "Yakkey", - "full_name": "Darius Eduard Bistrian", - "date_of_birth": "2005-01-14", - "nationality": "RO", - "birth_country": "RO", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/eb/PAR_Yakkey_2023_Split_2.png/revision/latest/scale-to-width-down/220?cb=20230528083849", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 60, - "strength": 62, - "agility": 61, - "passing": 61, - "shooting": 62, - "tackling": 62, - "dribbling": 65, - "defending": 62, - "positioning": 60, - "vision": 59, - "decisions": 61, - "composure": 62, - "aggression": 57, - "teamwork": 63, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-team-vitality-bee", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-lfl-team-vitality-bee-player-5", - "match_name": "Dekap", - "full_name": "Waleed Mohammed Ismail", - "date_of_birth": "2000-12-11", - "nationality": "JO", - "birth_country": "JO", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/1/14/GK_Dekap_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250429125541", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 65, - "strength": 63, - "agility": 65, - "passing": 65, - "shooting": 65, - "tackling": 63, - "dribbling": 62, - "defending": 67, - "positioning": 64, - "vision": 66, - "decisions": 62, - "composure": 63, - "aggression": 60, - "teamwork": 63, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-lfl-team-vitality-bee", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-spandau-player-1", - "match_name": "JNX", - "full_name": "Janik Bartels", - "date_of_birth": "1998-12-10", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/d1/EINS_JNX_2026_Split_1.png/revision/latest?cb=20260124043347", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 60, - "stamina": 62, - "strength": 59, - "agility": 61, - "passing": 60, - "shooting": 61, - "tackling": 59, - "dribbling": 60, - "defending": 63, - "positioning": 61, - "vision": 60, - "decisions": 63, - "composure": 59, - "aggression": 56, - "teamwork": 59, - "leadership": 60, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-spandau", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-spandau-player-2", - "match_name": "Xagog", - "full_name": "Isa Arda Dagli", - "date_of_birth": "2004-02-14", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/59/EINS_Xagog_2026_Split_1.png/revision/latest?cb=20260124043346", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 69, - "strength": 72, - "agility": 70, - "passing": 72, - "shooting": 69, - "tackling": 72, - "dribbling": 71, - "defending": 72, - "positioning": 70, - "vision": 70, - "decisions": 71, - "composure": 72, - "aggression": 66, - "teamwork": 72, - "leadership": 74, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-spandau", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 84, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-spandau-player-3", - "match_name": "PowerOfEvil", - "full_name": "Tristan Schrage", - "date_of_birth": "1997-10-27", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f2/EINS_PowerOfEvil_2025_Split_1.png/revision/latest?cb=20250216163956", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 68, - "strength": 66, - "agility": 70, - "passing": 68, - "shooting": 71, - "tackling": 66, - "dribbling": 68, - "defending": 66, - "positioning": 67, - "vision": 69, - "decisions": 65, - "composure": 66, - "aggression": 63, - "teamwork": 66, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-spandau", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-spandau-player-4", - "match_name": "Keduii", - "full_name": "Tim Willers", - "date_of_birth": "2000-10-13", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/52/EINS_Keduii_2026_Split_1.png/revision/latest?cb=20260124043344", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 68, - "strength": 70, - "agility": 69, - "passing": 66, - "shooting": 70, - "tackling": 70, - "dribbling": 68, - "defending": 70, - "positioning": 68, - "vision": 67, - "decisions": 69, - "composure": 70, - "aggression": 65, - "teamwork": 71, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-spandau", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-spandau-player-5", - "match_name": "Seaz", - "full_name": "Daniel Binderhofer", - "date_of_birth": "2000-12-17", - "nationality": "AT", - "birth_country": "AT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/67/EINS_seaz_2026_Split_1.png/revision/latest?cb=20260124043343", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 65, - "agility": 62, - "passing": 62, - "shooting": 62, - "tackling": 65, - "dribbling": 60, - "defending": 69, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 65, - "aggression": 59, - "teamwork": 65, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-spandau", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-g2-nord-player-1", - "match_name": "Shelfmade", - "full_name": "Francesco Cardia", - "date_of_birth": "2006-10-02", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bb/BIG_Shelfmade_2025_Split_1.png/revision/latest?cb=20250216162354", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 70, - "strength": 70, - "agility": 68, - "passing": 71, - "shooting": 65, - "tackling": 70, - "dribbling": 68, - "defending": 74, - "positioning": 70, - "vision": 68, - "decisions": 64, - "composure": 70, - "aggression": 67, - "teamwork": 68, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-g2-nord", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-g2-nord-player-2", - "match_name": "Markoon", - "full_name": "Mark van Woensel", - "date_of_birth": "2002-06-28", - "nationality": "NL", - "birth_country": "NL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/1/10/SLY_Markoon_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530151743", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 68, - "strength": 64, - "agility": 69, - "passing": 64, - "shooting": 65, - "tackling": 64, - "dribbling": 67, - "defending": 64, - "positioning": 62, - "vision": 67, - "decisions": 68, - "composure": 67, - "aggression": 58, - "teamwork": 67, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-g2-nord", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-g2-nord-player-3", - "match_name": "Toasty", - "full_name": "Victor Alexander Chea", - "date_of_birth": "2006-01-19", - "nationality": "US", - "birth_country": "US", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 70, - "strength": 62, - "agility": 68, - "passing": 64, - "shooting": 75, - "tackling": 62, - "dribbling": 76, - "defending": 62, - "positioning": 65, - "vision": 70, - "decisions": 69, - "composure": 68, - "aggression": 59, - "teamwork": 78, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-g2-nord", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 90, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-g2-nord-player-4", - "match_name": "Rin", - "full_name": "Khalil Sahraoui", - "date_of_birth": "2002-11-05", - "nationality": "DZ", - "birth_country": "DZ", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bf/HRTS_Rin_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124035", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 65, - "strength": 66, - "agility": 68, - "passing": 65, - "shooting": 77, - "tackling": 66, - "dribbling": 78, - "defending": 66, - "positioning": 64, - "vision": 66, - "decisions": 67, - "composure": 64, - "aggression": 61, - "teamwork": 75, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-g2-nord", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 84, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-g2-nord-player-5", - "match_name": "Tockimo", - "full_name": "Timo Nils Bock", - "date_of_birth": "2002-02-22", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/95/Tockimo_with_cat_ears.png/revision/latest/scale-to-width-down/220?cb=20250211184639", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 66, - "strength": 69, - "agility": 65, - "passing": 71, - "shooting": 66, - "tackling": 69, - "dribbling": 68, - "defending": 73, - "positioning": 70, - "vision": 69, - "decisions": 69, - "composure": 67, - "aggression": 66, - "teamwork": 66, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-g2-nord", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-team-orange-gaming-player-1", - "match_name": "zorenous", - "full_name": "Cameron Abbott", - "date_of_birth": "2007-04-13", - "nationality": "EU", - "birth_country": "EU", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/ed/CHF_zorenous_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250430135308", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 63, - "strength": 60, - "agility": 62, - "passing": 61, - "shooting": 62, - "tackling": 60, - "dribbling": 61, - "defending": 64, - "positioning": 62, - "vision": 61, - "decisions": 64, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 61, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-team-orange-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-team-orange-gaming-player-2", - "match_name": "Woldjo", - "full_name": "William Donatzky", - "date_of_birth": "2005-07-09", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/2/2b/Woldjo_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240610211337", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 63, - "strength": 66, - "agility": 64, - "passing": 63, - "shooting": 63, - "tackling": 66, - "dribbling": 61, - "defending": 66, - "positioning": 64, - "vision": 64, - "decisions": 65, - "composure": 66, - "aggression": 60, - "teamwork": 66, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-team-orange-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-team-orange-gaming-player-3", - "match_name": "Sajator", - "full_name": "Jan Zítek", - "date_of_birth": "2004-10-11", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/2/22/HRTS_SAJATOR_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124036", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 62, - "strength": 60, - "agility": 64, - "passing": 62, - "shooting": 65, - "tackling": 60, - "dribbling": 63, - "defending": 60, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-team-orange-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-team-orange-gaming-player-4", - "match_name": "Ryuk", - "full_name": "David Hörmann", - "date_of_birth": "2005-06-25", - "nationality": "AT", - "birth_country": "AT", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 63, - "strength": 65, - "agility": 64, - "passing": 64, - "shooting": 65, - "tackling": 65, - "dribbling": 68, - "defending": 65, - "positioning": 63, - "vision": 62, - "decisions": 64, - "composure": 65, - "aggression": 60, - "teamwork": 66, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-team-orange-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-team-orange-gaming-player-5", - "match_name": "Lilipp", - "full_name": "Philipp Samuel Englert", - "date_of_birth": "2001-01-20", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/32/EINS_Lilipp_2025_Split_1.png/revision/latest?cb=20250216163954", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 65, - "agility": 62, - "passing": 62, - "shooting": 62, - "tackling": 65, - "dribbling": 60, - "defending": 69, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 65, - "aggression": 59, - "teamwork": 65, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-team-orange-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-kaufland-hangry-knights-player-1", - "match_name": "Venour", - "full_name": "Iwan Skorikov", - "date_of_birth": "2002-01-08", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/76/KHK_Venour_2025_Split_1.png/revision/latest?cb=20250216163951", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 66, - "strength": 63, - "agility": 65, - "passing": 64, - "shooting": 65, - "tackling": 63, - "dribbling": 64, - "defending": 67, - "positioning": 65, - "vision": 64, - "decisions": 67, - "composure": 63, - "aggression": 60, - "teamwork": 63, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-kaufland-hangry-knights", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-kaufland-hangry-knights-player-2", - "match_name": "Densi", - "full_name": "Denis Aljic", - "date_of_birth": "2003-06-03", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/1/14/Densi.png/revision/latest/scale-to-width-down/220?cb=20240523175431", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 67, - "strength": 65, - "agility": 68, - "passing": 67, - "shooting": 67, - "tackling": 65, - "dribbling": 65, - "defending": 65, - "positioning": 68, - "vision": 68, - "decisions": 69, - "composure": 65, - "aggression": 62, - "teamwork": 65, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-kaufland-hangry-knights", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-kaufland-hangry-knights-player-3", - "match_name": "Abbedagge", - "full_name": "Felix Alfred Braun", - "date_of_birth": "1999-09-10", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/97/SK_Abbedagge_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250810162243", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 60, - "agility": 59, - "passing": 62, - "shooting": 60, - "tackling": 60, - "dribbling": 63, - "defending": 60, - "positioning": 61, - "vision": 63, - "decisions": 59, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-kaufland-hangry-knights", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-kaufland-hangry-knights-player-4", - "match_name": "UNF0RGIVEN", - "full_name": "William Nieminen", - "date_of_birth": "2000-08-23", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/90/MKFX_UNF0RGIVEN_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124059", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 73, - "strength": 70, - "agility": 69, - "passing": 71, - "shooting": 70, - "tackling": 70, - "dribbling": 73, - "defending": 70, - "positioning": 70, - "vision": 72, - "decisions": 69, - "composure": 70, - "aggression": 68, - "teamwork": 71, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-kaufland-hangry-knights", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-kaufland-hangry-knights-player-5", - "match_name": "Pyrka", - "full_name": "Łukasz Grześkowiak", - "date_of_birth": "2000-06-04", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/ad/RBT_Pyrka_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124103", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 65, - "strength": 63, - "agility": 65, - "passing": 65, - "shooting": 65, - "tackling": 63, - "dribbling": 63, - "defending": 67, - "positioning": 66, - "vision": 66, - "decisions": 67, - "composure": 63, - "aggression": 60, - "teamwork": 63, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-kaufland-hangry-knights", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-rossmann-centaurs-player-1", - "match_name": "CPM", - "full_name": "Laurentiu-Dodel Zidaru", - "date_of_birth": "1994-12-13", - "nationality": "RO", - "birth_country": "RO", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/03/ZTA_CPM_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20250726152141", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 67, - "strength": 69, - "agility": 66, - "passing": 65, - "shooting": 66, - "tackling": 69, - "dribbling": 65, - "defending": 73, - "positioning": 66, - "vision": 65, - "decisions": 68, - "composure": 69, - "aggression": 64, - "teamwork": 69, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-rossmann-centaurs", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-rossmann-centaurs-player-2", - "match_name": "Pasu", - "full_name": "Paul Hildebrandt", - "date_of_birth": "2007-12-20", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/02/A41G_Pasu.png/revision/latest/scale-to-width-down/220?cb=20241128153051", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 60, - "stamina": 61, - "strength": 59, - "agility": 62, - "passing": 61, - "shooting": 61, - "tackling": 59, - "dribbling": 59, - "defending": 59, - "positioning": 62, - "vision": 62, - "decisions": 63, - "composure": 59, - "aggression": 56, - "teamwork": 59, - "leadership": 61, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-rossmann-centaurs", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-rossmann-centaurs-player-3", - "match_name": "Fooneses", - "full_name": "Hannes Hollmann", - "date_of_birth": "2004-12-17", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/5d/A41G_Fooneses_2025_Split_3.png/revision/latest/scale-to-width-down/220?cb=20251102140357", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 61, - "strength": 59, - "agility": 63, - "passing": 61, - "shooting": 64, - "tackling": 59, - "dribbling": 62, - "defending": 59, - "positioning": 62, - "vision": 62, - "decisions": 63, - "composure": 59, - "aggression": 56, - "teamwork": 59, - "leadership": 61, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-rossmann-centaurs", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-rossmann-centaurs-player-4", - "match_name": "Devn", - "full_name": "Nam Jürgen Nguyen", - "date_of_birth": "2005-11-10", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/4/4e/DIA_Devn_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240608063353", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 64, - "strength": 66, - "agility": 65, - "passing": 65, - "shooting": 66, - "tackling": 66, - "dribbling": 69, - "defending": 66, - "positioning": 64, - "vision": 63, - "decisions": 65, - "composure": 66, - "aggression": 61, - "teamwork": 67, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-rossmann-centaurs", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-rossmann-centaurs-player-5", - "match_name": "Smarty", - "full_name": "Matyáš Rozvoral", - "date_of_birth": "2005-07-11", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fd/ESB_Smarty_2024_Split_1.png/revision/latest/scale-to-width-down/220?cb=20240124161944", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 65, - "strength": 63, - "agility": 65, - "passing": 65, - "shooting": 65, - "tackling": 63, - "dribbling": 62, - "defending": 67, - "positioning": 64, - "vision": 66, - "decisions": 62, - "composure": 63, - "aggression": 60, - "teamwork": 63, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-rossmann-centaurs", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-a-one-man-army-player-1", - "match_name": "Smurfe", - "full_name": "Felix Rivedal Hylleseth", - "date_of_birth": "2004-09-27", - "nationality": "NO", - "birth_country": "NO", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c6/AOMA_Smurfe_2026_Split_1.png/revision/latest?cb=20260124043336", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 72, - "strength": 69, - "agility": 66, - "passing": 70, - "shooting": 66, - "tackling": 69, - "dribbling": 70, - "defending": 73, - "positioning": 69, - "vision": 70, - "decisions": 68, - "composure": 69, - "aggression": 66, - "teamwork": 69, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-a-one-man-army", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 89, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-a-one-man-army-player-2", - "match_name": "Dome", - "full_name": "Dominik Christensen", - "date_of_birth": "2007-11-28", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/ec/AOMA_Dome_2026_Split_1.png/revision/latest?cb=20260124043337", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 71, - "strength": 69, - "agility": 72, - "passing": 71, - "shooting": 71, - "tackling": 69, - "dribbling": 69, - "defending": 69, - "positioning": 72, - "vision": 72, - "decisions": 73, - "composure": 69, - "aggression": 66, - "teamwork": 69, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-a-one-man-army", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-a-one-man-army-player-3", - "match_name": "Artoria", - "full_name": "Alexis Diebold", - "date_of_birth": "2002-12-17", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f1/AOMA_Artoria_2026_Split_1.png/revision/latest?cb=20260124043339", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 66, - "strength": 69, - "agility": 68, - "passing": 69, - "shooting": 69, - "tackling": 69, - "dribbling": 72, - "defending": 69, - "positioning": 67, - "vision": 67, - "decisions": 68, - "composure": 69, - "aggression": 63, - "teamwork": 69, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-a-one-man-army", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-a-one-man-army-player-4", - "match_name": "Xay", - "full_name": "Corentin Leclercq", - "date_of_birth": "2005-10-03", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/dc/AOMA_Xay_2026_Split_1.png/revision/latest?cb=20260124043334", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 66, - "strength": 63, - "agility": 62, - "passing": 64, - "shooting": 63, - "tackling": 63, - "dribbling": 66, - "defending": 63, - "positioning": 63, - "vision": 65, - "decisions": 62, - "composure": 63, - "aggression": 61, - "teamwork": 64, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-a-one-man-army", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-a-one-man-army-player-5", - "match_name": "Urban", - "full_name": "Marcus Urban Christensen", - "date_of_birth": "2000-07-03", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c5/AOMA_Urban_2026_Split_1.png/revision/latest?cb=20260124043338", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 64, - "strength": 62, - "agility": 64, - "passing": 64, - "shooting": 64, - "tackling": 62, - "dribbling": 62, - "defending": 66, - "positioning": 65, - "vision": 65, - "decisions": 66, - "composure": 62, - "aggression": 59, - "teamwork": 62, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-a-one-man-army", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 87, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-e-wie-einfach-e-sports-player-1", - "match_name": "Vizicsacsi", - "full_name": "Tamás Kiss", - "date_of_birth": "1993-06-14", - "nationality": "HU", - "birth_country": "HU", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/6d/EWI_Vizicsacsi_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260213130330", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 59, - "stamina": 61, - "strength": 63, - "agility": 60, - "passing": 59, - "shooting": 60, - "tackling": 63, - "dribbling": 59, - "defending": 67, - "positioning": 60, - "vision": 59, - "decisions": 62, - "composure": 63, - "aggression": 58, - "teamwork": 63, - "leadership": 59, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-e-wie-einfach-e-sports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-e-wie-einfach-e-sports-player-2", - "match_name": "Afroboi", - "full_name": "Adrian Kaymer", - "date_of_birth": "2000-04-13", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c3/EWI_Afroboi_2025_Split_1.png/revision/latest?cb=20250216164038", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 71, - "strength": 69, - "agility": 67, - "passing": 71, - "shooting": 66, - "tackling": 69, - "dribbling": 68, - "defending": 69, - "positioning": 70, - "vision": 72, - "decisions": 68, - "composure": 69, - "aggression": 66, - "teamwork": 69, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-e-wie-einfach-e-sports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-e-wie-einfach-e-sports-player-3", - "match_name": "Relative", - "full_name": "Leon Van", - "date_of_birth": "2002-06-14", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/bd/EWI_Relative_2025_Split_1.png/revision/latest?cb=20250216164037", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 65, - "strength": 68, - "agility": 67, - "passing": 65, - "shooting": 68, - "tackling": 68, - "dribbling": 66, - "defending": 68, - "positioning": 66, - "vision": 66, - "decisions": 67, - "composure": 68, - "aggression": 62, - "teamwork": 68, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-e-wie-einfach-e-sports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 79, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-e-wie-einfach-e-sports-player-4", - "match_name": "Noz2k", - "full_name": "Noah Richter", - "date_of_birth": "2004-06-29", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fa/EWI_Noz2k_2025_Split_1.png/revision/latest?cb=20250216164036", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 65, - "strength": 67, - "agility": 66, - "passing": 63, - "shooting": 67, - "tackling": 67, - "dribbling": 65, - "defending": 67, - "positioning": 65, - "vision": 64, - "decisions": 66, - "composure": 67, - "aggression": 62, - "teamwork": 68, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-e-wie-einfach-e-sports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-e-wie-einfach-e-sports-player-5", - "match_name": "Wildenbruch", - "full_name": "Linus Köhler", - "date_of_birth": "2003-08-20", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/ad/EWI_Wildenbruch_2026_Split_1.png/revision/latest/scale-to-width-down/220?cb=20260213130952", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 70, - "strength": 73, - "agility": 70, - "passing": 70, - "shooting": 70, - "tackling": 73, - "dribbling": 68, - "defending": 77, - "positioning": 71, - "vision": 71, - "decisions": 72, - "composure": 73, - "aggression": 67, - "teamwork": 73, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-e-wie-einfach-e-sports", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 85, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-unicorns-of-love-sexy-edition-player-1", - "match_name": "Fornoreason", - "full_name": "Felix Schummel", - "date_of_birth": "2003-10-29", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/0d/USE_Fornoreason_2025_Split_1.png/revision/latest?cb=20250216164019", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 67, - "strength": 64, - "agility": 66, - "passing": 65, - "shooting": 66, - "tackling": 64, - "dribbling": 65, - "defending": 68, - "positioning": 66, - "vision": 65, - "decisions": 68, - "composure": 64, - "aggression": 61, - "teamwork": 64, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-unicorns-of-love-sexy-edition", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-unicorns-of-love-sexy-edition-player-2", - "match_name": "White", - "full_name": "Aslan Panglose", - "date_of_birth": "2002-07-11", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/9b/USE_White_2025_Split_1.png/revision/latest?cb=20250216164017", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 70, - "strength": 73, - "agility": 71, - "passing": 70, - "shooting": 70, - "tackling": 73, - "dribbling": 68, - "defending": 73, - "positioning": 71, - "vision": 71, - "decisions": 72, - "composure": 73, - "aggression": 67, - "teamwork": 73, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-unicorns-of-love-sexy-edition", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-unicorns-of-love-sexy-edition-player-3", - "match_name": "RoyalKanin", - "full_name": "Linus Grönlund", - "date_of_birth": "2002-07-06", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/32/ROSS_RoyalKanin_2025_Split_1.png/revision/latest?cb=20250216164023", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 67, - "strength": 70, - "agility": 69, - "passing": 67, - "shooting": 70, - "tackling": 70, - "dribbling": 68, - "defending": 70, - "positioning": 68, - "vision": 68, - "decisions": 69, - "composure": 70, - "aggression": 64, - "teamwork": 70, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-unicorns-of-love-sexy-edition", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-unicorns-of-love-sexy-edition-player-4", - "match_name": "DenVoksne", - "full_name": "Nikolaj Asbjorn Meilby", - "date_of_birth": "2001-07-15", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/05/USE_DenVoksne_2025_Split_1.png/revision/latest?cb=20250216164015", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 68, - "strength": 65, - "agility": 64, - "passing": 66, - "shooting": 65, - "tackling": 65, - "dribbling": 68, - "defending": 65, - "positioning": 65, - "vision": 67, - "decisions": 64, - "composure": 65, - "aggression": 63, - "teamwork": 66, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-unicorns-of-love-sexy-edition", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 81, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-unicorns-of-love-sexy-edition-player-5", - "match_name": "Twiizt", - "full_name": "Elton Richie Garcia Spetsig", - "date_of_birth": "2000-11-02", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f5/GL_Twiizt_2025_Split_2.png/revision/latest/scale-to-width-down/220?cb=20250530150816", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 66, - "strength": 64, - "agility": 61, - "passing": 66, - "shooting": 61, - "tackling": 64, - "dribbling": 63, - "defending": 68, - "positioning": 65, - "vision": 67, - "decisions": 63, - "composure": 64, - "aggression": 61, - "teamwork": 64, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-unicorns-of-love-sexy-edition", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-berlin-international-gaming-player-1", - "match_name": "Irrelevant", - "full_name": "Joel Miro Scharoll", - "date_of_birth": "2001-10-22", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/76/BDS_Irrelevant_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250125185551", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 65, - "strength": 67, - "agility": 64, - "passing": 65, - "shooting": 64, - "tackling": 67, - "dribbling": 68, - "defending": 71, - "positioning": 64, - "vision": 63, - "decisions": 66, - "composure": 67, - "aggression": 62, - "teamwork": 67, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-berlin-international-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-berlin-international-gaming-player-2", - "match_name": "Habubu", - "full_name": "Seyit Cüce", - "date_of_birth": "2007-06-10", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c7/EZY_Habuubu_2021.png/revision/latest/scale-to-width-down/220?cb=20210620182553", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 64, - "strength": 62, - "agility": 65, - "passing": 64, - "shooting": 64, - "tackling": 62, - "dribbling": 62, - "defending": 62, - "positioning": 65, - "vision": 65, - "decisions": 66, - "composure": 62, - "aggression": 59, - "teamwork": 62, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-berlin-international-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-berlin-international-gaming-player-3", - "match_name": "Reeker", - "full_name": "Steven Chen", - "date_of_birth": "2001-05-15", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/1/1a/SK_RKR_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250125185606", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 61, - "stamina": 62, - "strength": 60, - "agility": 59, - "passing": 62, - "shooting": 60, - "tackling": 60, - "dribbling": 63, - "defending": 60, - "positioning": 61, - "vision": 63, - "decisions": 59, - "composure": 60, - "aggression": 57, - "teamwork": 60, - "leadership": 62, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-berlin-international-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-berlin-international-gaming-player-4", - "match_name": "Patrik", - "full_name": "Patrik Jírů", - "date_of_birth": "2000-04-07", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/5d/RGE_Patrik_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250125185608", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 61, - "strength": 58, - "agility": 62, - "passing": 59, - "shooting": 63, - "tackling": 58, - "dribbling": 61, - "defending": 58, - "positioning": 61, - "vision": 60, - "decisions": 62, - "composure": 58, - "aggression": 56, - "teamwork": 59, - "leadership": 59, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-berlin-international-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-berlin-international-gaming-player-5", - "match_name": "Kaiser", - "full_name": "Norman Kaiser", - "date_of_birth": "1998-11-19", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/7a/HRTS_Kaiser_2025_Split_1.png/revision/latest/scale-to-width-down/220?cb=20250121124033", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 61, - "strength": 64, - "agility": 61, - "passing": 64, - "shooting": 61, - "tackling": 64, - "dribbling": 64, - "defending": 68, - "positioning": 62, - "vision": 62, - "decisions": 63, - "composure": 64, - "aggression": 58, - "teamwork": 64, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-berlin-international-gaming", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-frankfurt-player-1", - "match_name": "Mietek", - "full_name": "Nikolas Nowak", - "date_of_birth": "2005-06-06", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/2/2f/SGE_Mietek_2026_Winter.png/revision/latest/scale-to-width-down/220?cb=20260413004823", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 61, - "strength": 63, - "agility": 60, - "passing": 61, - "shooting": 60, - "tackling": 63, - "dribbling": 64, - "defending": 67, - "positioning": 60, - "vision": 59, - "decisions": 62, - "composure": 63, - "aggression": 58, - "teamwork": 63, - "leadership": 64, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-frankfurt", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-frankfurt-player-2", - "match_name": "D4nKa", - "full_name": "Daniel Golzmann", - "date_of_birth": "2001-11-17", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/b8/AFW_D4nKa_2025_Split_1.png/revision/latest?cb=20250216164010", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 62, - "stamina": 63, - "strength": 61, - "agility": 64, - "passing": 63, - "shooting": 63, - "tackling": 61, - "dribbling": 61, - "defending": 61, - "positioning": 64, - "vision": 64, - "decisions": 65, - "composure": 61, - "aggression": 58, - "teamwork": 61, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-frankfurt", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 79, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-frankfurt-player-3", - "match_name": "Sencux", - "full_name": "Chres Laursen", - "date_of_birth": "1998-09-17", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f9/BIG_Sencux_PRM_1st_Division_2024_Summer.png/revision/latest/scale-to-width-down/220?cb=20240523181729", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 63, - "strength": 61, - "agility": 65, - "passing": 63, - "shooting": 66, - "tackling": 61, - "dribbling": 63, - "defending": 61, - "positioning": 62, - "vision": 64, - "decisions": 60, - "composure": 61, - "aggression": 58, - "teamwork": 61, - "leadership": 63, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-frankfurt", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 79, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-frankfurt-player-4", - "match_name": "Notiko", - "full_name": "Nick Celombitko", - "date_of_birth": "2001-09-27", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/9/94/SGE_MEDIADAY_NOTIKO.jpg/revision/latest/scale-to-width-down/220?cb=20260208112830", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 67, - "strength": 69, - "agility": 68, - "passing": 65, - "shooting": 69, - "tackling": 69, - "dribbling": 67, - "defending": 69, - "positioning": 67, - "vision": 66, - "decisions": 68, - "composure": 69, - "aggression": 64, - "teamwork": 70, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-frankfurt", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 79, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "academy-prime-league-eintracht-frankfurt-player-5", - "match_name": "Farfetch", - "full_name": "Berk Badur", - "date_of_birth": "1998-09-09", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/cd/MISA_Farfetch_2024_Split_2.png/revision/latest/scale-to-width-down/220?cb=20240618160637", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 67, - "stamina": 68, - "strength": 71, - "agility": 68, - "passing": 68, - "shooting": 68, - "tackling": 71, - "dribbling": 66, - "defending": 75, - "positioning": 69, - "vision": 69, - "decisions": 70, - "composure": 71, - "aggression": 65, - "teamwork": 71, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": "academy-prime-league-eintracht-frankfurt", - "traits": [], - "contract_end": "2028-11-30", - "wage": 8000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": false, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-bwipo-1", - "match_name": "Bwipo", - "full_name": "Gabriel Rau", - "date_of_birth": "1999-04-28", - "nationality": "BE", - "birth_country": "BE", - "profile_image_url": "https://dpm.lol/esport/players/bwipo.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 77, - "strength": 79, - "agility": 76, - "passing": 75, - "shooting": 76, - "tackling": 79, - "dribbling": 75, - "defending": 83, - "positioning": 76, - "vision": 75, - "decisions": 78, - "composure": 79, - "aggression": 74, - "teamwork": 79, - "leadership": 75, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 81, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 190000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-odoamne-2", - "match_name": "Odoamne", - "full_name": "Andrei Pascu", - "date_of_birth": "1995-10-04", - "nationality": "RO", - "birth_country": "RO", - "profile_image_url": "https://dpm.lol/esport/players/odoamne.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 72, - "strength": 74, - "agility": 71, - "passing": 72, - "shooting": 71, - "tackling": 74, - "dribbling": 73, - "defending": 78, - "positioning": 71, - "vision": 70, - "decisions": 73, - "composure": 74, - "aggression": 69, - "teamwork": 74, - "leadership": 75, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 84, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 170000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-alphari-3", - "match_name": "Alphari", - "full_name": "Barney Morris", - "date_of_birth": "1999-10-15", - "nationality": "GB", - "birth_country": null, - "profile_image_url": "https://dpm.lol/esport/players/alphari.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 74, - "strength": 71, - "agility": 73, - "passing": 72, - "shooting": 73, - "tackling": 71, - "dribbling": 71, - "defending": 75, - "positioning": 71, - "vision": 72, - "decisions": 70, - "composure": 71, - "aggression": 68, - "teamwork": 71, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 83, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 165000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 71, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-malrang-4", - "match_name": "Malrang", - "full_name": "Kim Geun-seong", - "date_of_birth": "2000-10-11", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/malrang.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 66, - "strength": 77, - "agility": 75, - "passing": 79, - "shooting": 68, - "tackling": 77, - "dribbling": 65, - "defending": 77, - "positioning": 78, - "vision": 67, - "decisions": 65, - "composure": 72, - "aggression": 74, - "teamwork": 64, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 78, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 215000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-jankos-5", - "match_name": "Jankos", - "full_name": "Marcin Jankowski", - "date_of_birth": "1994-08-23", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://dpm.lol/esport/players/jankos.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 74, - "strength": 72, - "agility": 75, - "passing": 74, - "shooting": 74, - "tackling": 72, - "dribbling": 72, - "defending": 72, - "positioning": 75, - "vision": 75, - "decisions": 76, - "composure": 72, - "aggression": 69, - "teamwork": 72, - "leadership": 74, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 85, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 175000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-bjergsen-6", - "match_name": "Bjergsen", - "full_name": "Søren Bjerg", - "date_of_birth": "1996-02-21", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://dpm.lol/esport/players/bjergsen.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 74, - "strength": 72, - "agility": 71, - "passing": 74, - "shooting": 72, - "tackling": 72, - "dribbling": 75, - "defending": 72, - "positioning": 73, - "vision": 75, - "decisions": 71, - "composure": 72, - "aggression": 69, - "teamwork": 72, - "leadership": 74, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 90, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 170000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-perkz-7", - "match_name": "Perkz", - "full_name": "Luka Perković", - "date_of_birth": "1998-06-29", - "nationality": "HR", - "birth_country": "HR", - "profile_image_url": "https://dpm.lol/esport/players/perkz.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 79, - "stamina": 66, - "strength": 75, - "agility": 74, - "passing": 77, - "shooting": 70, - "tackling": 75, - "dribbling": 70, - "defending": 75, - "positioning": 78, - "vision": 78, - "decisions": 68, - "composure": 57, - "aggression": 72, - "teamwork": 70, - "leadership": 80, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 90, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 195000, - "market_value": 150000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-rekkles-10", - "match_name": "Rekkles", - "full_name": "Martin Larsson", - "date_of_birth": "1996-05-06", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://dpm.lol/esport/players/rekkles.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 69, - "strength": 75, - "agility": 74, - "passing": 76, - "shooting": 72, - "tackling": 75, - "dribbling": 74, - "defending": 75, - "positioning": 75, - "vision": 76, - "decisions": 74, - "composure": 70, - "aggression": 73, - "teamwork": 74, - "leadership": 75, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 86, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 185000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-doublelift-11", - "match_name": "Doublelift", - "full_name": "Yiliang Peng", - "date_of_birth": "1993-07-19", - "nationality": "US", - "birth_country": "US", - "profile_image_url": "https://dpm.lol/esport/players/doublelift.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 72, - "strength": 69, - "agility": 73, - "passing": 70, - "shooting": 74, - "tackling": 69, - "dribbling": 72, - "defending": 69, - "positioning": 72, - "vision": 71, - "decisions": 73, - "composure": 69, - "aggression": 67, - "teamwork": 70, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 88, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 165000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 71, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-hylissang-12", - "match_name": "Hylissang", - "full_name": "Zdravets Galabov", - "date_of_birth": "1995-07-15", - "nationality": "BG", - "birth_country": "BG", - "profile_image_url": "https://dpm.lol/esport/players/hylissang.webp", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 76, - "strength": 74, - "agility": 71, - "passing": 76, - "shooting": 71, - "tackling": 74, - "dribbling": 73, - "defending": 78, - "positioning": 75, - "vision": 77, - "decisions": 70, - "composure": 74, - "aggression": 71, - "teamwork": 74, - "leadership": 78, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 175000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-yagao-13", - "match_name": "Yagao", - "full_name": "Zeng Qi", - "date_of_birth": "1998-04-18", - "nationality": "CN", - "birth_country": "CN", - "profile_image_url": "https://dpm.lol/esport/players/yagao.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 82, - "stamina": 78, - "strength": 81, - "agility": 80, - "passing": 81, - "shooting": 81, - "tackling": 81, - "dribbling": 84, - "defending": 81, - "positioning": 79, - "vision": 79, - "decisions": 80, - "composure": 81, - "aggression": 75, - "teamwork": 81, - "leadership": 83, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 85, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "BallWinner", - "CompleteForward", - "SetPieceSpecialist" - ], - "contract_end": "2026-11-18", - "wage": 290000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 81, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-bengi-14", - "match_name": "Bengi", - "full_name": "Bae Seong-ung", - "date_of_birth": "1994-03-03", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/bengi.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 78, - "strength": 76, - "agility": 79, - "passing": 78, - "shooting": 78, - "tackling": 76, - "dribbling": 75, - "defending": 76, - "positioning": 77, - "vision": 79, - "decisions": 75, - "composure": 76, - "aggression": 73, - "teamwork": 76, - "leadership": 78, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 90, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 215000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-frappii-16", - "match_name": "Frappii", - "full_name": "Louis Maurin", - "date_of_birth": "2001-11-27", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/ab/UOL_Frappii_2021_Split_1.png/revision/latest?cb=20210501113929", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 66, - "strength": 64, - "agility": 66, - "passing": 66, - "shooting": 66, - "tackling": 64, - "dribbling": 63, - "defending": 68, - "positioning": 65, - "vision": 67, - "decisions": 63, - "composure": 64, - "aggression": 61, - "teamwork": 64, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 64, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 135000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 64, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-beryl-17", - "match_name": "BeryL", - "full_name": "Geon-hee Cho", - "date_of_birth": "2001-11-30", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/beryl.webp", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 91, - "stamina": 93, - "strength": 91, - "agility": 93, - "passing": 93, - "shooting": 93, - "tackling": 91, - "dribbling": 90, - "defending": 95, - "positioning": 92, - "vision": 94, - "decisions": 90, - "composure": 91, - "aggression": 88, - "teamwork": 91, - "leadership": 93, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 93, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "Speedster", - "Tank", - "Agile", - "Tireless", - "Playmaker", - "Sharpshooter", - "Dribbler", - "BallWinner", - "Rock", - "Leader", - "CoolHead", - "Visionary", - "TeamPlayer", - "CompleteForward", - "Engine", - "SetPieceSpecialist" - ], - "contract_end": "2026-11-18", - "wage": 310000, - "market_value": 360000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 91, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-bonnie-18", - "match_name": "Bonnie", - "full_name": "Yoon-seong Hong", - "date_of_birth": "2006-03-25", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/bonnie.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 77, - "stamina": 78, - "strength": 81, - "agility": 79, - "passing": 78, - "shooting": 78, - "tackling": 81, - "dribbling": 76, - "defending": 81, - "positioning": 79, - "vision": 79, - "decisions": 80, - "composure": 81, - "aggression": 75, - "teamwork": 81, - "leadership": 78, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 78, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "BallWinner", - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 230000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-clid-19", - "match_name": "Clid", - "full_name": "Dong-geun Kim", - "date_of_birth": "1998-11-04", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/clid.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 78, - "stamina": 80, - "strength": 78, - "agility": 81, - "passing": 80, - "shooting": 80, - "tackling": 78, - "dribbling": 77, - "defending": 78, - "positioning": 79, - "vision": 81, - "decisions": 77, - "composure": 78, - "aggression": 75, - "teamwork": 78, - "leadership": 80, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 78, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "Playmaker", - "CompleteForward", - "SetPieceSpecialist" - ], - "contract_end": "2026-11-18", - "wage": 230000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-deft-20", - "match_name": "Deft", - "full_name": "Hyuk-kyu Kim", - "date_of_birth": "1996-03-09", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/deft.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 82, - "stamina": 79, - "strength": 81, - "agility": 80, - "passing": 80, - "shooting": 81, - "tackling": 81, - "dribbling": 84, - "defending": 81, - "positioning": 79, - "vision": 78, - "decisions": 80, - "composure": 81, - "aggression": 76, - "teamwork": 82, - "leadership": 82, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 90, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "BallWinner", - "CompleteForward", - "SetPieceSpecialist" - ], - "contract_end": "2026-11-18", - "wage": 240000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-dndn-21", - "match_name": "DnDn", - "full_name": "Won-seok Park", - "date_of_birth": "2002-01-27", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/aa/NS.C_DnDn_2021_Split_1.png/revision/latest/scale-to-width-down/640?cb=20210129170411", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 77, - "strength": 79, - "agility": 76, - "passing": 75, - "shooting": 76, - "tackling": 79, - "dribbling": 75, - "defending": 83, - "positioning": 76, - "vision": 75, - "decisions": 78, - "composure": 79, - "aggression": 74, - "teamwork": 79, - "leadership": 75, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 79, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 215000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-doinb-22", - "match_name": "Doinb", - "full_name": "Tae-sang Kim", - "date_of_birth": "1996-05-28", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/doinb.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 88, - "stamina": 84, - "strength": 87, - "agility": 86, - "passing": 87, - "shooting": 87, - "tackling": 87, - "dribbling": 90, - "defending": 87, - "positioning": 85, - "vision": 85, - "decisions": 86, - "composure": 87, - "aggression": 81, - "teamwork": 87, - "leadership": 89, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 90, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "Speedster", - "Tank", - "Agile", - "Playmaker", - "Sharpshooter", - "Dribbler", - "BallWinner", - "Rock", - "Leader", - "CoolHead", - "Visionary", - "TeamPlayer", - "CompleteForward", - "SetPieceSpecialist" - ], - "contract_end": "2026-11-18", - "wage": 275000, - "market_value": 240000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 86, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-envyy-23", - "match_name": "Envyy", - "full_name": "Jin Douglas", - "date_of_birth": "2003-07-12", - "nationality": "US", - "birth_country": "US", - "profile_image_url": "https://dpm.lol/esport/players/envyy.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 72, - "stamina": 73, - "strength": 71, - "agility": 74, - "passing": 73, - "shooting": 73, - "tackling": 71, - "dribbling": 71, - "defending": 71, - "positioning": 74, - "vision": 74, - "decisions": 75, - "composure": 71, - "aggression": 68, - "teamwork": 71, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 65, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 170000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-fate-24", - "match_name": "FATE", - "full_name": "Dong-eun Yu", - "date_of_birth": "2001-09-05", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/fate.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 72, - "strength": 70, - "agility": 74, - "passing": 72, - "shooting": 75, - "tackling": 70, - "dribbling": 73, - "defending": 70, - "positioning": 73, - "vision": 73, - "decisions": 74, - "composure": 70, - "aggression": 67, - "teamwork": 70, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 195000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-grizzly-25", - "match_name": "Grizzly", - "full_name": "Seung-hoon Cho", - "date_of_birth": "2006-04-15", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/grizzly.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 71, - "strength": 73, - "agility": 70, - "passing": 69, - "shooting": 70, - "tackling": 73, - "dribbling": 69, - "defending": 77, - "positioning": 70, - "vision": 69, - "decisions": 72, - "composure": 73, - "aggression": 68, - "teamwork": 73, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 62, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 185000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 82, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-pullbae-26", - "match_name": "Pullbae", - "full_name": "Kwang-seok Jang", - "date_of_birth": "2003-08-14", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/pullbae.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 72, - "strength": 69, - "agility": 71, - "passing": 70, - "shooting": 71, - "tackling": 69, - "dribbling": 70, - "defending": 73, - "positioning": 71, - "vision": 70, - "decisions": 73, - "composure": 69, - "aggression": 66, - "teamwork": 69, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 60, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 185000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-rascal-27", - "match_name": "Rascal", - "full_name": "Dong-geon Kim", - "date_of_birth": "1999-06-18", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/rascal.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 75, - "strength": 77, - "agility": 74, - "passing": 73, - "shooting": 74, - "tackling": 77, - "dribbling": 73, - "defending": 81, - "positioning": 74, - "vision": 73, - "decisions": 76, - "composure": 77, - "aggression": 72, - "teamwork": 77, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 82, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 205000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-toland-28", - "match_name": "TolanD", - "full_name": "Yu-seong Park", - "date_of_birth": "2005-11-22", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/toland.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 70, - "strength": 68, - "agility": 71, - "passing": 70, - "shooting": 70, - "tackling": 68, - "dribbling": 67, - "defending": 68, - "positioning": 69, - "vision": 71, - "decisions": 67, - "composure": 68, - "aggression": 65, - "teamwork": 68, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 62, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 175000, - "market_value": 150000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-kobs-29", - "match_name": "Kobs", - "full_name": "Rayan Mahiddine", - "date_of_birth": "2003-10-16", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 69, - "strength": 67, - "agility": 70, - "passing": 69, - "shooting": 69, - "tackling": 67, - "dribbling": 67, - "defending": 67, - "positioning": 70, - "vision": 70, - "decisions": 71, - "composure": 67, - "aggression": 64, - "teamwork": 67, - "leadership": 69, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 85, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 69000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-xkenzuke-30", - "match_name": "xKenzuke", - "full_name": "Serkan Atilgan", - "date_of_birth": "1999-06-17", - "nationality": "TR", - "birth_country": "TR", - "profile_image_url": "https://dpm.lol/esport/players/xkenzuke.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 64, - "strength": 72, - "agility": 69, - "passing": 69, - "shooting": 66, - "tackling": 72, - "dribbling": 65, - "defending": 72, - "positioning": 70, - "vision": 70, - "decisions": 67, - "composure": 66, - "aggression": 66, - "teamwork": 67, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 70, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 78000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 67, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-avra-31", - "match_name": "Avra", - "full_name": "Ilhan Berkant", - "date_of_birth": "2003-06-04", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/e3/TPAA_Avra_2022_Split_1.png/revision/latest/scale-to-width-down/640?cb=20220120181705", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 69, - "strength": 66, - "agility": 70, - "passing": 67, - "shooting": 71, - "tackling": 66, - "dribbling": 69, - "defending": 66, - "positioning": 69, - "vision": 68, - "decisions": 70, - "composure": 66, - "aggression": 64, - "teamwork": 67, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 84, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 78000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-mxe-32", - "match_name": "Mxe", - "full_name": "Aziz Görkem Altinpinar", - "date_of_birth": "2003-01-13", - "nationality": "Turkey", - "birth_country": "Turkey", - "profile_image_url": "https://dpm.lol/esport/players/mxe.webp", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 70, - "strength": 73, - "agility": 70, - "passing": 70, - "shooting": 70, - "tackling": 73, - "dribbling": 68, - "defending": 77, - "positioning": 71, - "vision": 71, - "decisions": 72, - "composure": 73, - "aggression": 67, - "teamwork": 73, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 65, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2027-11-18", - "wage": 60000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 71, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-toffe-49", - "match_name": "Toffe", - "full_name": "Tautvydas Gegeckas", - "date_of_birth": "2005-05-02", - "nationality": "LT", - "birth_country": "LT", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/2/25/MCon_Toffe_2024_Split_2.png/revision/latest/scale-to-width-down/473?cb=20240604114053", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 73, - "strength": 71, - "agility": 75, - "passing": 73, - "shooting": 76, - "tackling": 71, - "dribbling": 73, - "defending": 71, - "positioning": 72, - "vision": 74, - "decisions": 70, - "composure": 71, - "aggression": 68, - "teamwork": 71, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 84, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 82000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-leny-51", - "match_name": "Leny", - "full_name": "Albertini Leny", - "date_of_birth": "2002-12-09", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://dpm.lol/esport/players/leny.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 72, - "strength": 74, - "agility": 71, - "passing": 70, - "shooting": 71, - "tackling": 74, - "dribbling": 70, - "defending": 78, - "positioning": 71, - "vision": 70, - "decisions": 73, - "composure": 74, - "aggression": 69, - "teamwork": 74, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 72, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2027-11-18", - "wage": 67000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-riip-64", - "match_name": "Riip", - "full_name": "Arnaud Mesmin", - "date_of_birth": "1995-09-13", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 66, - "strength": 64, - "agility": 66, - "passing": 66, - "shooting": 66, - "tackling": 64, - "dribbling": 64, - "defending": 68, - "positioning": 67, - "vision": 67, - "decisions": 68, - "composure": 64, - "aggression": 61, - "teamwork": 64, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 76, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 20000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 65, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-steelback-69", - "match_name": "Steelback", - "full_name": "Pierre Medjaldi", - "date_of_birth": "1996-08-16", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "/player-photos/107455908655055017.png", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 67, - "strength": 65, - "agility": 67, - "passing": 67, - "shooting": 67, - "tackling": 65, - "dribbling": 64, - "defending": 69, - "positioning": 66, - "vision": 68, - "decisions": 64, - "composure": 65, - "aggression": 62, - "teamwork": 65, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 76, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2027-11-18", - "wage": 68000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 65, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-oscarinin-76", - "match_name": "Oscarinin", - "full_name": "Óscar Muñoz Jiménez", - "date_of_birth": "2003-6-11", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://dpm.lol/esport/players/oscarinin.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 82, - "strength": 74, - "agility": 80, - "passing": 75, - "shooting": 83, - "tackling": 74, - "dribbling": 84, - "defending": 78, - "positioning": 76, - "vision": 80, - "decisions": 78, - "composure": 85, - "aggression": 71, - "teamwork": 81, - "leadership": 75, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 140000, - "market_value": 200000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 84, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-summit-77", - "match_name": "Summit", - "full_name": "Woo-tae Park", - "date_of_birth": "1998-12-08", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/summit.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 77, - "strength": 74, - "agility": 76, - "passing": 75, - "shooting": 76, - "tackling": 74, - "dribbling": 75, - "defending": 78, - "positioning": 76, - "vision": 75, - "decisions": 78, - "composure": 74, - "aggression": 71, - "teamwork": 74, - "leadership": 75, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 79, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 130000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-bo-78", - "match_name": "Bo", - "full_name": "Zhou Yangbo", - "date_of_birth": "2002-04-22", - "nationality": "CN", - "birth_country": "CN", - "profile_image_url": "https://dpm.lol/esport/players/bo.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 72, - "strength": 75, - "agility": 73, - "passing": 75, - "shooting": 72, - "tackling": 75, - "dribbling": 74, - "defending": 75, - "positioning": 73, - "vision": 73, - "decisions": 74, - "composure": 75, - "aggression": 69, - "teamwork": 75, - "leadership": 77, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 83, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 200000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 83, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-larssen-80", - "match_name": "Larssen", - "full_name": "Emil Larsson", - "date_of_birth": "2000-03-30", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://dpm.lol/esport/players/larssen.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 72, - "strength": 75, - "agility": 74, - "passing": 72, - "shooting": 75, - "tackling": 75, - "dribbling": 73, - "defending": 75, - "positioning": 73, - "vision": 73, - "decisions": 74, - "composure": 75, - "aggression": 69, - "teamwork": 75, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 78, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 210000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-vetheo-81", - "match_name": "Vetheo", - "full_name": "Vincent Berrié", - "date_of_birth": "2002-07-26", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://dpm.lol/esport/players/vetheo.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 69, - "strength": 71, - "agility": 75, - "passing": 73, - "shooting": 80, - "tackling": 71, - "dribbling": 82, - "defending": 71, - "positioning": 74, - "vision": 73, - "decisions": 72, - "composure": 68, - "aggression": 68, - "teamwork": 79, - "leadership": 76, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 78, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 230000, - "market_value": 150000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-nemesis-83", - "match_name": "Nemesis", - "full_name": "Tim Lipovšek", - "date_of_birth": "1999-07-26", - "nationality": "SI", - "birth_country": "SI", - "profile_image_url": "https://dpm.lol/esport/players/nemesis.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 82, - "stamina": 61, - "strength": 78, - "agility": 82, - "passing": 80, - "shooting": 86, - "tackling": 78, - "dribbling": 87, - "defending": 78, - "positioning": 81, - "vision": 80, - "decisions": 84, - "composure": 60, - "aggression": 75, - "teamwork": 85, - "leadership": 85, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 83, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "Playmaker", - "CompleteForward", - "SetPieceSpecialist" - ], - "contract_end": "2026-11-18", - "wage": 270000, - "market_value": 160000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-unforgiven-85", - "match_name": "Unforgiven", - "full_name": "William Nieminen", - "date_of_birth": "2000-08-23", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://dpm.lol/esport/players/unforgiven.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 62, - "strength": 72, - "agility": 68, - "passing": 73, - "shooting": 70, - "tackling": 72, - "dribbling": 70, - "defending": 72, - "positioning": 75, - "vision": 70, - "decisions": 67, - "composure": 64, - "aggression": 70, - "teamwork": 69, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 72, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 115000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 67, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-crownie-86", - "match_name": "Crownie", - "full_name": "Juš Marušič", - "date_of_birth": "1998-04-17", - "nationality": "SI", - "birth_country": "SI", - "profile_image_url": "https://dpm.lol/esport/players/crownie.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 70, - "strength": 72, - "agility": 71, - "passing": 71, - "shooting": 72, - "tackling": 72, - "dribbling": 75, - "defending": 72, - "positioning": 70, - "vision": 69, - "decisions": 71, - "composure": 72, - "aggression": 67, - "teamwork": 73, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 74, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 75000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 71, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-light-87", - "match_name": "Light", - "full_name": "Guang-Yu Wang", - "date_of_birth": "2001-02-21", - "nationality": "CN", - "birth_country": "CN", - "profile_image_url": "https://dpm.lol/esport/players/light.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 81, - "stamina": 80, - "strength": 77, - "agility": 81, - "passing": 78, - "shooting": 82, - "tackling": 77, - "dribbling": 80, - "defending": 77, - "positioning": 80, - "vision": 79, - "decisions": 81, - "composure": 77, - "aggression": 75, - "teamwork": 78, - "leadership": 78, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 205000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-execute-88", - "match_name": "Execute", - "full_name": "Jeong-hoon Lee", - "date_of_birth": "2000-2-22", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/execute.webp", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 72, - "strength": 75, - "agility": 72, - "passing": 72, - "shooting": 72, - "tackling": 75, - "dribbling": 70, - "defending": 79, - "positioning": 73, - "vision": 73, - "decisions": 74, - "composure": 75, - "aggression": 69, - "teamwork": 75, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 76, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 100000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 73, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-thebausffs-89", - "match_name": "Thebausffs", - "full_name": "Simon Hofverberg", - "date_of_birth": "1999-10-03", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://dpm.lol/esport/players/thebausffs.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 59, - "strength": 70, - "agility": 60, - "passing": 71, - "shooting": 80, - "tackling": 70, - "dribbling": 67, - "defending": 74, - "positioning": 70, - "vision": 60, - "decisions": 57, - "composure": 58, - "aggression": 67, - "teamwork": 68, - "leadership": 60, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2025-11-18", - "wage": 90000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 63, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-tyler1-91", - "match_name": "Tyler1", - "full_name": "Tyler Steinkamp", - "date_of_birth": "1995-03-07", - "nationality": "US", - "birth_country": "US", - "profile_image_url": "https://dpm.lol/esport/players/tyler1.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 54, - "stamina": 51, - "strength": 53, - "agility": 52, - "passing": 52, - "shooting": 53, - "tackling": 53, - "dribbling": 56, - "defending": 53, - "positioning": 51, - "vision": 50, - "decisions": 52, - "composure": 53, - "aggression": 48, - "teamwork": 54, - "leadership": 54, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 95, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 45000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 52, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-elmillor-92", - "match_name": "Elmillor", - "full_name": "Anselmo Sanz", - "date_of_birth": "1994-05-03", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/e/e4/G2V_ElmiilloR_2017.png/revision/latest?cb=20200205122931", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 57, - "stamina": 56, - "strength": 59, - "agility": 57, - "passing": 59, - "shooting": 56, - "tackling": 59, - "dribbling": 58, - "defending": 59, - "positioning": 57, - "vision": 57, - "decisions": 58, - "composure": 59, - "aggression": 53, - "teamwork": 59, - "leadership": 61, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 88, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 35000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 60, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-kobbe-94", - "match_name": "Kobbe", - "full_name": "Kasper Kobberup", - "date_of_birth": "1996-09-21", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://dpm.lol/esport/players/kobbe.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 67, - "strength": 75, - "agility": 68, - "passing": 71, - "shooting": 70, - "tackling": 75, - "dribbling": 70, - "defending": 75, - "positioning": 73, - "vision": 72, - "decisions": 67, - "composure": 66, - "aggression": 70, - "teamwork": 72, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 125000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-selfmade-95", - "match_name": "Selfmade", - "full_name": "Oskar Boderek", - "date_of_birth": "1999-12-15", - "nationality": "PL", - "birth_country": "PL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f9/Bask_SelfMadeMan.jpeg/revision/latest?cb=20170728185318", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 63, - "strength": 72, - "agility": 70, - "passing": 74, - "shooting": 84, - "tackling": 72, - "dribbling": 87, - "defending": 72, - "positioning": 73, - "vision": 80, - "decisions": 76, - "composure": 62, - "aggression": 69, - "teamwork": 85, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 84, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 100000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-werlyb-96", - "match_name": "Werlyb", - "full_name": "Jorge Casanovas Moreno-Torres", - "date_of_birth": "1997-08-14", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/1/14/Dragons_Werlyb.jpg/revision/latest?cb=20170801201133", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 68, - "strength": 65, - "agility": 67, - "passing": 66, - "shooting": 67, - "tackling": 65, - "dribbling": 66, - "defending": 69, - "positioning": 67, - "vision": 66, - "decisions": 69, - "composure": 65, - "aggression": 62, - "teamwork": 65, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 85, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 60000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 69, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-broxah-97", - "match_name": "Broxah", - "full_name": "Mads Brock-Pedersen", - "date_of_birth": "1997-08-12", - "nationality": "DK", - "birth_country": "DK", - "profile_image_url": "https://dpm.lol/esport/players/broxah.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 69, - "strength": 72, - "agility": 70, - "passing": 72, - "shooting": 69, - "tackling": 72, - "dribbling": 71, - "defending": 72, - "positioning": 70, - "vision": 70, - "decisions": 71, - "composure": 72, - "aggression": 66, - "teamwork": 72, - "leadership": 74, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 90, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 140000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-forg1ven-99", - "match_name": "FORG1VEN", - "full_name": "Konstantinos-Napoleon Tzortziou", - "date_of_birth": "1992-07-23", - "nationality": "GR", - "birth_country": "GR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/3/38/CW_FORG1VEN.jpg/revision/latest?cb=20170801175148", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 68, - "strength": 65, - "agility": 64, - "passing": 66, - "shooting": 65, - "tackling": 65, - "dribbling": 68, - "defending": 65, - "positioning": 65, - "vision": 67, - "decisions": 64, - "composure": 65, - "aggression": 63, - "teamwork": 66, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 95, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 80000, - "market_value": 50000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 65, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-113-100", - "match_name": "113", - "full_name": "Doğukan Balcı", - "date_of_birth": "2004-08-12", - "nationality": "Turkey", - "birth_country": "Turkey", - "profile_image_url": "https://dpm.lol/esport/players/113.webp", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 65, - "strength": 77, - "agility": 75, - "passing": 77, - "shooting": 80, - "tackling": 77, - "dribbling": 82, - "defending": 77, - "positioning": 75, - "vision": 80, - "decisions": 75, - "composure": 67, - "aggression": 71, - "teamwork": 81, - "leadership": 78, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 77, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 120000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 80, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-slowq-101", - "match_name": "SlowQ", - "full_name": "Ye-bit Seo", - "date_of_birth": "2004-03-20", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/6/66/Z10_SlowQ_2023_Split_1.png/revision/latest/scale-to-width-down/639?cb=20230216192154", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 78, - "stamina": 76, - "strength": 74, - "agility": 78, - "passing": 76, - "shooting": 79, - "tackling": 74, - "dribbling": 77, - "defending": 74, - "positioning": 77, - "vision": 77, - "decisions": 78, - "composure": 74, - "aggression": 71, - "teamwork": 74, - "leadership": 76, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 76, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 130000, - "market_value": 170000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 81, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-hype-102", - "match_name": "Hype", - "full_name": "Jeong-hyeon Byeon", - "date_of_birth": "2003-09-09", - "nationality": "KR", - "birth_country": "KR", - "profile_image_url": "https://dpm.lol/esport/players/hype.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 80, - "stamina": 72, - "strength": 79, - "agility": 70, - "passing": 80, - "shooting": 74, - "tackling": 79, - "dribbling": 75, - "defending": 79, - "positioning": 79, - "vision": 72, - "decisions": 70, - "composure": 73, - "aggression": 77, - "teamwork": 76, - "leadership": 58, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "Playmaker", - "CompleteForward", - "SetPieceSpecialist" - ], - "contract_end": "2026-11-18", - "wage": 155000, - "market_value": 210000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 85, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-stend-103", - "match_name": "Stend", - "full_name": "Paul Lardin", - "date_of_birth": "2001-7-13", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://dpm.lol/esport/players/stend.webp", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 74, - "strength": 76, - "agility": 78, - "passing": 78, - "shooting": 74, - "tackling": 76, - "dribbling": 76, - "defending": 80, - "positioning": 77, - "vision": 75, - "decisions": 71, - "composure": 73, - "aggression": 73, - "teamwork": 71, - "leadership": 76, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 140000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-hiro-106", - "match_name": "Hiro", - "full_name": "Alexendre El Hodebey", - "date_of_birth": "2002-06-23", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/fb/Hiro.jpeg/revision/latest/scale-to-width-down/640?cb=20180925054152", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 65, - "strength": 67, - "agility": 64, - "passing": 65, - "shooting": 64, - "tackling": 67, - "dribbling": 68, - "defending": 71, - "positioning": 64, - "vision": 63, - "decisions": 66, - "composure": 67, - "aggression": 62, - "teamwork": 67, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 84, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 40000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-jackspektra-107", - "match_name": "Jackspektra", - "full_name": "Jakob Gullvåg Kepple", - "date_of_birth": "2000-12-05", - "nationality": "NO", - "birth_country": "NO", - "profile_image_url": "https://dpm.lol/esport/players/jackspektra.webp", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 72, - "strength": 69, - "agility": 73, - "passing": 70, - "shooting": 74, - "tackling": 69, - "dribbling": 72, - "defending": 69, - "positioning": 72, - "vision": 71, - "decisions": 73, - "composure": 69, - "aggression": 67, - "teamwork": 70, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 70, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 90000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 71, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-samux-109", - "match_name": "Samux", - "full_name": "Samuel Fernández Fort", - "date_of_birth": "1995-06-11", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/f/f0/Giants_Samux.jpg/revision/latest?cb=20170801231800", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 70, - "strength": 67, - "agility": 66, - "passing": 68, - "shooting": 67, - "tackling": 67, - "dribbling": 70, - "defending": 67, - "positioning": 67, - "vision": 69, - "decisions": 66, - "composure": 67, - "aggression": 65, - "teamwork": 68, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 76, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 75000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 67, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-random-112", - "match_name": "Random", - "full_name": "Adam Grepl", - "date_of_birth": "2001-12-30", - "nationality": "CZ", - "birth_country": "CZ", - "profile_image_url": "https://dpm.lol/esport/players/random.webp", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 68, - "strength": 66, - "agility": 70, - "passing": 68, - "shooting": 71, - "tackling": 66, - "dribbling": 69, - "defending": 66, - "positioning": 69, - "vision": 69, - "decisions": 70, - "composure": 66, - "aggression": 63, - "teamwork": 66, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 75, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 80000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-hadess-114", - "match_name": "Hadess", - "full_name": "Maik Jonker", - "date_of_birth": "1999-07-22", - "nationality": "NL", - "birth_country": "NL", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/2/2f/Hades_2018.jpg/revision/latest?cb=20190211212032", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 72, - "strength": 70, - "agility": 73, - "passing": 72, - "shooting": 72, - "tackling": 70, - "dribbling": 69, - "defending": 70, - "positioning": 71, - "vision": 73, - "decisions": 69, - "composure": 70, - "aggression": 67, - "teamwork": 70, - "leadership": 72, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 78, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 90000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-send0o-115", - "match_name": "Send0o", - "full_name": "Rosendo Fuentes", - "date_of_birth": "1996-07-12", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://dpm.lol/esport/players/send0o.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 65, - "stamina": 67, - "strength": 69, - "agility": 66, - "passing": 65, - "shooting": 66, - "tackling": 69, - "dribbling": 65, - "defending": 73, - "positioning": 66, - "vision": 65, - "decisions": 68, - "composure": 69, - "aggression": 64, - "teamwork": 69, - "leadership": 65, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 65, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 70000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-marky-116", - "match_name": "Marky", - "full_name": "Pedro José Serrano", - "date_of_birth": "2002-9-23", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://dpm.lol/esport/players/marky.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 64, - "stamina": 68, - "strength": 65, - "agility": 62, - "passing": 66, - "shooting": 62, - "tackling": 65, - "dribbling": 66, - "defending": 69, - "positioning": 65, - "vision": 66, - "decisions": 64, - "composure": 65, - "aggression": 62, - "teamwork": 65, - "leadership": 66, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 60, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 60000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-baca-117", - "match_name": "Baca", - "full_name": "João Miguel Novais Bigas", - "date_of_birth": "2000-5-11", - "nationality": "PT", - "birth_country": "PT", - "profile_image_url": "https://dpm.lol/esport/players/baca.webp", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 70, - "strength": 67, - "agility": 69, - "passing": 68, - "shooting": 69, - "tackling": 67, - "dribbling": 68, - "defending": 71, - "positioning": 69, - "vision": 68, - "decisions": 71, - "composure": 67, - "aggression": 64, - "teamwork": 67, - "leadership": 68, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 75, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 80000, - "market_value": 80000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 70, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-rhuckz-119", - "match_name": "Rhuckz", - "full_name": "Rúben Barbosa", - "date_of_birth": "1996-8-28", - "nationality": "PT", - "birth_country": "PT", - "profile_image_url": "https://dpm.lol/esport/players/rhuckz.webp", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 69, - "stamina": 73, - "strength": 71, - "agility": 68, - "passing": 73, - "shooting": 68, - "tackling": 71, - "dribbling": 70, - "defending": 75, - "positioning": 72, - "vision": 74, - "decisions": 70, - "composure": 71, - "aggression": 68, - "teamwork": 71, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 72, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 85000, - "market_value": 100000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-kasing-120", - "match_name": "Kasing", - "full_name": "Raymond Tsang", - "date_of_birth": "1993-12-08", - "nationality": "GB", - "birth_country": null, - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/a/ac/H2k-kasing-2015spring.jpg/revision/latest?cb=20170801234730", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 68, - "stamina": 70, - "strength": 68, - "agility": 70, - "passing": 70, - "shooting": 70, - "tackling": 68, - "dribbling": 67, - "defending": 72, - "positioning": 69, - "vision": 71, - "decisions": 67, - "composure": 68, - "aggression": 65, - "teamwork": 68, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 80, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 85000, - "market_value": 60000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 68, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-homi-121", - "match_name": "Homi", - "full_name": "Adrián Moldes López", - "date_of_birth": "1993-05-30", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/d7/Homi-summa-1.jpg/revision/latest?cb=20170802002458", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 63, - "stamina": 62, - "strength": 65, - "agility": 62, - "passing": 65, - "shooting": 62, - "tackling": 65, - "dribbling": 65, - "defending": 69, - "positioning": 63, - "vision": 63, - "decisions": 64, - "composure": 65, - "aggression": 59, - "teamwork": 65, - "leadership": 67, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 58, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 55000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-skain-123", - "match_name": "Skain", - "full_name": "David Carbó Ferrer", - "date_of_birth": "1997-03-10", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/0/08/Skain_g2v.jpeg/revision/latest?cb=20170802132525", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 66, - "stamina": 65, - "strength": 68, - "agility": 65, - "passing": 68, - "shooting": 65, - "tackling": 68, - "dribbling": 68, - "defending": 72, - "positioning": 66, - "vision": 66, - "decisions": 67, - "composure": 68, - "aggression": 62, - "teamwork": 68, - "leadership": 70, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 62, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 70000, - "market_value": 70000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 69, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-zeniv-124", - "match_name": "Zeniv", - "full_name": "Mina", - "date_of_birth": "2000-02-18", - "nationality": "DE", - "birth_country": "DE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/7/7c/G2H_Zeniv_2025.png/revision/latest/scale-to-width-down/220?cb=20250216161450", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 76, - "strength": 73, - "agility": 75, - "passing": 74, - "shooting": 75, - "tackling": 73, - "dribbling": 74, - "defending": 77, - "positioning": 75, - "vision": 74, - "decisions": 77, - "composure": 73, - "aggression": 70, - "teamwork": 73, - "leadership": 74, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 71, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 165000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 77, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-shiina-125", - "match_name": "Shiina", - "full_name": "Marta Mesas Garrido", - "date_of_birth": "2001-10-26", - "nationality": "ES", - "birth_country": "ES", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/5/57/G2H_Shiina_2025.png/revision/latest/scale-to-width-down/220?cb=20250216161452", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 74, - "strength": 72, - "agility": 75, - "passing": 74, - "shooting": 74, - "tackling": 72, - "dribbling": 72, - "defending": 72, - "positioning": 75, - "vision": 75, - "decisions": 76, - "composure": 72, - "aggression": 69, - "teamwork": 72, - "leadership": 74, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 70, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 156000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-rym-126", - "match_name": "Rym", - "full_name": "Rym Salloum", - "date_of_birth": "2002-01-01", - "nationality": "VE", - "birth_country": "VE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/1/18/G2H_rym_2025.png/revision/latest/scale-to-width-down/220?cb=20250216161453", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 74, - "stamina": 70, - "strength": 73, - "agility": 72, - "passing": 73, - "shooting": 73, - "tackling": 73, - "dribbling": 76, - "defending": 73, - "positioning": 71, - "vision": 71, - "decisions": 72, - "composure": 73, - "aggression": 67, - "teamwork": 73, - "leadership": 75, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 148000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-caltys-127", - "match_name": "Caltys", - "full_name": "Maya Henckel", - "date_of_birth": "2002-05-11", - "nationality": "SE", - "birth_country": "SE", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/b/b8/G2H_Caltys_2025.png/revision/latest/scale-to-width-down/220?cb=20250216161457", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 76, - "stamina": 75, - "strength": 72, - "agility": 76, - "passing": 73, - "shooting": 77, - "tackling": 72, - "dribbling": 75, - "defending": 72, - "positioning": 75, - "vision": 74, - "decisions": 76, - "composure": 72, - "aggression": 70, - "teamwork": 73, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 72, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [ - "CompleteForward" - ], - "contract_end": "2026-11-18", - "wage": 171000, - "market_value": 140000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 78, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-colomblbl-128", - "match_name": "Colomblbl", - "full_name": "Ève Monvoisin", - "date_of_birth": "2002-01-01", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/cc/G2H_Colomblbl_2025.png/revision/latest/scale-to-width-down/220?cb=20250216161456", - "position": "DefensiveMidfielder", - "natural_position": "DefensiveMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 70, - "stamina": 71, - "strength": 74, - "agility": 71, - "passing": 71, - "shooting": 71, - "tackling": 74, - "dribbling": 69, - "defending": 78, - "positioning": 72, - "vision": 72, - "decisions": 73, - "composure": 74, - "aggression": 68, - "teamwork": 74, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 64 - }, - "condition": 100, - "morale": 67, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 142000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-starrie-129", - "match_name": "Starrie", - "full_name": "Ivy Starr", - "date_of_birth": "2002-06-26", - "nationality": "US", - "birth_country": "US", - "profile_image_url": "https://i.imgur.com/6pwxTZx.png", - "position": "Defender", - "natural_position": "Defender", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 73, - "stamina": 75, - "strength": 72, - "agility": 74, - "passing": 73, - "shooting": 74, - "tackling": 72, - "dribbling": 72, - "defending": 76, - "positioning": 72, - "vision": 73, - "decisions": 71, - "composure": 72, - "aggression": 69, - "teamwork": 72, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 68 - }, - "condition": 100, - "morale": 68, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 150000, - "market_value": 120000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 75, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-delicate-130", - "match_name": "Delicate", - "full_name": "Chara Giannopoulou", - "date_of_birth": "2002-01-01", - "nationality": "GR", - "birth_country": "GR", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/d/da/Delicate_2025.jpg/revision/latest/scale-to-width-down/220?cb=20251201143054", - "position": "Midfielder", - "natural_position": "Midfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 73, - "strength": 71, - "agility": 74, - "passing": 73, - "shooting": 73, - "tackling": 71, - "dribbling": 70, - "defending": 71, - "positioning": 72, - "vision": 74, - "decisions": 70, - "composure": 71, - "aggression": 68, - "teamwork": 71, - "leadership": 73, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 67, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 145000, - "market_value": 110000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 74, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-sashy-131", - "match_name": "Sashy", - "full_name": "Sasha Barrault", - "date_of_birth": "2002-05-27", - "nationality": "FR", - "birth_country": "FR", - "profile_image_url": "https://liquipedia.net/commons/images/thumb/7/73/ET_Sashy_LGC_Rising_2025.jpg/600px-ET_Sashy_LGC_Rising_2025.jpg", - "position": "AttackingMidfielder", - "natural_position": "AttackingMidfielder", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 75, - "stamina": 74, - "strength": 72, - "agility": 76, - "passing": 74, - "shooting": 77, - "tackling": 72, - "dribbling": 74, - "defending": 72, - "positioning": 73, - "vision": 75, - "decisions": 71, - "composure": 72, - "aggression": 69, - "teamwork": 72, - "leadership": 74, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 70, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 158000, - "market_value": 130000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 76, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - }, - { - "id": "lec-fa-sea-132", - "match_name": "Sea", - "full_name": "Nova Jenčáková", - "date_of_birth": "1998-11-21", - "nationality": "SK", - "birth_country": "SK", - "profile_image_url": "https://static.wikia.nocookie.net/lolesports_gamepedia_en/images/c/c2/SNC_Sea_2025.jpg/revision/latest/scale-to-width-down/220?cb=20250830143850", - "position": "Forward", - "natural_position": "Forward", - "alternate_positions": [], - "footedness": "Right", - "weak_foot": 2, - "attributes": { - "pace": 71, - "stamina": 73, - "strength": 70, - "agility": 69, - "passing": 71, - "shooting": 70, - "tackling": 70, - "dribbling": 73, - "defending": 70, - "positioning": 70, - "vision": 72, - "decisions": 69, - "composure": 70, - "aggression": 68, - "teamwork": 71, - "leadership": 71, - "handling": 20, - "reflexes": 22, - "aerial": 52 - }, - "condition": 100, - "morale": 66, - "fitness": 75, - "injury": null, - "team_id": null, - "traits": [], - "contract_end": "2026-11-18", - "wage": 138000, - "market_value": 90000, - "stats": { - "appearances": 0, - "goals": 0, - "assists": 0, - "clean_sheets": 0, - "yellow_cards": 0, - "red_cards": 0, - "avg_rating": 0.0, - "minutes_played": 0, - "shots": 0, - "shots_on_target": 0, - "passes_completed": 0, - "passes_attempted": 0, - "tackles_won": 0, - "interceptions": 0, - "fouls_committed": 0 - }, - "career": [], - "training_focus": null, - "transfer_listed": true, - "loan_listed": false, - "transfer_offers": [], - "morale_core": { - "manager_trust": 50, - "unresolved_issue": null, - "recent_treatment": null, - "pending_promise": null, - "talk_cooldown_until": null, - "renewal_state": null - }, - "potential_base": 72, - "potential_revealed": null, - "potential_research_started_on": null, - "potential_research_eta_days": null, - "champion_training_target": null, - "champion_training_targets": [] - } - ], - "staff": [ - { - "id": "lec-fnatic-staff-0", - "first_name": "FNC", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-fnatic", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-fnatic-staff-1", - "first_name": "FNC", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-fnatic", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-fnatic-staff-2", - "first_name": "FNC", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-fnatic", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-fnatic-staff-3", - "first_name": "FNC", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-fnatic", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-g2-esports-staff-0", - "first_name": "G2", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-g2-esports", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-g2-esports-staff-1", - "first_name": "G2", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-g2-esports", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-g2-esports-staff-2", - "first_name": "G2", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-g2-esports", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-g2-esports-staff-3", - "first_name": "G2", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-g2-esports", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-giantx-lec-staff-0", - "first_name": "GX", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-giantx-lec", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-giantx-lec-staff-1", - "first_name": "GX", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-giantx-lec", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-giantx-lec-staff-2", - "first_name": "GX", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-giantx-lec", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-giantx-lec-staff-3", - "first_name": "GX", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-giantx-lec", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-karmine-corp-staff-0", - "first_name": "KC", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-karmine-corp", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-karmine-corp-staff-1", - "first_name": "KC", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-karmine-corp", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-karmine-corp-staff-2", - "first_name": "KC", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-karmine-corp", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-karmine-corp-staff-3", - "first_name": "KC", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-karmine-corp", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-mad-lions-staff-0", - "first_name": "MKOI", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-mad-lions", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-mad-lions-staff-1", - "first_name": "MKOI", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-mad-lions", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-mad-lions-staff-2", - "first_name": "MKOI", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-mad-lions", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-mad-lions-staff-3", - "first_name": "MKOI", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-mad-lions", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-natus-vincere-staff-0", - "first_name": "NAVI", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-natus-vincere", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-natus-vincere-staff-1", - "first_name": "NAVI", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-natus-vincere", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-natus-vincere-staff-2", - "first_name": "NAVI", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-natus-vincere", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-natus-vincere-staff-3", - "first_name": "NAVI", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-natus-vincere", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-shifters-staff-0", - "first_name": "SFT", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-shifters", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-shifters-staff-1", - "first_name": "SFT", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-shifters", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-shifters-staff-2", - "first_name": "SFT", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-shifters", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-shifters-staff-3", - "first_name": "SFT", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-shifters", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-sk-gaming-staff-0", - "first_name": "SK", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-sk-gaming", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-sk-gaming-staff-1", - "first_name": "SK", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-sk-gaming", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-sk-gaming-staff-2", - "first_name": "SK", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-sk-gaming", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-sk-gaming-staff-3", - "first_name": "SK", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-sk-gaming", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-heretics-lec-staff-0", - "first_name": "TH", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-team-heretics-lec", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-heretics-lec-staff-1", - "first_name": "TH", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-team-heretics-lec", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-heretics-lec-staff-2", - "first_name": "TH", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-team-heretics-lec", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-heretics-lec-staff-3", - "first_name": "TH", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-team-heretics-lec", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-vitality-staff-0", - "first_name": "VIT", - "last_name": "Staff 1", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "AssistantManager", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-team-vitality", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-vitality-staff-1", - "first_name": "VIT", - "last_name": "Staff 2", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Coach", - "attributes": { - "coaching": 78, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 52 - }, - "team_id": "lec-team-vitality", - "specialization": "Tactics", - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-vitality-staff-2", - "first_name": "VIT", - "last_name": "Staff 3", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Scout", - "attributes": { - "coaching": 66, - "judging_ability": 77, - "judging_potential": 76, - "physiotherapy": 52 - }, - "team_id": "lec-team-vitality", - "specialization": null, - "wage": 18000, - "contract_end": null - }, - { - "id": "lec-team-vitality-staff-3", - "first_name": "VIT", - "last_name": "Staff 4", - "date_of_birth": "1988-01-01", - "nationality": "EUN", - "birth_country": "EUN", - "profile_image_url": null, - "role": "Physio", - "attributes": { - "coaching": 66, - "judging_ability": 62, - "judging_potential": 62, - "physiotherapy": 79 - }, - "team_id": "lec-team-vitality", - "specialization": null, - "wage": 18000, - "contract_end": null - } - ] -} \ No newline at end of file diff --git a/src-tauri/databases/world.json b/src-tauri/databases/world.json new file mode 100644 index 000000000..5788193aa --- /dev/null +++ b/src-tauri/databases/world.json @@ -0,0 +1,3598 @@ +{ + "name": "LEC 2026", + "description": "Mundo predefinido de League of Legends (LEC) para OpenFootManager adaptado.", + "teams": [ + { + "id": "lec-fnatic", + "name": "Fnatic", + "short_name": "FNC", + "logo_url": "/teams-icons/fnatic.webp", + "country": "GB", + "city": "London", + "stadium_name": "Fnatic Arena", + "stadium_capacity": 28000, + "finance": 1500000, + "manager_id": null, + "reputation": 650, + "wage_budget": 1300000, + "transfer_budget": 200000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-g2-esports", + "name": "G2 Esports", + "short_name": "G2", + "logo_url": "/teams-icons/g2-esports.webp", + "country": "DE", + "city": "Berlin", + "stadium_name": "G2 Esports Arena", + "stadium_capacity": 28000, + "finance": 1900000, + "manager_id": null, + "reputation": 350, + "wage_budget": 1600000, + "transfer_budget": 300000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-giantx-lec", + "name": "GIANTX", + "short_name": "GX", + "logo_url": "/teams-icons/giantx-lec.webp", + "country": "ES", + "city": "Málaga", + "stadium_name": "GIANTX Arena", + "stadium_capacity": 28000, + "finance": 1250000, + "manager_id": null, + "reputation": 500, + "wage_budget": 1100000, + "transfer_budget": 150000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-karmine-corp", + "name": "Karmine Corp", + "short_name": "KC", + "logo_url": "/teams-icons/karmine-corp.webp", + "country": "FR", + "city": "Paris", + "stadium_name": "Karmine Corp Arena", + "stadium_capacity": 28000, + "finance": 1800000, + "manager_id": null, + "reputation": 350, + "wage_budget": 1600000, + "transfer_budget": 200000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-movistar-koi", + "name": "Movistar KOI", + "short_name": "MKOI", + "logo_url": "/teams-icons/movistar-koi.webp", + "country": "EUN", + "city": "Berlin", + "stadium_name": "Movistar KOI Arena", + "stadium_capacity": 28000, + "finance": 1700000, + "manager_id": null, + "reputation": 500, + "wage_budget": 1400000, + "transfer_budget": 300000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-natus-vincere", + "name": "Natus Vincere", + "short_name": "NAVI", + "logo_url": "/teams-icons/natus-vincere.webp", + "country": "UA", + "city": "Kyiv", + "stadium_name": "Natus Vincere Arena", + "stadium_capacity": 28000, + "finance": 1550000, + "manager_id": null, + "reputation": 500, + "wage_budget": 1300000, + "transfer_budget": 250000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-shifters", + "name": "Shifters", + "short_name": "shft", + "logo_url": "/teams-icons/shifters.webp", + "country": "EUN", + "city": "Berlin", + "stadium_name": "Shifters Arena", + "stadium_capacity": 28000, + "finance": 1200000, + "manager_id": null, + "reputation": 500, + "wage_budget": 1000000, + "transfer_budget": 200000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-sk-gaming", + "name": "SK Gaming", + "short_name": "SK", + "logo_url": "/teams-icons/sk-gaming.webp", + "country": "DE", + "city": "Berlin", + "stadium_name": "SK Gaming Arena", + "stadium_capacity": 28000, + "finance": 1200000, + "manager_id": null, + "reputation": 650, + "wage_budget": 1000000, + "transfer_budget": 200000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-team-heretics-lec", + "name": "Team Heretics", + "short_name": "TH", + "logo_url": "/teams-icons/team-heretics-lec.webp", + "country": "ES", + "city": "Madrid", + "stadium_name": "Team Heretics Arena", + "stadium_capacity": 28000, + "finance": 1050000, + "manager_id": null, + "reputation": 650, + "wage_budget": 900000, + "transfer_budget": 150000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + }, + { + "id": "lec-team-vitality", + "name": "Team Vitality", + "short_name": "VIT", + "logo_url": "/teams-icons/team-vitality.webp", + "country": "FR", + "city": "Paris", + "stadium_name": "Team Vitality Arena", + "stadium_capacity": 28000, + "finance": 1550000, + "manager_id": null, + "reputation": 500, + "wage_budget": 1300000, + "transfer_budget": 250000, + "season_income": 0, + "season_expenses": 0, + "financial_ledger": [], + "sponsorship": null, + "facilities": { + "training": 2, + "medical": 2, + "scouting": 2 + }, + "formation": "4-4-2", + "play_style": "Balanced", + "training_focus": "Tactical", + "training_intensity": "Medium", + "training_schedule": "Balanced", + "founded_year": 2015, + "colors": { + "primary": "#1f2937", + "secondary": "#f3f4f6" + }, + "training_groups": [], + "starting_xi_ids": [], + "team_roles": { + "captain": null, + "shotcaller": null + }, + "form": [], + "history": [] + } + ], + "players": [ + { + "id": "lec-player-109705412728201213", + "match_name": "Empyros", + "full_name": "Panagiotis Tantis", + "date_of_birth": "2004-04-01", + "nationality": "GR", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 71, + "laning": 73, + "teamfighting": 69, + "macro_play": 56, + "consistency": 68, + "shotcalling": 58, + "champion_pool": 65, + "discipline": 54, + "mental_resilience": 67 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-fnatic", + "traits": [], + "contract_end": null, + "wage": 185000, + "market_value": 630000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-100238780551262852", + "match_name": "Razork", + "full_name": "Ivan Diaz", + "date_of_birth": "2000-10-07", + "nationality": "ES", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-fnatic", + "traits": [], + "contract_end": null, + "wage": 245000, + "market_value": 350000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107045034481599547", + "match_name": "Vladi", + "full_name": "Vladimiros Kourtidis", + "date_of_birth": "2005-08-12", + "nationality": "GR", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-fnatic", + "traits": [], + "contract_end": null, + "wage": 220000, + "market_value": 670000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-99322214653265200", + "match_name": "Upset", + "full_name": "Elias Lipp", + "date_of_birth": "1999-12-16", + "nationality": "DE", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 77, + "laning": 79, + "teamfighting": 75, + "macro_play": 62, + "consistency": 74, + "shotcalling": 64, + "champion_pool": 71, + "discipline": 60, + "mental_resilience": 73 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-fnatic", + "traits": [], + "contract_end": null, + "wage": 260000, + "market_value": 225000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107492067202132417", + "match_name": "Lospa", + "full_name": "Park Joon-hyeong", + "date_of_birth": "2002-09-30", + "nationality": "KR", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 70, + "laning": 72, + "teamfighting": 68, + "macro_play": 55, + "consistency": 67, + "shotcalling": 57, + "champion_pool": 64, + "discipline": 53, + "mental_resilience": 66 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-fnatic", + "traits": [], + "contract_end": null, + "wage": 200000, + "market_value": 480000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-99566406047571736", + "match_name": "BrokenBlade", + "full_name": "Sergen Celik", + "date_of_birth": "2000-01-19", + "nationality": "DE", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 77, + "laning": 79, + "teamfighting": 75, + "macro_play": 62, + "consistency": 74, + "shotcalling": 64, + "champion_pool": 71, + "discipline": 60, + "mental_resilience": 73 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-g2-esports", + "traits": [], + "contract_end": null, + "wage": 255000, + "market_value": 225000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107128052280762804", + "match_name": "SkewMond", + "full_name": "Rudy Semaan", + "date_of_birth": "2004-08-09", + "nationality": "FR", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 80, + "laning": 82, + "teamfighting": 78, + "macro_play": 65, + "consistency": 77, + "shotcalling": 67, + "champion_pool": 74, + "discipline": 63, + "mental_resilience": 76 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-g2-esports", + "traits": [], + "contract_end": null, + "wage": 195000, + "market_value": 670000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-98767975968177297", + "match_name": "Caps", + "full_name": "Rasmus Borregaard Winther", + "date_of_birth": "1999-11-17", + "nationality": "DK", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 80, + "laning": 82, + "teamfighting": 78, + "macro_play": 65, + "consistency": 77, + "shotcalling": 67, + "champion_pool": 74, + "discipline": 63, + "mental_resilience": 76 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-g2-esports", + "traits": [], + "contract_end": null, + "wage": 295000, + "market_value": 255000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-98767975961872793", + "match_name": "Hans Sama", + "full_name": "Steven Liv", + "date_of_birth": "1999-09-02", + "nationality": "FR", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 79, + "laning": 81, + "teamfighting": 77, + "macro_play": 64, + "consistency": 76, + "shotcalling": 66, + "champion_pool": 73, + "discipline": 62, + "mental_resilience": 75 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-g2-esports", + "traits": [], + "contract_end": null, + "wage": 260000, + "market_value": 240000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-102787200059605684", + "match_name": "Labrov", + "full_name": "Labros Papoutsakis", + "date_of_birth": "2002-02-12", + "nationality": "GR", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 77, + "laning": 79, + "teamfighting": 75, + "macro_play": 62, + "consistency": 74, + "shotcalling": 64, + "champion_pool": 71, + "discipline": 60, + "mental_resilience": 73 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-g2-esports", + "traits": [], + "contract_end": null, + "wage": 235000, + "market_value": 390000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-103495716738607011", + "match_name": "Lot", + "full_name": "Eren Yildiz", + "date_of_birth": "2004-01-02", + "nationality": "TR", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-giantx-lec", + "traits": [], + "contract_end": null, + "wage": 175000, + "market_value": 525000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107464179845128878", + "match_name": "Isma", + "full_name": "IsmaÏl Boualem", + "date_of_birth": "2001-06-20", + "nationality": "FR", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-giantx-lec", + "traits": [], + "contract_end": null, + "wage": 195000, + "market_value": 425000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105647947016264573", + "match_name": "Jackies", + "full_name": "Adam Jeřábek", + "date_of_birth": "2004-10-06", + "nationality": "CZ", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-giantx-lec", + "traits": [], + "contract_end": null, + "wage": 235000, + "market_value": 525000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105501717406803640", + "match_name": "Noah", + "full_name": "Hyeon-Taek Oh", + "date_of_birth": "2001-10-04", + "nationality": "KR", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-giantx-lec", + "traits": [], + "contract_end": null, + "wage": 195000, + "market_value": 375000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105501802535116331", + "match_name": "Jun", + "full_name": "Sejun Yoon", + "date_of_birth": "2000-08-02", + "nationality": "KR", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-giantx-lec", + "traits": [], + "contract_end": null, + "wage": 195000, + "market_value": 355000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-103495716771322725", + "match_name": "Canna", + "full_name": "Changdong Kim", + "date_of_birth": "2000-02-11", + "nationality": "KR", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 79, + "laning": 81, + "teamfighting": 77, + "macro_play": 64, + "consistency": 76, + "shotcalling": 66, + "champion_pool": 73, + "discipline": 62, + "mental_resilience": 75 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-karmine-corp", + "traits": [], + "contract_end": null, + "wage": 255000, + "market_value": 295000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105537190986692036", + "match_name": "Yike", + "full_name": "Martin Emrik Sundelin", + "date_of_birth": "2000-11-11", + "nationality": "SE", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 79, + "laning": 81, + "teamfighting": 77, + "macro_play": 64, + "consistency": 76, + "shotcalling": 66, + "champion_pool": 73, + "discipline": 62, + "mental_resilience": 75 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-karmine-corp", + "traits": [], + "contract_end": null, + "wage": 245000, + "market_value": 320000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-108205130709313212", + "match_name": "kyeahoo", + "full_name": "Yeahoo Kang", + "date_of_birth": "2005-08-13", + "nationality": "KR", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-karmine-corp", + "traits": [], + "contract_end": null, + "wage": 200000, + "market_value": 765000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-109461265532592848", + "match_name": "Caliste", + "full_name": "Caliste Henry-Hennebert", + "date_of_birth": "2006-08-28", + "nationality": "FR", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 78, + "laning": 80, + "teamfighting": 76, + "macro_play": 63, + "consistency": 75, + "shotcalling": 65, + "champion_pool": 72, + "discipline": 61, + "mental_resilience": 74 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-karmine-corp", + "traits": [], + "contract_end": null, + "wage": 195000, + "market_value": 855000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-106625308523122120", + "match_name": "Busio", + "full_name": "Alan Cwalina", + "date_of_birth": "2003-10-22", + "nationality": "PL", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 77, + "laning": 79, + "teamfighting": 75, + "macro_play": 62, + "consistency": 74, + "shotcalling": 64, + "champion_pool": 71, + "discipline": 60, + "mental_resilience": 73 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-karmine-corp", + "traits": [], + "contract_end": null, + "wage": 195000, + "market_value": 640000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-110350224593953686", + "match_name": "Myrwn", + "full_name": "Alex Pastor Villarejo", + "date_of_birth": "2003-06-13", + "nationality": "ES", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-movistar-koi", + "traits": [], + "contract_end": null, + "wage": 235000, + "market_value": 470000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-103877629120745120", + "match_name": "Elyoya", + "full_name": "Javier Prades Batalla", + "date_of_birth": "2000-03-13", + "nationality": "ES", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 78, + "laning": 80, + "teamfighting": 76, + "macro_play": 63, + "consistency": 75, + "shotcalling": 65, + "champion_pool": 72, + "discipline": 61, + "mental_resilience": 74 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-movistar-koi", + "traits": [], + "contract_end": null, + "wage": 260000, + "market_value": 235000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105504920899018806", + "match_name": "Jojopyun", + "full_name": "Joseph Joon Pyun", + "date_of_birth": "2004-10-01", + "nationality": "CA", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 77, + "laning": 79, + "teamfighting": 75, + "macro_play": 62, + "consistency": 74, + "shotcalling": 64, + "champion_pool": 71, + "discipline": 60, + "mental_resilience": 73 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-movistar-koi", + "traits": [], + "contract_end": null, + "wage": 260000, + "market_value": 570000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-103536968833612789", + "match_name": "Supa", + "full_name": "David Martinez Garcia", + "date_of_birth": "2000-10-23", + "nationality": "ES", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-movistar-koi", + "traits": [], + "contract_end": null, + "wage": 235000, + "market_value": 350000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107564404490889053", + "match_name": "Alvaro", + "full_name": "Alvaro Fernandez del Amo", + "date_of_birth": "2003-07-15", + "nationality": "ES", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 77, + "laning": 79, + "teamfighting": 75, + "macro_play": 62, + "consistency": 74, + "shotcalling": 64, + "champion_pool": 71, + "discipline": 60, + "mental_resilience": 73 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-movistar-koi", + "traits": [], + "contract_end": null, + "wage": 170000, + "market_value": 560000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105700869624784693", + "match_name": "Maynter", + "full_name": "Volodymyr Sorokin", + "date_of_birth": "2000-12-15", + "nationality": "UA", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 72, + "laning": 74, + "teamfighting": 70, + "macro_play": 57, + "consistency": 69, + "shotcalling": 59, + "champion_pool": 66, + "discipline": 55, + "mental_resilience": 68 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-natus-vincere", + "traits": [], + "contract_end": null, + "wage": 180000, + "market_value": 315000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105548731617719496", + "match_name": "Rhilech", + "full_name": "Ucan Enes", + "date_of_birth": "2005-10-15", + "nationality": "TR", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-natus-vincere", + "traits": [], + "contract_end": null, + "wage": 180000, + "market_value": 970000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107840393299826151", + "match_name": "Poby", + "full_name": "Sungwon Yun", + "date_of_birth": "2006-02-07", + "nationality": "KR", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-natus-vincere", + "traits": [], + "contract_end": null, + "wage": 190000, + "market_value": 750000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-104287359934240404", + "match_name": "SamD", + "full_name": "Jaehoon Lee", + "date_of_birth": "2001-03-14", + "nationality": "KR", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-natus-vincere", + "traits": [], + "contract_end": null, + "wage": 220000, + "market_value": 355000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-103805069759346933", + "match_name": "Parus", + "full_name": "Polat Furkan Çiçek", + "date_of_birth": "2003-02-22", + "nationality": "TR", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-natus-vincere", + "traits": [], + "contract_end": null, + "wage": 210000, + "market_value": 595000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107767810249714879", + "match_name": "Rooster", + "full_name": "Yunhwan Shin", + "date_of_birth": "2005-04-28", + "nationality": "KR", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-shifters", + "traits": [], + "contract_end": null, + "wage": 180000, + "market_value": 820000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105515296576479523", + "match_name": "Boukada", + "full_name": "Mehdi Lahlou", + "date_of_birth": "2002-10-01", + "nationality": "FR", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 69, + "laning": 71, + "teamfighting": 67, + "macro_play": 54, + "consistency": 66, + "shotcalling": 56, + "champion_pool": 63, + "discipline": 52, + "mental_resilience": 65 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-shifters", + "traits": [], + "contract_end": null, + "wage": 210000, + "market_value": 335000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105554437688383476", + "match_name": "nuc", + "full_name": "Ilias Bizriken", + "date_of_birth": "2002-10-17", + "nationality": "FR", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-shifters", + "traits": [], + "contract_end": null, + "wage": 175000, + "market_value": 465000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107492114500277895", + "match_name": "Paduck", + "full_name": "Seokhyeon Park", + "date_of_birth": "2005-02-12", + "nationality": "KR", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-shifters", + "traits": [], + "contract_end": null, + "wage": 230000, + "market_value": 740000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-102181528883745160", + "match_name": "Trymbi", + "full_name": "Adrian Trybus", + "date_of_birth": "2000-10-20", + "nationality": "PL", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 71, + "laning": 73, + "teamfighting": 69, + "macro_play": 56, + "consistency": 68, + "shotcalling": 58, + "champion_pool": 65, + "discipline": 54, + "mental_resilience": 67 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-shifters", + "traits": [], + "contract_end": null, + "wage": 215000, + "market_value": 185000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-99322214618656216", + "match_name": "Wunder", + "full_name": "Martin Nordahl Hansen", + "date_of_birth": "1998-11-09", + "nationality": "DK", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-sk-gaming", + "traits": [], + "contract_end": null, + "wage": 230000, + "market_value": 180000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-101389808348806587", + "match_name": "Skeanz", + "full_name": "Duncan Marquet", + "date_of_birth": "2000-09-25", + "nationality": "FR", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 72, + "laning": 74, + "teamfighting": 70, + "macro_play": 57, + "consistency": 69, + "shotcalling": 59, + "champion_pool": 66, + "discipline": 55, + "mental_resilience": 68 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-sk-gaming", + "traits": [], + "contract_end": null, + "wage": 180000, + "market_value": 315000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-103889902476986558", + "match_name": "LIDER", + "full_name": "Adam Ramzanovich Ilyasov", + "date_of_birth": "1999-07-03", + "nationality": "NO", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 68, + "laning": 70, + "teamfighting": 66, + "macro_play": 53, + "consistency": 65, + "shotcalling": 55, + "champion_pool": 62, + "discipline": 51, + "mental_resilience": 64 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-sk-gaming", + "traits": [], + "contract_end": null, + "wage": 210000, + "market_value": 145000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105553696718837337", + "match_name": "Jopa", + "full_name": "Josip Čančar", + "date_of_birth": "2003-11-03", + "nationality": "HR", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-sk-gaming", + "traits": [], + "contract_end": null, + "wage": 180000, + "market_value": 680000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-99322214629661297", + "match_name": "Mikyx", + "full_name": "Mihael Mehle", + "date_of_birth": "1998-11-02", + "nationality": "SI", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-sk-gaming", + "traits": [], + "contract_end": null, + "wage": 245000, + "market_value": 185000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107156544177574787", + "match_name": "Tracyn", + "full_name": "Sebastian Wojtoń", + "date_of_birth": "2005-09-16", + "nationality": "PL", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-heretics-lec", + "traits": [], + "contract_end": null, + "wage": 170000, + "market_value": 670000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "academy-liga-espanola-team-heretics-player-2", + "match_name": "Daglas", + "full_name": "Kacper Dagiel", + "date_of_birth": "2005-10-23", + "nationality": "PL", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 72, + "laning": 74, + "teamfighting": 70, + "macro_play": 57, + "consistency": 69, + "shotcalling": 59, + "champion_pool": 66, + "discipline": 55, + "mental_resilience": 68 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-heretics-lec", + "traits": [], + "contract_end": null, + "wage": 185000, + "market_value": 785000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-102174699705191142", + "match_name": "Serin", + "full_name": "Tolga Ölmez", + "date_of_birth": "2002-04-10", + "nationality": "TR", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 71, + "laning": 73, + "teamfighting": 69, + "macro_play": 56, + "consistency": 68, + "shotcalling": 58, + "champion_pool": 65, + "discipline": 54, + "mental_resilience": 67 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-heretics-lec", + "traits": [], + "contract_end": null, + "wage": 190000, + "market_value": 395000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105501834624360050", + "match_name": "Ice", + "full_name": "Sanghun Yoon", + "date_of_birth": "2001-04-09", + "nationality": "KR", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-heretics-lec", + "traits": [], + "contract_end": null, + "wage": 195000, + "market_value": 330000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107492119089043087", + "match_name": "Way", + "full_name": "Han Kil", + "date_of_birth": "2002-06-29", + "nationality": "KR", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-heretics-lec", + "traits": [], + "contract_end": null, + "wage": 230000, + "market_value": 595000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105830645287286396", + "match_name": "Sheo", + "full_name": "Théo Borile", + "date_of_birth": "2001-07-05", + "nationality": "FR", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-heretics-lec", + "traits": [], + "contract_end": null, + "wage": 185000, + "market_value": 420000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107605411481021064", + "match_name": "Naak Nako", + "full_name": "Kaan Okan", + "date_of_birth": "2005-03-24", + "nationality": "TR", + "birth_country": null, + "position": "Top", + "natural_position": "Top", + "alternate_positions": [], + "attributes": { + "mechanics": 78, + "laning": 80, + "teamfighting": 76, + "macro_play": 63, + "consistency": 75, + "shotcalling": 65, + "champion_pool": 72, + "discipline": 61, + "mental_resilience": 74 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-vitality", + "traits": [], + "contract_end": null, + "wage": 200000, + "market_value": 645000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-105503548109547493", + "match_name": "Lyncas", + "full_name": "Linas Naunčikas", + "date_of_birth": "2003-12-10", + "nationality": "LT", + "birth_country": null, + "position": "Jungle", + "natural_position": "Jungle", + "alternate_positions": [], + "attributes": { + "mechanics": 74, + "laning": 76, + "teamfighting": 72, + "macro_play": 59, + "consistency": 71, + "shotcalling": 61, + "champion_pool": 68, + "discipline": 57, + "mental_resilience": 70 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-vitality", + "traits": [], + "contract_end": null, + "wage": 210000, + "market_value": 670000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-100356590519370319", + "match_name": "Humanoid", + "full_name": "Marek Brázda", + "date_of_birth": "2000-03-14", + "nationality": "CZ", + "birth_country": null, + "position": "Mid", + "natural_position": "Mid", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-vitality", + "traits": [], + "contract_end": null, + "wage": 255000, + "market_value": 215000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-102787200044335760", + "match_name": "Carzzy", + "full_name": "Matyáš Orság", + "date_of_birth": "2002-01-31", + "nationality": "CZ", + "birth_country": null, + "position": "Adc", + "natural_position": "Adc", + "alternate_positions": [], + "attributes": { + "mechanics": 76, + "laning": 78, + "teamfighting": 74, + "macro_play": 61, + "consistency": 73, + "shotcalling": 63, + "champion_pool": 70, + "discipline": 59, + "mental_resilience": 72 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-vitality", + "traits": [], + "contract_end": null, + "wage": 250000, + "market_value": 450000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + }, + { + "id": "lec-player-107605583684952312", + "match_name": "Fleshy", + "full_name": "Kadir Kemiksiz", + "date_of_birth": "2000-11-24", + "nationality": "TR", + "birth_country": null, + "position": "Support", + "natural_position": "Support", + "alternate_positions": [], + "attributes": { + "mechanics": 75, + "laning": 77, + "teamfighting": 73, + "macro_play": 60, + "consistency": 72, + "shotcalling": 62, + "champion_pool": 69, + "discipline": 58, + "mental_resilience": 71 + }, + "condition": 100, + "morale": 100, + "fitness": 75, + "injury": null, + "team_id": "lec-team-vitality", + "traits": [], + "contract_end": null, + "wage": 200000, + "market_value": 280000, + "stats": { + "assists": 0, + "avg_rating": 0 + }, + "career": [], + "training_focus": null, + "transfer_listed": false, + "loan_listed": false, + "transfer_offers": [], + "morale_core": { + "manager_trust": 50, + "unresolved_issue": null, + "recent_treatment": null, + "pending_promise": null, + "talk_cooldown_until": null, + "renewal_state": null + } + } + ], + "staff": [ + { + "id": "lec-fnatic-staff-0", + "first_name": "FNC", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-fnatic", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-fnatic-staff-1", + "first_name": "FNC", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-fnatic", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-fnatic-staff-2", + "first_name": "FNC", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-fnatic", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-fnatic-staff-3", + "first_name": "FNC", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-fnatic", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-g2-esports-staff-0", + "first_name": "G2", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-g2-esports", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-g2-esports-staff-1", + "first_name": "G2", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-g2-esports", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-g2-esports-staff-2", + "first_name": "G2", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-g2-esports", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-g2-esports-staff-3", + "first_name": "G2", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-g2-esports", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-giantx-lec-staff-0", + "first_name": "GX", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-giantx-lec", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-giantx-lec-staff-1", + "first_name": "GX", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-giantx-lec", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-giantx-lec-staff-2", + "first_name": "GX", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-giantx-lec", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-giantx-lec-staff-3", + "first_name": "GX", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-giantx-lec", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-karmine-corp-staff-0", + "first_name": "KC", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-karmine-corp", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-karmine-corp-staff-1", + "first_name": "KC", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-karmine-corp", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-karmine-corp-staff-2", + "first_name": "KC", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-karmine-corp", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-karmine-corp-staff-3", + "first_name": "KC", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-karmine-corp", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-movistar-koi-staff-0", + "first_name": "MKOI", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-movistar-koi", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-movistar-koi-staff-1", + "first_name": "MKOI", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-movistar-koi", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-movistar-koi-staff-2", + "first_name": "MKOI", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-movistar-koi", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-movistar-koi-staff-3", + "first_name": "MKOI", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-movistar-koi", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-natus-vincere-staff-0", + "first_name": "NAVI", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-natus-vincere", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-natus-vincere-staff-1", + "first_name": "NAVI", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-natus-vincere", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-natus-vincere-staff-2", + "first_name": "NAVI", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-natus-vincere", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-natus-vincere-staff-3", + "first_name": "NAVI", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-natus-vincere", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-shifters-staff-0", + "first_name": "shft", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-shifters", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-shifters-staff-1", + "first_name": "shft", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-shifters", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-shifters-staff-2", + "first_name": "shft", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-shifters", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-shifters-staff-3", + "first_name": "shft", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-shifters", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-sk-gaming-staff-0", + "first_name": "SK", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-sk-gaming", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-sk-gaming-staff-1", + "first_name": "SK", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-sk-gaming", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-sk-gaming-staff-2", + "first_name": "SK", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-sk-gaming", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-sk-gaming-staff-3", + "first_name": "SK", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-sk-gaming", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-heretics-lec-staff-0", + "first_name": "TH", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-team-heretics-lec", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-heretics-lec-staff-1", + "first_name": "TH", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-team-heretics-lec", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-heretics-lec-staff-2", + "first_name": "TH", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-team-heretics-lec", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-heretics-lec-staff-3", + "first_name": "TH", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-team-heretics-lec", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-vitality-staff-0", + "first_name": "VIT", + "last_name": "Staff 1", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "AssistantManager", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-team-vitality", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-vitality-staff-1", + "first_name": "VIT", + "last_name": "Staff 2", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Coach", + "attributes": { + "coaching": 78, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 52 + }, + "team_id": "lec-team-vitality", + "specialization": "Tactics", + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-vitality-staff-2", + "first_name": "VIT", + "last_name": "Staff 3", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Scout", + "attributes": { + "coaching": 66, + "judging_ability": 77, + "judging_potential": 76, + "physiotherapy": 52 + }, + "team_id": "lec-team-vitality", + "specialization": null, + "wage": 18000, + "contract_end": null + }, + { + "id": "lec-team-vitality-staff-3", + "first_name": "VIT", + "last_name": "Staff 4", + "date_of_birth": "1988-01-01", + "nationality": "EUN", + "role": "Physio", + "attributes": { + "coaching": 66, + "judging_ability": 62, + "judging_potential": 62, + "physiotherapy": 79 + }, + "team_id": "lec-team-vitality", + "specialization": null, + "wage": 18000, + "contract_end": null + } + ] +} \ No newline at end of file diff --git a/src-tauri/src/application/team_talk.rs b/src-tauri/src/application/team_talk.rs index 03aaf9983..e2ab99a80 100644 --- a/src-tauri/src/application/team_talk.rs +++ b/src-tauri/src/application/team_talk.rs @@ -10,7 +10,7 @@ fn team_talk_action_key(tone: &str, context: &str) -> String { fn team_talk_personality_factor(player: &domain::player::Player) -> i32 { let composure = i32::from(player.attributes.discipline); let leadership = i32::from(player.attributes.shotcalling); - let aggression = i32::from(player.attributes.aggression); + let aggression = i32::from(player.attributes.shotcalling); ((composure + leadership - aggression) / 6).clamp(-20, 20) } diff --git a/src-tauri/src/application/time_blockers.rs b/src-tauri/src/application/time_blockers.rs index bdebb7583..f216d3622 100644 --- a/src-tauri/src/application/time_blockers.rs +++ b/src-tauri/src/application/time_blockers.rs @@ -1,7 +1,7 @@ use log::info; use ofm_core::game::Game; -use ofm_core::player_rating::{effective_rating_for_assignment, formation_slots, natural_ovr}; +use ofm_core::player_rating::{effective_rating_for_assignment, position_slots, natural_ovr}; fn user_team_context<'a>( game: &'a Game, @@ -45,7 +45,6 @@ fn should_notify_contract_risk_30d( fn build_effective_healthy_lineup_ids( saved_lineup_ids: &[String], roster: &[&domain::player::Player], - formation: &str, ) -> Vec { let healthy_roster: Vec<&domain::player::Player> = roster .iter() @@ -76,7 +75,7 @@ fn build_effective_healthy_lineup_ids( .unwrap_or(std::cmp::Ordering::Equal) }); - let slots = formation_slots(formation); + let slots = position_slots(); if valid_saved_ids.len() >= 8 { let mut xi_ids = valid_saved_ids; @@ -445,7 +444,7 @@ pub fn compute_blocking_actions(game: &Game) -> Vec { let saved_xi_ids = &team.active_lineup_ids; let current_date = game.clock.current_date.date_naive(); let effective_healthy_xi_ids = - build_effective_healthy_lineup_ids(saved_xi_ids, &roster, &team.formation); + build_effective_healthy_lineup_ids(saved_xi_ids, &roster); if let Some(blocker) = injured_lineup_blocker(saved_xi_ids, &roster) { blockers.push(blocker); diff --git a/src-tauri/src/commands/contracts.rs b/src-tauri/src/commands/contracts.rs index 9ddebb385..9c9fa0d27 100644 --- a/src-tauri/src/commands/contracts.rs +++ b/src-tauri/src/commands/contracts.rs @@ -164,7 +164,7 @@ mod tests { use chrono::{TimeZone, Utc}; use db::save_manager::SaveManager; use domain::manager::Manager; - use domain::player::{Player, PlayerAttributes, Position}; + use domain::player::{Player, PlayerAttributes, LolRole}; use domain::staff::{Staff, StaffAttributes, StaffRole}; use domain::team::Team; use ofm_core::clock::GameClock; @@ -203,25 +203,15 @@ mod tests { fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, - mental_resilience: 60, - strength: 60, - champion_pool: 60, - passing: 60, - laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, + laning: 60, + teamfighting: 60, macro_play: 60, consistency: 60, - discipline: 60, - aggression: 60, - teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, + champion_pool: 60, + discipline: 60, + mental_resilience: 60, } } @@ -232,7 +222,7 @@ mod tests { "John Smith".to_string(), "2000-01-01".to_string(), "England".to_string(), - Position::Forward, + LolRole::Adc, default_attrs(), ); player.team_id = Some("team-1".to_string()); diff --git a/src-tauri/src/commands/game.rs b/src-tauri/src/commands/game.rs index b26b961a4..2b268c201 100644 --- a/src-tauri/src/commands/game.rs +++ b/src-tauri/src/commands/game.rs @@ -1,6 +1,6 @@ use chrono::{Datelike, TimeZone}; use domain::message::{InboxMessage, MessageCategory, MessageContext, MessagePriority}; -use domain::player::{Player, PlayerAttributes}; +use domain::player::{Player, PlayerAttributes, LolRole}; use domain::team::{ AcademyLifecycle, AcademyMetadata, ErlAssignment, ErlAssignmentRule, Team, TeamKind, }; @@ -669,22 +669,22 @@ fn resolve_default_world_path(app_handle: &tauri::AppHandle) -> Result Result Result PlayerAttributes { PlayerAttributes { - pace: 60, - mental_resilience: 60, - strength: 60, - champion_pool: 60, - passing: 60, - laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, + laning: 60, + teamfighting: 60, macro_play: 60, consistency: 60, - discipline: 60, - aggression: 60, - teamfighting: 60, shotcalling: 60, - handling: 60, - reflexes: 60, - aerial: 60, + champion_pool: 60, + discipline: 60, + mental_resilience: 60, } } @@ -1597,7 +1587,7 @@ mod tests { id.to_string(), "2000-01-01".to_string(), "ES".to_string(), - Position::Midfielder, + LolRole::Jungle, default_attrs(), ); player.contract_end = contract_end.map(str::to_string); @@ -1706,40 +1696,16 @@ fn build_attributes_from_seed(seed: &DraftPlayerSeed) -> PlayerAttributes { let [mechanics, laning, teamfighting, macro_play, consistency, shotcalling, champion_pool, discipline, mental_resilience] = build_lol_stats_from_seed(seed); - let role_key = normalize_seed_name(seed.role.as_deref().unwrap_or("")); - - let defending = if role_key == "top" || role_key == "support" { - clamp_stat(((i16::from(teamfighting) + i16::from(discipline)) / 2) + 4) - } else { - clamp_stat((i16::from(teamfighting) + i16::from(discipline)) / 2) - }; - PlayerAttributes { - pace: clamp_stat((i16::from(mechanics) + i16::from(laning)) / 2), - mental_resilience: mental_resilience, - strength: clamp_stat((i16::from(teamfighting) + i16::from(discipline)) / 2), - champion_pool: champion_pool, - passing: clamp_stat((i16::from(macro_play) + i16::from(shotcalling)) / 2), - laning: laning, - tackling: clamp_stat((i16::from(discipline) + i16::from(teamfighting)) / 2), - mechanics: mechanics, - defending, - positioning: clamp_stat((i16::from(macro_play) + i16::from(consistency)) / 2), - macro_play: macro_play, - consistency: consistency, - discipline: discipline, - aggression: clamp_stat((i16::from(teamfighting) + i16::from(mental_resilience)) / 2 - 4), - teamfighting: teamfighting, - shotcalling: shotcalling, - handling: 20, - reflexes: 22, - aerial: if role_key == "top" { - 68 - } else if role_key == "support" { - 64 - } else { - 52 - }, + mechanics, + laning, + teamfighting, + macro_play, + consistency, + shotcalling, + champion_pool, + discipline, + mental_resilience, } } @@ -1913,13 +1879,13 @@ pub async fn start_new_game( let clock = GameClock::new(start_date); // Load world based on source - let world_source = world_source.unwrap_or_else(|| "lec-default".to_string()); + let world_source = world_source.unwrap_or_else(|| "default".to_string()); let (teams, mut players, staff) = if world_source == "random" { ofm_core::generator::generate_world(None) - } else if world_source == "lec-default" { + } else if world_source == "default" { let path = resolve_default_world_path(&app_handle)?; let json = std::fs::read_to_string(&path) - .map_err(|e| format!("Failed to read default LEC world database: {}", e))?; + .map_err(|e| format!("Failed to read world database: {}", e))?; let has_explicit_potential_base = json.contains("\"potential_base\""); let mut world = ofm_core::generator::load_world_from_json(&json)?; if !has_explicit_potential_base { diff --git a/src-tauri/src/commands/live_match.rs b/src-tauri/src/commands/live_match.rs index fcb72fbbf..82e81fdc0 100644 --- a/src-tauri/src/commands/live_match.rs +++ b/src-tauri/src/commands/live_match.rs @@ -436,40 +436,30 @@ mod tests { use chrono::{TimeZone, Utc}; use domain::league::{Fixture, FixtureCompetition, FixtureStatus, League, StandingEntry}; use domain::manager::Manager; - use domain::player::{Player, PlayerAttributes, PlayerIssue, PlayerIssueCategory, Position}; + use domain::player::{Player, PlayerAttributes, PlayerIssue, PlayerIssueCategory, LolRole}; use domain::team::Team; use ofm_core::clock::GameClock; use ofm_core::game::Game; use ofm_core::live_match_manager::{self, MatchMode}; use ofm_core::state::StateManager; - fn default_attrs(position: Position) -> PlayerAttributes { - let is_goalkeeper = matches!(position, Position::Goalkeeper); + fn default_attrs(position: LolRole) -> PlayerAttributes { + let is_goalkeeper = matches!(position, LolRole::Support); PlayerAttributes { - pace: 65, - mental_resilience: 65, - strength: 65, - champion_pool: 65, - passing: 65, - laning: if is_goalkeeper { 30 } else { 65 }, - tackling: if is_goalkeeper { 30 } else { 65 }, mechanics: if is_goalkeeper { 30 } else { 65 }, - defending: if is_goalkeeper { 30 } else { 65 }, - positioning: 65, + laning: if is_goalkeeper { 30 } else { 65 }, + teamfighting: 65, macro_play: 65, consistency: 65, - discipline: 65, - aggression: 50, - teamfighting: 65, shotcalling: 50, - handling: if is_goalkeeper { 75 } else { 20 }, - reflexes: if is_goalkeeper { 75 } else { 20 }, - aerial: 60, + champion_pool: 65, + discipline: 65, + mental_resilience: 65, } } - fn make_player(id: &str, name: &str, team_id: &str, position: Position) -> Player { + fn make_player(id: &str, name: &str, team_id: &str, position: LolRole) -> Player { let mut player = Player::new( id.to_string(), name.to_string(), @@ -503,14 +493,14 @@ mod tests { &format!("{}_gk", prefix), &format!("{} GK", prefix), team_id, - Position::Goalkeeper, + LolRole::Support, )); for index in 0..4 { players.push(make_player( &format!("{}_def{}", prefix, index), &format!("{} Def{}", prefix, index), team_id, - Position::Defender, + LolRole::Top, )); } for index in 0..4 { @@ -518,7 +508,7 @@ mod tests { &format!("{}_mid{}", prefix, index), &format!("{} Mid{}", prefix, index), team_id, - Position::Midfielder, + LolRole::Jungle, )); } for index in 0..2 { @@ -526,7 +516,7 @@ mod tests { &format!("{}_fwd{}", prefix, index), &format!("{} Fwd{}", prefix, index), team_id, - Position::Forward, + LolRole::Adc, )); } players @@ -675,7 +665,7 @@ mod tests { state.set_live_match(session); let response = - finish_live_match_internal(&state, None).expect("finish live match response"); + finish_live_match_internal(&state, None, None).expect("finish live match response"); let round_summary = response.round_summary.expect("round summary response"); assert!(round_summary.is_complete); @@ -702,7 +692,6 @@ mod tests { .unwrap(); composed.attributes.discipline = 90; composed.attributes.shotcalling = 90; - composed.attributes.aggression = 20; composed.morale_core.manager_trust = 80; let volatile = game @@ -712,7 +701,6 @@ mod tests { .unwrap(); volatile.attributes.discipline = 20; volatile.attributes.shotcalling = 20; - volatile.attributes.aggression = 90; volatile.morale_core.manager_trust = 25; volatile.morale_core.unresolved_issue = Some(PlayerIssue { category: PlayerIssueCategory::Morale, diff --git a/src-tauri/src/commands/squad.rs b/src-tauri/src/commands/squad.rs index 40e71f282..7a113d668 100644 --- a/src-tauri/src/commands/squad.rs +++ b/src-tauri/src/commands/squad.rs @@ -467,87 +467,6 @@ fn apply_post_scrim_decision_internal( Ok(()) } -#[tauri::command] -pub fn set_formation(state: State<'_, StateManager>, formation: String) -> Result { - info!("[cmd] set_formation: {}", formation); - let mut game = state - .get_game(|g| g.clone()) - .ok_or("No active game session".to_string())?; - - let team_id = game - .manager - .team_id - .clone() - .ok_or("No team assigned".to_string())?; - - // Parse formation into (def, mid, fwd) counts - let parts: Vec = formation - .split('-') - .filter_map(|s| s.parse().ok()) - .collect(); - let (num_def, num_mid, num_fwd) = match parts.len() { - 3 => (parts[0], parts[1], parts[2]), - 4 => (parts[0], parts[1] + parts[2], parts[3]), - _ => (4, 4, 2), - }; - - if let Some(team) = game.teams.iter_mut().find(|t| t.id == team_id) { - team.formation = formation; - } - - // Reassign positions for outfield players on this team - // In LoL, filter out Support role (the "goalkeeper" equivalent) - let player_ids: Vec = game - .players - .iter() - .filter(|p| { - p.team_id.as_deref() == Some(&team_id) && p.position != domain::player::LolRole::Support - }) - .map(|p| p.id.clone()) - .collect(); - - // Sort by defensive ability (most defensive first) - let mut sorted_ids = player_ids.clone(); - sorted_ids.sort_by(|a_id, b_id| { - let pa = game - .players - .iter() - .find(|p| p.id == *a_id) - .expect("set_formation: player should exist in game state"); - let pb = game - .players - .iter() - .find(|p| p.id == *b_id) - .expect("set_formation: player should exist in game state"); - let def_a = pa.attributes.defending as u16 - + pa.attributes.tackling as u16 - + pa.attributes.strength as u16; - let def_b = pb.attributes.defending as u16 - + pb.attributes.tackling as u16 - + pb.attributes.strength as u16; - def_b.cmp(&def_a) - }); - - // Assign positions - map to LoL roles - for (slot, pid) in sorted_ids.iter().enumerate() { - let new_pos = if slot < num_def { - domain::player::LolRole::Top - } else if slot < num_def + num_mid { - domain::player::LolRole::Mid - } else if slot < num_def + num_mid + num_fwd { - domain::player::LolRole::Adc - } else { - continue; - }; - if let Some(player) = game.players.iter_mut().find(|p| p.id == *pid) { - player.position = new_pos; - } - } - - state.set_game(game.clone()); - Ok(game) -} - #[tauri::command] pub fn set_active_lineup( state: State<'_, StateManager>, @@ -593,8 +512,8 @@ fn apply_active_lineup(game: &mut Game, team_id: &str, player_ids: Vec) } #[tauri::command] -pub fn set_play_style(state: State<'_, StateManager>, play_style: String) -> Result { - info!("[cmd] set_play_style: {}", play_style); +pub fn set_draft_strategy(state: State<'_, StateManager>, draft_strategy: String) -> Result { + info!("[cmd] set_draft_strategy: {}", draft_strategy); let mut game = state .get_game(|g| g.clone()) .ok_or("No active game session".to_string())?; @@ -605,17 +524,16 @@ pub fn set_play_style(state: State<'_, StateManager>, play_style: String) -> Res .clone() .ok_or("No team assigned".to_string())?; - let style = match play_style.as_str() { - "Attacking" => domain::team::PlayStyle::Attacking, - "Defensive" => domain::team::PlayStyle::Defensive, - "Possession" => domain::team::PlayStyle::Possession, - "Counter" => domain::team::PlayStyle::Counter, - "HighPress" => domain::team::PlayStyle::HighPress, - _ => domain::team::PlayStyle::Balanced, + let strategy = match draft_strategy.as_str() { + "Attacking" | "HighPress" => domain::team::DraftStrategy::Aggressive, + "Defensive" => domain::team::DraftStrategy::Passive, + "Possession" => domain::team::DraftStrategy::Scaling, + "Counter" => domain::team::DraftStrategy::CounterPick, + _ => domain::team::DraftStrategy::Balanced, }; if let Some(team) = game.teams.iter_mut().find(|t| t.id == team_id) { - team.play_style = style; + team.draft_strategy = strategy; } state.set_game(game.clone()); @@ -1927,7 +1845,7 @@ pub fn auto_select_team_roles( mod tests { use chrono::{TimeZone, Utc}; use domain::manager::Manager; - use domain::player::{Player, PlayerAttributes, Position}; + use domain::player::{Player, PlayerAttributes, LolRole}; use domain::staff::{Staff, StaffAttributes, StaffRole}; use domain::team::{Team, TrainingFocus, TrainingIntensity, TrainingSchedule}; use ofm_core::clock::GameClock; @@ -1935,25 +1853,15 @@ mod tests { fn attrs(stat: u8) -> PlayerAttributes { PlayerAttributes { - pace: stat, - mental_resilience: stat, - strength: stat, - champion_pool: stat, - passing: stat, - laning: stat, - tackling: stat, mechanics: stat, - defending: stat, - positioning: stat, + laning: stat, + teamfighting: stat, macro_play: stat, consistency: stat, - discipline: stat, - aggression: stat, - teamfighting: stat, shotcalling: stat, - handling: stat, - reflexes: stat, - aerial: stat, + champion_pool: stat, + discipline: stat, + mental_resilience: stat, } } @@ -1964,7 +1872,7 @@ mod tests { format!("{} Full", id), "2005-01-01".to_string(), "GB".to_string(), - Position::Midfielder, + LolRole::Jungle, attrs(stat), ); player.team_id = Some(team_id.to_string()); @@ -2012,7 +1920,6 @@ mod tests { ); coach.nationality = "GB".to_string(); coach.team_id = Some("team-1".to_string()); - coach.specialization = Some(domain::staff::CoachingSpecialization::Technique); Game::new( clock, diff --git a/src-tauri/src/commands/stats/tests.rs b/src-tauri/src/commands/stats/tests.rs index 97f59b8a8..09b95fe3c 100644 --- a/src-tauri/src/commands/stats/tests.rs +++ b/src-tauri/src/commands/stats/tests.rs @@ -1,9 +1,9 @@ use chrono::{TimeZone, Utc}; use domain::league::FixtureCompetition; use domain::manager::Manager; -use domain::player::{Player, PlayerAttributes, Position}; +use domain::player::{Player, PlayerAttributes, LolRole}; use domain::stats::{ - LolRole, MatchOutcome, PlayerMatchStatsRecord, StatsState, TeamMatchStatsRecord, TeamSide, + MatchOutcome, PlayerMatchStatsRecord, StatsState, TeamMatchStatsRecord, TeamSide, }; use domain::team::Team; use ofm_core::clock::GameClock; @@ -15,29 +15,19 @@ use super::team::{get_team_match_history_internal, get_team_stats_overview_inter fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, - mental_resilience: 60, - strength: 60, - champion_pool: 60, - passing: 60, - laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, + laning: 60, + teamfighting: 60, macro_play: 60, consistency: 60, - discipline: 60, - aggression: 60, - teamfighting: 60, shotcalling: 60, - handling: 60, - reflexes: 60, - aerial: 60, + champion_pool: 60, + discipline: 60, + mental_resilience: 60, } } -fn make_player(id: &str, team_id: &str, natural_position: Position) -> Player { +fn make_player(id: &str, team_id: &str, natural_position: LolRole) -> Player { let mut player = Player::new( id.to_string(), id.to_string(), @@ -162,7 +152,7 @@ fn get_player_match_history_returns_lol_first_fields() { state.set_game(make_game(vec![make_player( "player-1", "team-1", - Position::Striker, + LolRole::Adc, )])); state.set_stats_state(StatsState { player_matches: vec![ @@ -206,9 +196,9 @@ fn get_player_match_history_returns_lol_first_fields() { fn get_player_stats_overview_aggregates_lol_metrics_by_position() { let state = StateManager::new(); state.set_game(make_game(vec![ - make_player("player-1", "team-1", Position::Striker), - make_player("player-2", "team-1", Position::Striker), - make_player("player-3", "team-1", Position::Striker), + make_player("player-1", "team-1", LolRole::Adc), + make_player("player-2", "team-1", LolRole::Adc), + make_player("player-3", "team-1", LolRole::Adc), ])); state.set_stats_state(StatsState { player_matches: vec![ @@ -323,7 +313,7 @@ fn get_team_stats_overview_aggregates_lol_team_metrics() { state.set_game(make_game(vec![make_player( "player-1", "team-1", - Position::Striker, + LolRole::Adc, )])); state.set_stats_state(StatsState { player_matches: vec![], @@ -351,7 +341,7 @@ fn get_team_match_history_returns_lol_first_fields() { state.set_game(make_game(vec![make_player( "player-1", "team-1", - Position::Striker, + LolRole::Adc, )])); state.set_stats_state(StatsState { player_matches: vec![], diff --git a/src-tauri/src/commands/time.rs b/src-tauri/src/commands/time.rs index 44071183b..e2c57f193 100644 --- a/src-tauri/src/commands/time.rs +++ b/src-tauri/src/commands/time.rs @@ -179,7 +179,7 @@ mod tests { use domain::league::{Fixture, FixtureCompetition, FixtureStatus}; use domain::manager::Manager; use domain::message::{InboxMessage, MessagePriority}; - use domain::player::{Injury, Player, PlayerAttributes, Position}; + use domain::player::{Injury, Player, PlayerAttributes, LolRole}; use domain::stats::StatsState; use domain::team::Team; use ofm_core::clock::GameClock; @@ -189,29 +189,19 @@ mod tests { fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, - mental_resilience: 60, - strength: 60, - champion_pool: 60, - passing: 60, - laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, + laning: 60, + teamfighting: 60, macro_play: 60, consistency: 60, - discipline: 60, - aggression: 60, - teamfighting: 60, shotcalling: 60, - handling: 60, - reflexes: 60, - aerial: 60, + champion_pool: 60, + discipline: 60, + mental_resilience: 60, } } - fn make_player(id: &str, name: &str, team_id: &str, position: Position) -> Player { + fn make_player(id: &str, name: &str, team_id: &str, position: LolRole) -> Player { let mut player = Player::new( id.to_string(), name.to_string(), @@ -239,15 +229,15 @@ mod tests { let players: Vec = (1..=roster_size) .map(|idx| { let position = if idx == 1 { - Position::Goalkeeper + LolRole::Support } else if idx <= 5 { - Position::Defender + LolRole::Top } else if idx == 6 { - Position::AttackingMidfielder + LolRole::Mid } else if idx <= 9 { - Position::Midfielder + LolRole::Jungle } else { - Position::Forward + LolRole::Adc }; make_player( @@ -519,7 +509,6 @@ mod tests { .unwrap(); first_key_player.contract_end = Some("2025-07-15".to_string()); first_key_player.wage = 35_000; - first_key_player.attributes.pace = 92; first_key_player.attributes.laning = 94; first_key_player.attributes.mechanics = 90; @@ -530,7 +519,6 @@ mod tests { .unwrap(); second_key_player.contract_end = Some("2025-07-15".to_string()); second_key_player.wage = 25_000; - second_key_player.attributes.pace = 90; second_key_player.attributes.laning = 91; second_key_player.attributes.mechanics = 89; @@ -653,14 +641,14 @@ mod tests { &format!("{}-gk", prefix), &format!("{} GK", prefix), team_id, - Position::Goalkeeper, + LolRole::Support, )); for idx in 0..4 { players.push(make_player( &format!("{}-def{}", prefix, idx), &format!("{} Def{}", prefix, idx), team_id, - Position::Defender, + LolRole::Top, )); } for idx in 0..4 { @@ -668,7 +656,7 @@ mod tests { &format!("{}-mid{}", prefix, idx), &format!("{} Mid{}", prefix, idx), team_id, - Position::Midfielder, + LolRole::Jungle, )); } for idx in 0..2 { @@ -676,7 +664,7 @@ mod tests { &format!("{}-fwd{}", prefix, idx), &format!("{} Fwd{}", prefix, idx), team_id, - Position::Forward, + LolRole::Adc, )); } } diff --git a/src-tauri/src/commands/transfers.rs b/src-tauri/src/commands/transfers.rs index d05eb59b1..a4b691593 100644 --- a/src-tauri/src/commands/transfers.rs +++ b/src-tauri/src/commands/transfers.rs @@ -251,7 +251,7 @@ mod tests { }; use chrono::{TimeZone, Utc}; use domain::manager::Manager; - use domain::player::{Player, PlayerAttributes, Position, TransferOffer, TransferOfferStatus}; + use domain::player::{Player, PlayerAttributes, TransferOffer, TransferOfferStatus, LolRole}; use domain::season::TransferWindowStatus; use domain::team::Team; use ofm_core::clock::GameClock; @@ -261,25 +261,15 @@ mod tests { fn default_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 60, - mental_resilience: 60, - strength: 60, - champion_pool: 60, - passing: 60, - laning: 60, - tackling: 60, mechanics: 60, - defending: 60, - positioning: 60, + laning: 60, + teamfighting: 60, macro_play: 60, consistency: 60, - discipline: 60, - aggression: 60, - teamfighting: 60, shotcalling: 60, - handling: 30, - reflexes: 30, - aerial: 60, + champion_pool: 60, + discipline: 60, + mental_resilience: 60, } } @@ -321,7 +311,7 @@ mod tests { "Player One".to_string(), "2000-01-01".to_string(), "England".to_string(), - Position::Forward, + LolRole::Adc, default_attrs(), ); player.team_id = Some("team-1".to_string()); @@ -372,7 +362,7 @@ mod tests { "Player Two".to_string(), "2000-01-01".to_string(), "England".to_string(), - Position::Forward, + LolRole::Adc, default_attrs(), ); player.team_id = Some("team-2".to_string()); @@ -425,7 +415,7 @@ mod tests { "Free Agent One".to_string(), "2001-02-10".to_string(), "England".to_string(), - Position::Forward, + LolRole::Adc, default_attrs(), ); free_agent.team_id = None; diff --git a/src-tauri/src/commands/world.rs b/src-tauri/src/commands/world.rs index 6897164b5..d4378b212 100644 --- a/src-tauri/src/commands/world.rs +++ b/src-tauri/src/commands/world.rs @@ -16,12 +16,12 @@ fn resolve_default_world_editor_path( let candidates = [ cwd.join("src-tauri") .join("databases") - .join("lec_world.json"), - cwd.join("databases").join("lec_world.json"), + .join("world.json"), + cwd.join("databases").join("world.json"), app_handle .path() .resource_dir() - .map(|dir| dir.join("databases").join("lec_world.json")) + .map(|dir| dir.join("databases").join("world.json")) .unwrap_or_else(|_| std::path::PathBuf::new()), ]; @@ -31,7 +31,7 @@ fn resolve_default_world_editor_path( } } - Err("Default LEC world database not found (lec_world.json).".to_string()) + Err("Default world database not found (world.json).".to_string()) } fn enrich_world_for_editor(world: &mut ofm_core::generator::WorldData) { @@ -60,7 +60,7 @@ fn writable_world_editor_database_dir( fn writable_world_editor_database_path( app_handle: &tauri::AppHandle, ) -> Result { - Ok(writable_world_editor_database_dir(app_handle)?.join("lec_world.json")) + Ok(writable_world_editor_database_dir(app_handle)?.join("world.json")) } fn write_world_database_with_fallback( @@ -89,7 +89,7 @@ fn write_world_database_with_fallback( .map_err(|e| format!("Failed to create writable database directory: {}", e))?; let fallback_path = fallback_dir.join( path.file_name() - .unwrap_or_else(|| std::ffi::OsStr::new("lec_world.json")), + .unwrap_or_else(|| std::ffi::OsStr::new("world.json")), ); std::fs::write(&fallback_path, json) .map_err(|e| format!("Failed to write fallback world database: {}", e))?; @@ -256,7 +256,7 @@ mod tests { use super::{export_world_database_internal, write_database_json_to_dir}; use chrono::{TimeZone, Utc}; use domain::manager::Manager; - use domain::player::{Player, PlayerAttributes, Position}; + use domain::player::{Player, PlayerAttributes, LolRole}; use domain::team::Team; use ofm_core::clock::GameClock; use ofm_core::game::Game; @@ -294,25 +294,15 @@ mod tests { fn sample_attrs() -> PlayerAttributes { PlayerAttributes { - pace: 65, - mental_resilience: 65, - strength: 65, - champion_pool: 65, - passing: 65, - laning: 65, - tackling: 65, mechanics: 65, - defending: 65, - positioning: 65, + laning: 65, + teamfighting: 65, macro_play: 65, consistency: 65, - discipline: 65, - aggression: 50, - teamfighting: 65, shotcalling: 50, - handling: 20, - reflexes: 20, - aerial: 60, + champion_pool: 65, + discipline: 65, + mental_resilience: 65, } } @@ -343,7 +333,7 @@ mod tests { "John Doe".to_string(), "2000-01-01".to_string(), "GB".to_string(), - Position::Midfielder, + LolRole::Jungle, sample_attrs(), ); player.team_id = Some("team-1".to_string()); @@ -389,8 +379,7 @@ mod tests { "transfer_budget": 250000, "season_income": 0, "season_expenses": 0, - "formation": "4-4-2", - "play_style": "Balanced", + "draft_strategy": "Balanced", "training_focus": "Scrims", "training_intensity": "Medium", "training_schedule": "Balanced", diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 0f1a1dc56..91083bf35 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -112,10 +112,9 @@ pub fn run() { propose_renewal, delegate_renewals, preview_renewal_financial_impact, - set_formation, set_active_lineup, set_starting_xi, - set_play_style, + set_draft_strategy, set_lol_tactics, set_team_roles, set_training, diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index dd6f16d95..3f08af8b9 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -28,7 +28,7 @@ "targets": "all", "createUpdaterArtifacts": true, "resources": [ - "databases/lec_world.json" + "databases/world.json" ], "icon": [ "icons/32x32.png", diff --git a/src/components/dashboard/DashboardHeader.tsx b/src/components/dashboard/DashboardHeader.tsx index 48ec83107..78ceacf08 100644 --- a/src/components/dashboard/DashboardHeader.tsx +++ b/src/components/dashboard/DashboardHeader.tsx @@ -17,7 +17,7 @@ import { Badge, ThemeToggle } from "../ui"; import { translatePositionAbbreviation } from "../squad/SquadTab.helpers"; import { getPlayerBadgeVariant } from "./dashboardHelpers"; import { resolvePlayerPhoto } from "../../lib/playerPhotos"; -import { resolveExampleTeamLogo } from "../../lib/teamLogos"; +import { resolveTeamLogo } from "../../lib/teamLogos"; export interface DashboardMatchModeMeta { buttonColorClass: string; @@ -208,7 +208,7 @@ function renderSearchResults(props: { className="flex w-full items-center gap-2 px-3 py-2 text-left transition-colors hover:bg-gray-50 dark:hover:bg-navy-600" > {(() => { - const teamLogo = resolveExampleTeamLogo(team.name); + const teamLogo = resolveTeamLogo(team.name); if (teamLogo) { return {team.name}; } diff --git a/src/components/dashboard/DashboardWorkspaceContent.test.tsx b/src/components/dashboard/DashboardWorkspaceContent.test.tsx index aa7777c6c..272f807e9 100644 --- a/src/components/dashboard/DashboardWorkspaceContent.test.tsx +++ b/src/components/dashboard/DashboardWorkspaceContent.test.tsx @@ -59,7 +59,6 @@ function createGameState(): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, @@ -82,8 +81,7 @@ function createGameState(): GameStateData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", @@ -108,8 +106,7 @@ function createGameState(): GameStateData { transfer_budget: 200000, season_income: 0, season_expenses: 0, - formation: "4-3-3", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", diff --git a/src/components/dashboard/dashboardHelpers.test.ts b/src/components/dashboard/dashboardHelpers.test.ts index fe955a98d..2a98f4322 100644 --- a/src/components/dashboard/dashboardHelpers.test.ts +++ b/src/components/dashboard/dashboardHelpers.test.ts @@ -26,8 +26,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Medium", training_schedule: "Balanced", @@ -142,7 +141,6 @@ function createGameState(overrides: Partial = {}): GameStateData career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/dashboard/dashboardTabContentModel.test.ts b/src/components/dashboard/dashboardTabContentModel.test.ts index f5ff11abe..0ede3fe63 100644 --- a/src/components/dashboard/dashboardTabContentModel.test.ts +++ b/src/components/dashboard/dashboardTabContentModel.test.ts @@ -24,7 +24,6 @@ function createGameState(): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/finances/FinancesTab.test.tsx b/src/components/finances/FinancesTab.test.tsx index c40987216..ad87b4d17 100644 --- a/src/components/finances/FinancesTab.test.tsx +++ b/src/components/finances/FinancesTab.test.tsx @@ -135,8 +135,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 300000, season_income: 1000000, season_expenses: 500000, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", @@ -288,7 +287,6 @@ function createGameState( career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/home/HomeLatestNewsCard.test.tsx b/src/components/home/HomeLatestNewsCard.test.tsx index 8dc280a89..94f7e0e52 100644 --- a/src/components/home/HomeLatestNewsCard.test.tsx +++ b/src/components/home/HomeLatestNewsCard.test.tsx @@ -31,8 +31,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", diff --git a/src/components/home/HomeLeaguePositionCard.test.tsx b/src/components/home/HomeLeaguePositionCard.test.tsx index 9a16cce72..4169c9418 100644 --- a/src/components/home/HomeLeaguePositionCard.test.tsx +++ b/src/components/home/HomeLeaguePositionCard.test.tsx @@ -39,8 +39,7 @@ describe("HomeLeaguePositionCard", () => { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "4-3-3", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Balanced", training_intensity: "Normal", training_schedule: "Default", @@ -80,10 +79,9 @@ describe("HomeLeaguePositionCard", () => { team_id: "lec-team-1", played: 5, won: 3, - drawn: 1, lost: 1, - goals_for: 9, - goals_against: 4, + maps_won: 9, + maps_lost: 4, points: 10, }, ]} diff --git a/src/components/home/HomeLeaguePositionCard.tsx b/src/components/home/HomeLeaguePositionCard.tsx index 4e0bc7676..5f68e6875 100644 --- a/src/components/home/HomeLeaguePositionCard.tsx +++ b/src/components/home/HomeLeaguePositionCard.tsx @@ -8,10 +8,9 @@ interface LeagueStandingSnapshot { team_id: string; played: number; won: number; - drawn: number; lost: number; - goals_for: number; - goals_against: number; + maps_won: number; + maps_lost: number; points: number; } diff --git a/src/components/home/HomeNextOpponentCard.test.tsx b/src/components/home/HomeNextOpponentCard.test.tsx index 58b273932..8f903aeef 100644 --- a/src/components/home/HomeNextOpponentCard.test.tsx +++ b/src/components/home/HomeNextOpponentCard.test.tsx @@ -47,8 +47,7 @@ function createNextOpponent(): NextOpponentWidgetData { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", diff --git a/src/components/home/HomeRecentResultsCard.test.tsx b/src/components/home/HomeRecentResultsCard.test.tsx index 666837a65..402d607fd 100644 --- a/src/components/home/HomeRecentResultsCard.test.tsx +++ b/src/components/home/HomeRecentResultsCard.test.tsx @@ -34,8 +34,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", diff --git a/src/components/home/HomeTab.helpers.test.ts b/src/components/home/HomeTab.helpers.test.ts index dc71dc957..4957d5e3a 100644 --- a/src/components/home/HomeTab.helpers.test.ts +++ b/src/components/home/HomeTab.helpers.test.ts @@ -38,8 +38,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", @@ -184,7 +183,6 @@ function createGameState(overrides: Partial = {}): GameStateData career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, @@ -250,20 +248,18 @@ describe("HomeTab.helpers", function (): void { team_id: "team-2", played: 1, won: 1, - drawn: 0, lost: 0, - goals_for: 2, - goals_against: 0, + maps_won: 2, + maps_lost: 0, points: 3, }, { team_id: "team-1", played: 1, won: 0, - drawn: 0, lost: 1, - goals_for: 0, - goals_against: 2, + maps_won: 0, + maps_lost: 2, points: 0, }, ], diff --git a/src/components/home/HomeTab.test.tsx b/src/components/home/HomeTab.test.tsx index c40075727..4ec508a4b 100644 --- a/src/components/home/HomeTab.test.tsx +++ b/src/components/home/HomeTab.test.tsx @@ -59,8 +59,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", @@ -189,7 +188,6 @@ function createGameState( career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, @@ -219,20 +217,18 @@ function createGameState( team_id: "team-2", played: 1, won: 1, - drawn: 0, lost: 0, - goals_for: 2, - goals_against: 0, + maps_won: 2, + maps_lost: 0, points: 3, }, { team_id: "team-1", played: 1, won: 0, - drawn: 0, lost: 1, - goals_for: 0, - goals_against: 2, + maps_won: 0, + maps_lost: 2, points: 0, }, ], diff --git a/src/components/home/HomeTab.tsx b/src/components/home/HomeTab.tsx index 2edc1f8d0..b9e5b0306 100644 --- a/src/components/home/HomeTab.tsx +++ b/src/components/home/HomeTab.tsx @@ -123,9 +123,13 @@ export default function HomeTab({ ? [...league.standings] .sort(compareStandingsByLolScore) .map((standing) => ({ - ...standing, - goals_for: standing.goals_for ?? standing.kills_for ?? 0, - goals_against: standing.goals_against ?? standing.kills_against ?? 0, + team_id: standing.team_id, + played: standing.played, + won: standing.won, + lost: standing.lost, + maps_won: standing.maps_won ?? standing.kills_for ?? standing.goals_for ?? 0, + maps_lost: standing.maps_lost ?? standing.kills_against ?? standing.goals_against ?? 0, + points: standing.points, })) : []; diff --git a/src/components/home/HomeTodayPlanCard.test.tsx b/src/components/home/HomeTodayPlanCard.test.tsx index d983e58b8..55102dfa8 100644 --- a/src/components/home/HomeTodayPlanCard.test.tsx +++ b/src/components/home/HomeTodayPlanCard.test.tsx @@ -52,8 +52,7 @@ function team(overrides: Partial = {}): TeamData { transfer_budget: 0, season_income: 0, season_expenses: 0, - formation: "LoL", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Scrims", training_intensity: "Medium", training_schedule: "Balanced", diff --git a/src/components/home/JobOpportunitiesCard.test.tsx b/src/components/home/JobOpportunitiesCard.test.tsx index ab2b194fa..5793925b9 100644 --- a/src/components/home/JobOpportunitiesCard.test.tsx +++ b/src/components/home/JobOpportunitiesCard.test.tsx @@ -47,7 +47,6 @@ function createGameState(): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/inbox/InboxTab.test.tsx b/src/components/inbox/InboxTab.test.tsx index 3b93878c6..14dac7da3 100644 --- a/src/components/inbox/InboxTab.test.tsx +++ b/src/components/inbox/InboxTab.test.tsx @@ -162,7 +162,6 @@ function createGameState(messages: MessageData[]): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/manager/ManagerTab.test.tsx b/src/components/manager/ManagerTab.test.tsx index 679eb02d7..7389e6e28 100644 --- a/src/components/manager/ManagerTab.test.tsx +++ b/src/components/manager/ManagerTab.test.tsx @@ -59,8 +59,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", @@ -92,7 +91,6 @@ function createGameState(withHistory: boolean): GameStateData { career_stats: { matches_managed: 100, wins: 55, - draws: 20, losses: 25, trophies: 2, best_finish: 1, @@ -106,7 +104,6 @@ function createGameState(withHistory: boolean): GameStateData { end_date: null, matches: 40, wins: 20, - draws: 10, losses: 10, best_league_position: 3, }, diff --git a/src/components/manager/ManagerTab.tsx b/src/components/manager/ManagerTab.tsx index 0e825d634..2322e447d 100644 --- a/src/components/manager/ManagerTab.tsx +++ b/src/components/manager/ManagerTab.tsx @@ -311,7 +311,6 @@ export default function ManagerTab({ gameState }: ManagerTabProps) {
- 0 ? `${(stats.wins / stats.matches_managed * 100).toFixed(0)}%` : "—"} /> @@ -373,7 +372,6 @@ export default function ManagerTab({ gameState }: ManagerTabProps) { {t('manager.period')} {t('common.played')} {t('common.won')} - {t('common.drawn')} {t('common.lost')} @@ -384,7 +382,6 @@ export default function ManagerTab({ gameState }: ManagerTabProps) { {entry.start_date.substring(0, 4)} — {entry.end_date?.substring(0, 4) || t('common.present')} {entry.matches} {entry.wins} - {entry.draws} {entry.losses} ))} diff --git a/src/components/match/ChampionDraft.tsx b/src/components/match/ChampionDraft.tsx index 94f7c447d..5d5c68ba8 100644 --- a/src/components/match/ChampionDraft.tsx +++ b/src/components/match/ChampionDraft.tsx @@ -476,7 +476,7 @@ function mapSnapshotPositionToDraftRole(role: string): Role { if (engineKey === "adc") return "ADC"; if (engineKey === "support") return "SUPPORT"; - // Fallback: map football positions to LoL roles + // Fallback: map legacy positions to LoL roles const key = normalizeKey(role); if (key.includes("top") || key === "defender") return "TOP"; if (key.includes("jung") || key === "midfielder" || key === "centralmidfielder") return "JUNGLE"; @@ -588,8 +588,8 @@ function hashText(value: string): number { return hash; } -function planTempo(playStyle: string): "early" | "mid" | "late" { - switch (playStyle) { +function planTempo(draftStrategy: string): "early" | "mid" | "late" { + switch (draftStrategy) { case "Attacking": case "HighPress": case "Counter": @@ -1679,7 +1679,7 @@ export default function ChampionDraft({ const scoreDraft = (side: Side): DraftScoreBreakdown => { const ownPicks = side === "blue" ? bluePicks : redPicks; const enemyPicks = side === "blue" ? redPicks : bluePicks; - const ownPlan = planTempo(side === "blue" ? snapshot.home_team.play_style : snapshot.away_team.play_style); + const ownPlan = planTempo(side === "blue" ? snapshot.home_team.draft_strategy : snapshot.away_team.draft_strategy); const teamId = side === "blue" ? snapshot.home_team.id : snapshot.away_team.id; const opponentTeamId = side === "blue" ? snapshot.away_team.id : snapshot.home_team.id; const playerIds = side === "blue" ? bluePlayerIds : redPlayerIds; @@ -1751,7 +1751,7 @@ export default function ChampionDraft({ redPicks, bluePlayerIds, snapshot.home_team.id, - snapshot.home_team.play_style, + snapshot.home_team.draft_strategy, snapshot.away_team.id, gameState?.staff, scrimReportsByTeamId, @@ -1761,7 +1761,7 @@ export default function ChampionDraft({ redPicks, redPlayerIds, snapshot.away_team.id, - snapshot.away_team.play_style, + snapshot.away_team.draft_strategy, snapshot.home_team.id, gameState?.staff, scrimReportsByTeamId, @@ -2281,7 +2281,7 @@ export default function ChampionDraft({ ? Math.round( (Number(playerState.attributes.consistency ?? 70) + Number(playerState.attributes.macro_play ?? 70) + - Number(playerState.attributes.positioning ?? 70) + + Number(playerState.attributes.consistency ?? 70) + Number(playerState.attributes.discipline ?? 70)) / 4, ) diff --git a/src/components/match/DraftResultScreen.tsx b/src/components/match/DraftResultScreen.tsx index c0fdaf521..07adc874d 100644 --- a/src/components/match/DraftResultScreen.tsx +++ b/src/components/match/DraftResultScreen.tsx @@ -3,7 +3,7 @@ import { useTranslation } from "react-i18next"; import teamsSeed from "../../../data/lec/draft/teams.json"; import { buildLolScrimPrepInsight } from "../../lib/lolScrimPrep"; import { resolvePlayerPhoto } from "../../lib/playerPhotos"; -import { resolveExampleTeamLogo } from "../../lib/teamLogos"; +import { resolveTeamLogo } from "../../lib/teamLogos"; import type { MatchSnapshot } from "./types"; import type { DraftMatchResult, DraftTimelineEvent } from "./draftResultSimulator"; @@ -169,8 +169,8 @@ export default function DraftResultScreen({ const redTeam = sideTeam(snapshot, "red"); const blueTri = teamTriCode(blueTeam.name); const redTri = teamTriCode(redTeam.name); - const blueLogo = resolveExampleTeamLogo(blueTeam.name); - const redLogo = resolveExampleTeamLogo(redTeam.name); + const blueLogo = resolveTeamLogo(blueTeam.name); + const redLogo = resolveTeamLogo(redTeam.name); const controlledWon = selectedResult.winnerSide === controlledSide; const controlledPrepInsight = buildLolScrimPrepInsight( diff --git a/src/components/match/HalfTimeBreak.tsx b/src/components/match/HalfTimeBreak.tsx index 7d522fa1e..a5565365a 100644 --- a/src/components/match/HalfTimeBreak.tsx +++ b/src/components/match/HalfTimeBreak.tsx @@ -5,8 +5,7 @@ import { GameStateData } from "../../store/gameStore"; import { MatchSnapshot, MatchEvent, - FORMATIONS, - PLAY_STYLES, + DRAFT_STRATEGIES, getTeamTalkOptions, TeamTalkTone, } from "./types"; @@ -91,25 +90,14 @@ export default function HalfTimeBreak({ ].includes(e.event_type), ); - const handleFormationChange = async (formation: string) => { + const handleDraftStrategyChange = async (draftStrategy: string) => { try { const snap = await invoke("apply_match_command", { - command: { ChangeFormation: { side: userSide, formation } }, + command: { ChangeDraftStrategy: { side: userSide, draft_strategy: draftStrategy } }, }); onUpdateSnapshot(snap); } catch (err) { - console.error("Formation change failed:", err); - } - }; - - const handlePlayStyleChange = async (playStyle: string) => { - try { - const snap = await invoke("apply_match_command", { - command: { ChangePlayStyle: { side: userSide, play_style: playStyle } }, - }); - onUpdateSnapshot(snap); - } catch (err) { - console.error("Play style change failed:", err); + console.error("Draft strategy change failed:", err); } }; @@ -404,40 +392,18 @@ export default function HalfTimeBreak({
{!isSpectator && ( <> - {/* Formation */} -
-

- {t("match.formation")} -

-
- {FORMATIONS.map((f) => ( - - ))} -
-
- {/* Play Style */}

- {t("match.playStyle")} + {t("match.draftStrategy")}

- {PLAY_STYLES.map((s) => ( + {DRAFT_STRATEGIES.map((s) => (
{snapshot.away_team.name}

-

{snapshot.away_team.formation}

@@ -342,20 +328,7 @@ export default function MatchLive({ {t('match.subs')} ({userSide === "Home" ? snapshot.home_subs_made : snapshot.away_subs_made}/{snapshot.max_subs})
-

{t('match.formation')}

-
- {["4-4-2", "4-3-3", "3-5-2", "4-5-1", "4-2-3-1", "3-4-3"].map(f => { - const cur = userSide === "Home" ? snapshot.home_team.formation : snapshot.away_team.formation; - return ( - - ); - })} -
-
-
-

{t('match.playStyle')}

+

{t('match.draftStrategy')}

{[ { id: "Balanced", icon: }, @@ -365,9 +338,9 @@ export default function MatchLive({ { id: "Counter", icon: }, { id: "HighPress", icon: }, ].map(s => { - const cur = userSide === "Home" ? snapshot.home_team.play_style : snapshot.away_team.play_style; + const cur = userSide === "Home" ? snapshot.home_team.draft_strategy : snapshot.away_team.draft_strategy; return ( - ); diff --git a/src/components/match/MatchPanels.tsx b/src/components/match/MatchPanels.tsx index 6f6ac87c8..a123078fd 100644 --- a/src/components/match/MatchPanels.tsx +++ b/src/components/match/MatchPanels.tsx @@ -188,10 +188,7 @@ export function Lineups({ snapshot }: { snapshot: MatchSnapshot }) {

- {team.name}{" "} - - ({team.formation}) - + {team.name}

{positions.map((pos) => { const players = team.players.filter((p) => (p.role ?? "") === pos); diff --git a/src/components/match/PostMatchScreen.test.tsx b/src/components/match/PostMatchScreen.test.tsx index e85559f28..42edd17f5 100644 --- a/src/components/match/PostMatchScreen.test.tsx +++ b/src/components/match/PostMatchScreen.test.tsx @@ -84,8 +84,7 @@ function makeSnapshot() { home_team: { id: "team1", name: "Alpha FC", - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", players: [ { id: "p1", @@ -128,8 +127,7 @@ function makeSnapshot() { away_team: { id: "team2", name: "Beta FC", - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", players: [ { id: "p2", @@ -234,8 +232,7 @@ function makeGameState() { transfer_budget: 500000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", @@ -264,8 +261,7 @@ function makeGameState() { transfer_budget: 500000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", @@ -429,21 +425,19 @@ function makeReportedFixture(id: string) { total_minutes: 90, home_stats: { possession_pct: 54, - shots: 13, - shots_on_target: 6, - fouls: 8, - corners: 5, - yellow_cards: 1, - red_cards: 0, + kills: 13, + deaths: 6, + gold_earned: 55000, + damage_dealt: 85000, + objectives: 5, }, away_stats: { possession_pct: 46, - shots: 9, - shots_on_target: 4, - fouls: 11, - corners: 3, - yellow_cards: 2, - red_cards: 0, + kills: 9, + deaths: 11, + gold_earned: 42000, + damage_dealt: 62000, + objectives: 3, }, events: [ { diff --git a/src/components/match/PostMatchScreen.tsx b/src/components/match/PostMatchScreen.tsx index b7e8238de..319f00ec5 100644 --- a/src/components/match/PostMatchScreen.tsx +++ b/src/components/match/PostMatchScreen.tsx @@ -143,13 +143,10 @@ export default function PostMatchScreen({ return null; } - const totalYellowCards = - report.home_stats.yellow_cards + report.away_stats.yellow_cards; - return [ `${report.home_stats.possession_pct}-${report.away_stats.possession_pct} ${t("match.possession")}`, - `${report.home_stats.shots + report.away_stats.shots} ${t("match.shots")}`, - `${totalYellowCards} ${t("match.yellowCards")}`, + `${report.home_stats.kills + report.away_stats.kills} ${t("match.kills")}`, + `${report.home_stats.deaths + report.away_stats.deaths} ${t("match.deaths")}`, ].join(" • "); }; const formatOtherMatchEvent = (event: CompactMatchEventData) => { @@ -848,29 +845,29 @@ export default function PostMatchScreen({ } />
diff --git a/src/components/match/PreMatchLineup.test.tsx b/src/components/match/PreMatchLineup.test.tsx index 4d52d80fc..4c6f5bea9 100644 --- a/src/components/match/PreMatchLineup.test.tsx +++ b/src/components/match/PreMatchLineup.test.tsx @@ -5,7 +5,6 @@ import PreMatchLineup, { condColor, getPlayerLolRole, getPositionOvr, - parseFormationNeeds, statColor, } from "./PreMatchLineup"; import type { EnginePlayerData, EngineTeamData } from "./types"; @@ -48,8 +47,7 @@ const makePlayer = (overrides: Partial = {}): EnginePlayerData const makeTeam = (overrides: Partial = {}): EngineTeamData => ({ id: "team1", name: "Test FC", - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", players: [ makePlayer({ id: "top", name: "Top One", role: "Top" }), makePlayer({ id: "jg", name: "Jg One", role: "Jungle" }), @@ -84,10 +82,6 @@ describe("PreMatchLineup helpers", () => { expect(getPositionOvr(player)).toBe(Math.round((80 + 70 + 75 + 65 + 60 + 70 + 68 + 72 + 74) / 9)); }); - it("returns fixed LoL role needs", () => { - expect(parseFormationNeeds("anything")).toEqual({ TOP: 1, JUNGLE: 1, MID: 1, ADC: 1, SUPPORT: 1 }); - }); - it("keeps condition/stat color helpers", () => { expect(condColor(90)).toBe("text-primary-400"); expect(condColor(60)).toBe("text-amber-400"); diff --git a/src/components/match/PreMatchLineup.tsx b/src/components/match/PreMatchLineup.tsx index 387b879aa..26aeaa6fa 100644 --- a/src/components/match/PreMatchLineup.tsx +++ b/src/components/match/PreMatchLineup.tsx @@ -91,16 +91,6 @@ const LOL_ROLE_ICON_URLS: Record = { SUPPORT: "https://raw.communitydragon.org/latest/plugins/rcp-fe-lol-clash/global/default/assets/images/position-selector/positions/icon-position-utility.png", }; -export function parseFormationNeeds(_formation: string): Record { - return { - TOP: 1, - JUNGLE: 1, - MID: 1, - ADC: 1, - SUPPORT: 1, - }; -} - interface PreMatchLineupProps { homeTeam: MatchSnapshot["home_team"]; homeBench: EnginePlayerData[]; @@ -366,7 +356,7 @@ export default function PreMatchLineup({
- {t("match.formationFit")} + {t("match.roleCoverage")} {LOL_ROLE_ORDER.map((role) => { const homeCount = homeTeam.players.filter((p) => getPlayerLolRole(p) === role).length; diff --git a/src/components/match/PreMatchSetup.tsx b/src/components/match/PreMatchSetup.tsx index 2bcecb477..70ad99ac2 100644 --- a/src/components/match/PreMatchSetup.tsx +++ b/src/components/match/PreMatchSetup.tsx @@ -114,7 +114,7 @@ export default function PreMatchSetup({ benchCount: (snapshot.home_bench || []).length, homeTeam: snapshot.home_team.name, phase: snapshot.phase, - playStyle: userTeam.play_style, + draftStrategy: userTeam.draft_strategy, selectedStarterId, startingPlayerCount: userTeam.players.length, userSide, diff --git a/src/components/match/PressConference.test.tsx b/src/components/match/PressConference.test.tsx index 61db7e562..7c30632bb 100644 --- a/src/components/match/PressConference.test.tsx +++ b/src/components/match/PressConference.test.tsx @@ -120,15 +120,13 @@ function makeSnapshot(overrides: Partial = {}): MatchSnapshot { home_team: { id: "fnc", name: "Fnatic", - formation: "1-1-1-2", - play_style: "Objective control", + draft_strategy: "Objective control", players: [makePlayer("adc1", "Rekkles", "ADC"), makePlayer("sup1", "Support", "SUPPORT")], }, away_team: { id: "g2", name: "G2 Esports", - formation: "1-1-1-2", - play_style: "Skirmish", + draft_strategy: "Skirmish", players: [makePlayer("enemy1", "Hans", "ADC")], }, home_bench: [], @@ -163,7 +161,7 @@ function makeGameState(): GameStateData { satisfaction: 50, fan_approval: 50, team_id: "fnc", - career_stats: { matches: 0, wins: 0, draws: 0, losses: 0, trophies: 0, matches_managed: 0, best_finish: null }, + career_stats: { matches: 0, wins: 0, losses: 0, trophies: 0, matches_managed: 0, best_finish: null }, career_history: [], }, teams: [], diff --git a/src/components/match/SubPanel.tsx b/src/components/match/SubPanel.tsx index c67b58840..8bb0913c6 100644 --- a/src/components/match/SubPanel.tsx +++ b/src/components/match/SubPanel.tsx @@ -44,24 +44,6 @@ export function SubPanel({ const positions = ["Goalkeeper", "Defender", "Midfielder", "Forward"]; - // Parse formation to get expected counts per position - const parts = team.formation.split("-").map(Number); - const expectedCounts: Record = { - Goalkeeper: 1, - Defender: 0, - Midfielder: 0, - Forward: 0, - }; - if (parts.length === 3) { - expectedCounts.Defender = parts[0]; - expectedCounts.Midfielder = parts[1]; - expectedCounts.Forward = parts[2]; - } else if (parts.length === 4) { - expectedCounts.Defender = parts[0]; - expectedCounts.Midfielder = parts[1] + parts[2]; - expectedCounts.Forward = parts[3]; - } - const getOvr = (p: EnginePlayerData) => { const vals = [ p.mental_resilience, diff --git a/src/components/match/draftResultSimulator.ts b/src/components/match/draftResultSimulator.ts index 0107f206d..87bb731a6 100644 --- a/src/components/match/draftResultSimulator.ts +++ b/src/components/match/draftResultSimulator.ts @@ -187,25 +187,22 @@ function toEnginePlayerFromState( champion_pool: player.attributes.champion_pool, discipline: player.attributes.discipline, mental_resilience: player.attributes.mental_resilience, - pace: player.attributes.pace, + pace: player.attributes.mechanics, stamina: player.attributes.mental_resilience, - strength: player.attributes.strength, + strength: player.attributes.mental_resilience, agility: player.attributes.champion_pool, - passing: player.attributes.passing, + passing: player.attributes.teamfighting, shooting: player.attributes.laning, - tackling: player.attributes.tackling, + tackling: player.attributes.macro_play, dribbling: player.attributes.mechanics, - defending: player.attributes.defending, - positioning: player.attributes.positioning, + defending: player.attributes.discipline, + positioning: player.attributes.consistency, vision: player.attributes.macro_play, decisions: player.attributes.consistency, composure: player.attributes.discipline, - aggression: player.attributes.aggression, + aggression: player.attributes.shotcalling, teamwork: player.attributes.teamfighting, leadership: player.attributes.shotcalling, - handling: player.attributes.handling, - reflexes: player.attributes.reflexes, - aerial: player.attributes.aerial, traits: player.traits, }; } diff --git a/src/components/match/helpers.test.ts b/src/components/match/helpers.test.ts index ac40757da..dfa5912ba 100644 --- a/src/components/match/helpers.test.ts +++ b/src/components/match/helpers.test.ts @@ -42,8 +42,7 @@ const makePlayer = (overrides: Partial = {}): EnginePlayerData const makeTeam = (overrides: Partial = {}): EngineTeamData => ({ id: "team1", name: "Test FC", - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", players: [], ...overrides, }); diff --git a/src/components/match/lol-prototype/engine/simulation.ts b/src/components/match/lol-prototype/engine/simulation.ts index b4239e291..a688a0140 100644 --- a/src/components/match/lol-prototype/engine/simulation.ts +++ b/src/components/match/lol-prototype/engine/simulation.ts @@ -618,7 +618,7 @@ export class PrototypeSimulation { if (parsed) return parsed; } - const style = teamData.play_style; + const style = teamData.draft_strategy; if (style === "HighPress" || style === "Attacking" || style === "Counter") return "red"; if (style === "Defensive" || style === "Possession") return "blue"; return team === "blue" ? "blue" : "red"; @@ -1855,7 +1855,7 @@ export class PrototypeSimulation { } private styleAggro(team: TeamId) { - const style = team === "blue" ? this.snapshot.home_team.play_style : this.snapshot.away_team.play_style; + const style = team === "blue" ? this.snapshot.home_team.draft_strategy : this.snapshot.away_team.draft_strategy; switch (style) { case "HighPress": return 1.12; case "Attacking": return 1.08; diff --git a/src/components/match/types.ts b/src/components/match/types.ts index 949bec65a..92f7ed437 100644 --- a/src/components/match/types.ts +++ b/src/components/match/types.ts @@ -111,7 +111,7 @@ export interface EnginePlayerData { name: string; profile_image_url?: string | null; role?: string; - /** @deprecated Legacy football test fixture field. */ + /** @deprecated Legacy test fixture field. */ position?: string; condition: number; fitness: number; @@ -125,7 +125,7 @@ export interface EnginePlayerData { discipline: number; mental_resilience: number; traits: string[]; - /** @deprecated Legacy football attributes retained for fixture compatibility. */ + /** @deprecated Legacy attributes retained for fixture compatibility. */ pace?: number; stamina?: number; strength?: number; @@ -150,8 +150,7 @@ export interface EnginePlayerData { export interface EngineTeamData { id: string; name: string; - formation: string; - play_style: string; + draft_strategy: string; players: EnginePlayerData[]; } @@ -319,13 +318,11 @@ export const SPEED_MS: Record = { instant: 10, }; -export const FORMATIONS = ["4-4-2", "4-3-3", "3-5-2", "4-5-1", "4-2-3-1", "3-4-3"]; - -export const PLAY_STYLES = [ +export const DRAFT_STRATEGIES = [ { id: "Balanced", label: "Balanced" }, - { id: "Attacking", label: "Attacking" }, - { id: "Defensive", label: "Defensive" }, - { id: "Possession", label: "Possession" }, - { id: "Counter", label: "Counter" }, - { id: "HighPress", label: "High Press" }, + { id: "Aggressive", label: "Aggressive" }, + { id: "Passive", label: "Passive" }, + { id: "Scaling", label: "Scaling" }, + { id: "CounterPick", label: "Counter Pick" }, + { id: "PriorityBans", label: "Priority Bans" }, ]; diff --git a/src/components/news/NewsTab.test.tsx b/src/components/news/NewsTab.test.tsx index eb919d206..30e2c67e3 100644 --- a/src/components/news/NewsTab.test.tsx +++ b/src/components/news/NewsTab.test.tsx @@ -42,8 +42,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", @@ -91,7 +90,6 @@ function createGameState(news: NewsArticle[]): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/playerProfile/PlayerProfile.helpers.test.ts b/src/components/playerProfile/PlayerProfile.helpers.test.ts index 04a3f6e46..dbcf4691d 100644 --- a/src/components/playerProfile/PlayerProfile.helpers.test.ts +++ b/src/components/playerProfile/PlayerProfile.helpers.test.ts @@ -26,8 +26,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", diff --git a/src/components/playerProfile/PlayerProfile.test.tsx b/src/components/playerProfile/PlayerProfile.test.tsx index 92c6fadfc..da34179e5 100644 --- a/src/components/playerProfile/PlayerProfile.test.tsx +++ b/src/components/playerProfile/PlayerProfile.test.tsx @@ -141,8 +141,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", @@ -239,7 +238,6 @@ function createGameState(player: PlayerData): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/playerProfile/PlayerProfileHeroCard.test.tsx b/src/components/playerProfile/PlayerProfileHeroCard.test.tsx index 896d77b3d..92ddaec5c 100644 --- a/src/components/playerProfile/PlayerProfileHeroCard.test.tsx +++ b/src/components/playerProfile/PlayerProfileHeroCard.test.tsx @@ -59,7 +59,6 @@ function makePlayer(overrides?: Partial): PlayerData { interceptions: 0, fouls_committed: 0, fouls_suffered: 0, - offsides: 0, saves: 0, goals_conceded: 0, penalties_scored: 0, diff --git a/src/components/playerProfile/PlayerProfileHeroCard.tsx b/src/components/playerProfile/PlayerProfileHeroCard.tsx index 381095a06..ecc2fe216 100644 --- a/src/components/playerProfile/PlayerProfileHeroCard.tsx +++ b/src/components/playerProfile/PlayerProfileHeroCard.tsx @@ -3,7 +3,7 @@ import { EyeOff, Pencil, Shield, User } from "lucide-react"; import type { PlayerData } from "../../store/gameStore"; import { formatPlayerMarketValue, formatPlayerWage } from "./PlayerProfile.helpers"; import { resolvePlayerPhoto } from "../../lib/playerPhotos"; -import { resolveExampleTeamLogo } from "../../lib/teamLogos"; +import { resolveTeamLogo } from "../../lib/teamLogos"; import type { PlayerProfileScoutStatus, ScoutAvailability, @@ -267,7 +267,7 @@ export default function PlayerProfileHeroCard({ ) : null}

{(() => { - const logoUrl = resolveExampleTeamLogo(teamName); + const logoUrl = resolveTeamLogo(teamName); return logoUrl ? ( {teamName} ) : ( diff --git a/src/components/players/PlayersListTab.test.tsx b/src/components/players/PlayersListTab.test.tsx index 532e35a0d..718915853 100644 --- a/src/components/players/PlayersListTab.test.tsx +++ b/src/components/players/PlayersListTab.test.tsx @@ -52,8 +52,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", @@ -143,7 +142,6 @@ function createGameState(): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/schedule/ScheduleCalendarView.test.tsx b/src/components/schedule/ScheduleCalendarView.test.tsx index 9dbf3ed64..68e0c5d18 100644 --- a/src/components/schedule/ScheduleCalendarView.test.tsx +++ b/src/components/schedule/ScheduleCalendarView.test.tsx @@ -34,8 +34,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Scrims", training_intensity: "Balanced", training_schedule: "Balanced", @@ -89,7 +88,6 @@ function createGameState(userTeamOverrides: Partial = {}): GameStateDa career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/schedule/ScheduleTab.test.tsx b/src/components/schedule/ScheduleTab.test.tsx index f8ab11497..1c4da385f 100644 --- a/src/components/schedule/ScheduleTab.test.tsx +++ b/src/components/schedule/ScheduleTab.test.tsx @@ -15,7 +15,7 @@ vi.mock("react-i18next", () => ({ useTranslation: () => ({ t: (key: string, params?: Record) => { if (key === "schedule.noLeague") return "No league"; - if (key === "schedule.fixtures") return "Fixtures"; + if (key === "schedule.matches") return "Fixtures"; if (key === "schedule.standings") return "Standings"; if (key === "common.team") return "Team"; if (key === "common.played") return "P"; @@ -56,8 +56,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "General", training_intensity: "Balanced", training_schedule: "Balanced", @@ -108,7 +107,6 @@ function createGameState(withLeague: boolean): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, @@ -134,20 +132,18 @@ function createGameState(withLeague: boolean): GameStateData { team_id: "team-1", played: 1, won: 1, - drawn: 0, - lost: 0, - goals_for: 2, - goals_against: 1, + lost: 0, + maps_won: 2, + maps_lost: 1, points: 3, }, { team_id: "team-2", played: 1, won: 0, - drawn: 0, - lost: 1, - goals_for: 1, - goals_against: 2, + lost: 1, + maps_won: 1, + maps_lost: 2, points: 0, }, ], diff --git a/src/components/schedule/ScheduleTab.tsx b/src/components/schedule/ScheduleTab.tsx index acc049152..07fc74a49 100644 --- a/src/components/schedule/ScheduleTab.tsx +++ b/src/components/schedule/ScheduleTab.tsx @@ -182,7 +182,7 @@ export default function ScheduleTab({ }`} > {" "} - {t("schedule.fixtures")} + {t("schedule.matches")} @@ -274,7 +274,7 @@ export default function TournamentsTab({ - {t("schedule.fixtures")} + {t("schedule.matches")} {sortedMatchdays.length === 0 ? (

diff --git a/src/components/training/TrainingGroupsCard.test.tsx b/src/components/training/TrainingGroupsCard.test.tsx index a18eccb7a..6094e1876 100644 --- a/src/components/training/TrainingGroupsCard.test.tsx +++ b/src/components/training/TrainingGroupsCard.test.tsx @@ -49,8 +49,7 @@ function createTeam(overrides: Partial & { training_groups?: unknown } transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Scrims", training_intensity: "Medium", training_schedule: "Balanced", @@ -140,7 +139,6 @@ function createGameState(team: TeamData): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/training/TrainingTab.test.tsx b/src/components/training/TrainingTab.test.tsx index 6deb7ce33..1dc0df079 100644 --- a/src/components/training/TrainingTab.test.tsx +++ b/src/components/training/TrainingTab.test.tsx @@ -63,8 +63,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 250000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Scrims", training_intensity: "Medium", training_schedule: "Balanced", @@ -154,7 +153,6 @@ function createGameState(withTeam: boolean): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/transfers/TransferBidModal.test.tsx b/src/components/transfers/TransferBidModal.test.tsx index b5dcdc95d..6519ceb93 100644 --- a/src/components/transfers/TransferBidModal.test.tsx +++ b/src/components/transfers/TransferBidModal.test.tsx @@ -68,8 +68,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 2000000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", diff --git a/src/components/transfers/TransferCounterOfferModal.test.tsx b/src/components/transfers/TransferCounterOfferModal.test.tsx index be366344a..1114323d8 100644 --- a/src/components/transfers/TransferCounterOfferModal.test.tsx +++ b/src/components/transfers/TransferCounterOfferModal.test.tsx @@ -50,8 +50,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 2000000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", diff --git a/src/components/transfers/TransfersTab.model.test.ts b/src/components/transfers/TransfersTab.model.test.ts index a93ad499e..424702478 100644 --- a/src/components/transfers/TransfersTab.model.test.ts +++ b/src/components/transfers/TransfersTab.model.test.ts @@ -24,8 +24,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 2000000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", @@ -127,7 +126,6 @@ function createGameState(players: PlayerData[]): GameStateData { career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/transfers/TransfersTab.test.tsx b/src/components/transfers/TransfersTab.test.tsx index 1d41e5dad..d6dc547a5 100644 --- a/src/components/transfers/TransfersTab.test.tsx +++ b/src/components/transfers/TransfersTab.test.tsx @@ -84,8 +84,7 @@ function createTeam(overrides: Partial = {}): TeamData { transfer_budget: 2000000, season_income: 0, season_expenses: 0, - formation: "4-4-2", - play_style: "Balanced", + draft_strategy: "Balanced", training_focus: "Physical", training_intensity: "Medium", training_schedule: "Balanced", @@ -199,7 +198,6 @@ function createGameState(players: PlayerData[] = [createPlayer()]): GameStateDat career_stats: { matches_managed: 0, wins: 0, - draws: 0, losses: 0, trophies: 0, best_finish: null, diff --git a/src/components/worldEditor/WorldEditorTab.tsx b/src/components/worldEditor/WorldEditorTab.tsx index 7270eef00..16166b2e3 100644 --- a/src/components/worldEditor/WorldEditorTab.tsx +++ b/src/components/worldEditor/WorldEditorTab.tsx @@ -189,11 +189,10 @@ function createNewPlayer(index: number): PlayerData { full_name: "Nuevo Jugador", date_of_birth: "2005-01-01", nationality: "KR", - football_nation: "KR", birth_country: "KR", profile_image_url: null, - position: "Midfielder", - natural_position: "Midfielder", + position: "SUPPORT", + natural_position: "SUPPORT", alternate_positions: [], footedness: "Right", weak_foot: 2, @@ -273,7 +272,7 @@ export default function WorldEditorTab({ onBack }: WorldEditorTabProps) { setWorld(loaded); setSelectedPlayerId(loaded.players[0]?.id ?? ""); setSelectedStaffId(loaded.staff[0]?.id ?? ""); - if (sourcePath) setPath(sourcePath === "lec-default" ? "" : sourcePath); + if (sourcePath) setPath(sourcePath === "default" ? "" : sourcePath); setStatus(`Mundo cargado: ${loaded.name}`); } catch (err) { setError(String(err)); @@ -552,7 +551,7 @@ export default function WorldEditorTab({ onBack }: WorldEditorTabProps) {

- +