PokeWG — Números de Combate SÓ LEITURA

Extraído de ~/pokeidle-web-staging (staging). Dados: data/creatures.json. Fórmulas: lib/combat.ts, lib/hunt.ts, lib/pokemon.ts, server/combat.ts, lib/pxg-pvp.ts, lib/pvp-sim.ts, lib/gym-battle.ts.

? Como funciona o combate

Velocidade de ataque

Na HUNT (PvE) a speed NÃO altera a frequência de ataque. O combate é por turnos fixos: a cada turno o aliado bate 1×, o selvagem revida 1×. Existe um relógio virtual só para os cooldowns:

STEP = 900 ms (relógio virtual por turno) MAX_TURNS = 40 (trava de abate) por turno: aliado ataca → selvagem revida

A speed é calculada como stat (statReal) e guardada no Pokémon, mas não entra no loop de dano da hunt — todos batem 1×/turno independentemente da velocidade.

PvP é diferente: lá a speed vira velocidade de locomoção (ms por tile) e prioridade de quem age primeiro — não reduz cooldown de golpe. Ver a seção PvP abaixo.

server/combat.ts (loop de turno) · lib/pxg-pvp.ts:66-84 · lib/pvp-sim.ts:84

Dano base → dano real

Núcleo estilo Pokémon (lib/combat.ts → damage()). Sem crítico na HUNT, de propósito (Rafael 30/07):

A = golpe SPECIAL ? spAtk : atk D = golpe SPECIAL ? spDef : def base = ((2·nível/5 + 2) · power · (A / D)) / 50 + 2 dano = round( base · STAB · tipo · rand(0.85–1.0) ) STAB = 1.5 se tipo do golpe == tipo do Pokémon tipo = tabela de efetividade Gen6

Os stats A/D/HP vêm de statReal (nível + IV + qualidade):

// lib/pokemon.ts statReal = round( (nível/100)·(base + 2·IV) · qualidade^expo ) expo = 0.95 (HP e Speed) · 0.80 (Atk/Def/SpAtk/SpDef) combatHp = max(24, round(hpStat · (inimigo ? 7 : 12)))

Na HUNT o dano recebe multiplicadores fixos (server/combat.ts) + amplificação de tipo (huntTypeAmp, lib/combat.ts):

DMG_SCALE = 0.85 (todo dano da hunt) HP selvagem reforçado · vantagem de tipo AMPLIFICADA: ×2 → ×2.5 · ×4 → ×5.5 · ×0.5 → ×0.33 (÷1.5) imunidade (×0) e neutro (×1) não mudam

O aliado luta no nível do TREINADOR (capado nele), não no nível do bicho — allyCombat() em lib/hunt.ts.

lib/combat.ts damage()/huntTypeAmp() · lib/pokemon.ts:93 combatHp · lib/hunt.ts allyCombat

Cooldowns

Cada golpe tem cooldownMs no catálogo (creatures.json). No combate é um mapa por NOME do golpe:

cds[golpe] = t + golpe.cooldownMs pickAttack prefere golpes com cds[golpe] ≤ agora relógio: t += 900 ms por turno → cd de 5000 ms ≈ pronto de novo a cada ~6 turnos

Não é afetado por speed. É por golpe (não compartilhado entre golpes diferentes). Na HUNT usa noBasic:true: se todos os golpes estão em cooldown, reusa a melhor skill (não cai no Ataque Básico fraco).

// PvP tem piso de cooldown por power (lib/pxg-pvp.ts:137) pvpCooldownMs = max(cooldownMs, round(power/5 · 1000)) Ataque Básico PvP: cd 2300 ms · melee floor 1500 ms

server/combat.ts pickAttack calls · lib/combat.ts:47 pickAttack() · lib/pxg-pvp.ts:137

4 Skills por Pokémon — a regra das 4

Como o jogo escolhe as 4 skills — a regra REAL

Não existe um CAP de 4 no código. Nenhum arquivo corta o moveset em 4. Procurei em lib/hunt.ts, lib/combat.ts, server/combat.ts, server/boss-arena.ts, lib/gym-battle.ts, lib/pvp-sim.ts, lib/pxg-pvp.ts, scripts/, app/ e server/*.mjs — não há slice(0,4) nem seleção de "as 4 melhores". O jogo usa TODOS os golpes já aprendidos:

// o único filtro em TODO ponto de combate é o nível: attacks.filter(a => a.power > 0 && a.learnLevel <= level) lib/hunt.ts:310-312 attacksFor(speciesId, level) → filtra por learnLevel lib/combat.ts:48 pickAttack: all = atk.attacks.filter(a => a.power>0 && a.learnLevel<=atk.level) server/combat.ts:220 ally: attacks.filter(a => a.learnLevel <= ac.level) server/combat.ts:221 wild: attacksFor(wild.speciesId, wild.level) lib/gym-battle.ts:36 Fighter.c.attacks = (c.attacks||[]).filter(a => a.learnLevel <= level)

O "4 skills" é uma convenção de DADO, não de código. No data/creatures.json (349 espécies): 273 têm exatamente 4 golpes. As demais têm menos (Ditto 0, Magikarp 1, Caterpie/Weedle 3) ou mais72 espécies têm 5 a 11 golpes (toda a leva de Gen 3 / Hoenn 132xx–133xx e Riolu/Lucario 13447/13448, que entraram com o moveset completo do idleworld e nunca foram aparadas). O corte "pra 4" foi feito editando o dado das 273 originais, não no motor — confirmado pelo comentário lib/pxg-pvp.ts:315: "quando os movesets foram cortados pra 4 golpes".

maxLearnLevel = 70 em todo o catálogo. Como o aliado luta no nível do treinador (que passa de 70 fácil), na prática todos os golpes da espécie ficam disponíveis. Por isso a tabela abaixo mostra o moveset COMPLETO por espécie: no nível alto, é exatamente o conjunto de golpes que o Pokémon pode usar. Em níveis baixos, só entram os de learnLevel ≤ nível.

Qual dos golpes SAI a cada ataque (a "rotação"): entre os que estão fora de cooldown, o de maior dano efetivo contra o alvo. lib/combat.ts:71-86 pickAttack:

score(golpe) = power · (A/D) · STAB · efetividade_de_tipo · área A/D = atk/def ou spAtk/spDef conforme a categoria STAB = 1.5 se o tipo do golpe casa com o do Pokémon área = 2.5 SÓ se aglomerado (>2 selvagens) e o golpe é AoE sem alvo → escolhe o de maior power bruto todos em cooldown → HUNT reusa a melhor (noBasic) · DUELO cai no Ataque Básico

Só 1 golpe no catálogo tem flag de área (aoe): "10,000,000 Volt Thunderbolt" do Ash Pikachu (dex 10025). O peso de área (2,5) entra no mesmo score, então nunca ignora a regra de tipo (imune continua imune). lib/combat.ts:74-86

Pokémon Tipos Arquétipo PvP Golpes Maior power Skills (nome · dano · cd)

Clique numa linha (ou aperte Enter/Espaço com ela focada) para expandir as skills com nome · tipo · categoria · dano (power) · cooldown · nível que aprende. A coluna resumo mostra até 4 na própria linha.

V PvP — combate ponta a ponta

Modo usado no Duelo de Ginásio 6v6 (ao vivo, com troca de Pokémon) e no X1 na cidade (pré-computado). PvE não passa por aqui (hunt/boss/líder/altar ficam em lib/combat.ts). Motor em tempo contínuo inspirado no engine TFS do PXG — não há turnos: cada criatura tem dois relógios independentes, um de passo (andar) e um de ataque. Andar nunca custa golpe e atacar nunca custa passo — é daí que emerge o kiting. lib/pxg-pvp.ts:1-25 · lib/pvp-sim.ts:1-13

1 · Arquétipo (define como anda)

Sai do eixo spAtk vs atk (o mesmo que decide a categoria do básico):

r = spAtk / atk r ≥ 1.25 → KITER (atira e recua) r ≤ 0.80 → MELEE (cola e bate) resto → HYBRID (fica perto, bate)
  • Split das espécies: ~87 KITER · ~106 HYBRID · ~131 MELEE.
  • Auto-correção: KITER sem nenhum golpe à distância (SPECIAL) vira MELEE — não teria como kitar. pxg-pvp.ts:45-49
  • Brigões forçados a MELEE por espécie: BRAWLER_SPECIES = {125} (Electabuzz) — magia elétrica é ranged mas o design é brawler. pxg-pvp.ts:57
  • Alcance do golpe: SPECIAL = à distância (range 0) · PHYSICAL = adjacente (range 1). pxg-pvp.ts:41

pxg-pvp.ts:34-58 · pvp-sim.ts:50 mkSide

2 · Velocidade → locomoção (ms por tile)

A speed (stat já calculado) vira o tempo pra atravessar 1 tile. Fórmula do TFS (creature.cpp:1393):

s = clamp(speed, 60, 900) calc = max(1, floor(857.36·ln(s/2 + 261.29) − 4795.01 + 0.5)) stepMs = ceil( floor(1000·150 / calc) / 50 ) · 50 // quantizado em 50 ms

Depois o passo é ajustado por arquétipo (piso/teto pra nunca teleportar):

pvpStepMs(speed, arch): KITER → clamp(stepMs, 400, 900) // anda de propósito ~12% + devagar MELEE/HYBRID → clamp(round(stepMs·0.90), 350, 900)
Constantes da curvaSPEED_A 857.36 · SPEED_B 261.29 · SPEED_C −4795.01 · GROUND 150
Passo diagonal× 3 (DIAGONAL_MULT) — diagonal custa 3 passos
Piso melee / rangedSTEP_MELEE_FLOOR 350 · STEP_RANGED_FLOOR 400
Teto do passoSTEP_CEIL 900
Bônus de passo melee× 0.90 (MELEE_STEP_MULT) — anda 10% + rápido que o stat
Trava de animaçãoATTACK_LOCK_MS 350 — ao atacar, congela o passo 350 ms
Perseguição (fechar gap)passo = max(CHASE_FLOOR 275, round(passo_do_alvo · CHASE_MULT 0.62)) → ~38% + rápido, garante que o melee pega o kiter

pxg-pvp.ts:62-111 · pvp-sim.ts:52-53,109-111

3 · Cadência de ataque (THINK / CHANCE / LOCK)

O ataque não é avaliado a todo instante. Roda no "think" a cada 1 s e o golpe pronto ainda passa por um sorteio de 40% (o valor do datapack inteiro do PXG):

ATTACK_THINK_MS = 1000 // reavalia se ataca a cada 1 s ATTACK_CHANCE = 40 % // do golpe pronto realmente sair falhou o sorteio → NÃO consome cooldown, tenta no próximo think ATTACK_LOCK_MS = 350 // trava o movimento ao atacar
  • Primeiro ataque garantido: no início do duelo / logo após uma troca (nextThink==0), o golpe sai sem o sorteio de 40% — a luta já começa soltando magia. pvp-sim.ts:130
  • Ataque Básico não sorteia: quando nenhuma magia está pronta, o básico SEMPRE sai (preenche os buracos de cooldown). Só as magias passam pelo 40%. pvp-sim.ts:134-137
  • Ordem no tick: o de maior speed age primeiroorder = a.speed >= b.speed ? [a,b] : [b,a]. pvp-sim.ts:84
  • Dodge: 8% de esquiva (DODGE_CHANCE 0.08) → dano 0 + "Dodge!". pxg-pvp.ts:101-103 · pvp-sim.ts:142

pxg-pvp.ts:74-84 · pvp-sim.ts:123-146

4 · Cooldown de PvP e Ataque Básico

No PvP cada magia ganha um piso de cooldown proporcional ao power (o dado no creatures.json fica intacto — só o PvP sente):

PVP_MAX_DPS = 5 // teto de power por segundo de recarga pvpCooldownMs(golpe) = max( golpe.cooldownMs, round(power / 5 · 1000) ) ex.: power 120 → piso 24 000 ms mesmo se o cd bruto for menor

O Ataque Básico do PvP é derivado da espécie:

power = clamp(round(atk · 0.5), 20, 70) tipo = type1 categoria = spAtk > atk ? SPECIAL : PHYSICAL cooldown = 2300 ms (auto-ataque; sem piso por power) melee floor entre golpes corpo-a-corpo = 1500 ms básico MELEE físico bate +15% (meleeBasicBonus 1.15)

Ex.: Machamp (atk 130) → básico power 65 (rivaliza com skill) · Alakazam (atk 50) → power 25 (só chip).

pxg-pvp.ts:113-138 · pvp-sim.ts:140,144-146

5 · Dano no PvP (mitigação PXG)

Diferente do PvE: efetividade é ±1.5 FLAT (não ×2/×4), dual-type não empilha, sem STAB, e a defesa amortece de leve:

flatEff(tipo): imune → 0 · vantagem → 1.5 · resistência → 1/1.5 · neutro → 1 defDamp(D) = clamp(1 − D/600, 0.5, 1) A = SPECIAL ? spAtk : atk D = SPECIAL ? spDef : def base = ((2·nível/5 + 2) · power · (A/D)) / 50 + 2 crit = 1% (×1.5) · block = 1% (×0) · roll = rand(0.85–1.0) dano = round( base · flatEff · defDamp(D) · roll · crit · PVP_DMG_SCALE ) × DMG_SCALE(0.5) × (básico melee físico ? 1.15 : 1) dodge (8%) → 0
PVP_DMG_SCALE6.0 — subiu de 4.5 quando os movesets foram cortados pra 4 (menos golpes = luta mais longa)
DMG_SCALE (pvp-sim)0.5
crit / block1% cada (crit ×1.5 · block ×0)
dodge8% → dano 0

pxg-pvp.ts:300-330 (dano) :318 (scale) · pvp-sim.ts:142-146,154

6 · HP, arena e escolha de golpe

HP do lutadorcombatHp = max(24, round(hpStat · 12)) pros dois lados gym-battle.ts:36 · pokemon.ts:93
HP e cooldown persistemviajam com o POKÉMON no 6v6: quem sai e volta mantém vida e recarga pvp-sim.ts:41-47,69-76
Escolha de golpepickAttackAt: entre os PRONTOS que alcançam a distância, maior power·(A/D)·flatEff; nenhum → básico se alcança, senão anda pxg-pvp.ts:287-298
AlcanceusableAt: ranged sempre · melee só a Chebyshev ≤ 1 (adjacente, inclui diagonal) pxg-pvp.ts:282-284
ArenaARENA_RADIUS 4 · START_GAP 4 · SIM_DT 50 ms · SIM_MAX_MS 90000 pxg-pvp.ts:333-338
Distância que cada arquétipo mantémKITER 5 · HYBRID 1 · MELEE 1 (PREFER) · KITE_TRIGGER 3 pxg-pvp.ts:52,60
Fuga por vida baixadesligada: FLEE_HP = 0 (luta até o fim; só "foge" com HP≤0 = morto). FLEE_DIST 3 pxg-pvp.ts:161-163
Movimento vivoJOCKEY_MS 1600 (circula o alvo) · SKIRMISH_MS 2200 (hit-and-run) — na v3 o tick só usa jockey, sem dash pxg-pvp.ts:209,217 · pvp-sim.ts:95,105
Investida (dash)constantes existem (DASH_CD_MS 9000 · DASH_TILES 3) mas desativadas na v3 — aproximação 100% gradual pxg-pvp.ts:262-263 · pvp-sim.ts:95-98
Talentos de guildNÃO valem no PvP — a ausência do import é o gate pvp-sim.ts:9-13

PPokémon — status base

Pokémon Tipos Arq. Speed Atk SpAtk Def SpDef HP BST

GGolpes / Magias

Golpe Tipo Categoria Power Cooldown CD PvP Pwr/s Nível Espécies