- AZeusFrontierOverlayActor: paredes (ProceduralMesh, material de portal) em
todas as fronteiras do grid; label DrawDebugString no centro de cada cell com
notacao de quadtree ("Cell 0" / "Cell 0,2" pos-split) + nome do servidor.
- UZeusAOIComponent: liga via toggle "Fronteiras (Mesh)" / CVar zeus.debug.frontier,
spawna/atualiza o ator, re-pede o 6163 a cada 2s (reflete split/merge).
- ZMMO.Build.cs: + ProceduralMeshComponent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
[YAW-BODY-ORIENT] commit conjunto cliente + servidor.
Sintoma: ao apertar D o proxy virava ~45 graus de uma vez, em vez de virar
igual ao player local (suave, so um pouco), e parado seguia o mouse.
Raiz: a fonte de verdade do yaw estava errada. O servidor derivava
simpleYawDeg de atan2(velocidade) INSTANTANEO ao mover (snap pra direcao do
movimento) e da mira (ControlRotation) ao parar -- nenhum dos dois e o yaw
do corpo do dono.
Correcao ponta-a-ponta:
- Cliente: envia GetActorRotation().Yaw (yaw do CORPO; o CMC ja orienta pra
direcao do movimento a 500 deg/s e bUseControllerRotationYaw=false faz o
MOUSE nao girar o corpo) no lugar de GetControlRotation().Yaw.
- Servidor: usa o yaw recebido DIRETO em simpleYawDeg (remove atan2
instantaneo + mira-no-idle).
- Proxy: replica Snapshot.YawDeg interpolado shortest-path (remove a
derivacao por Atan2 da velocidade).
Resultado: o proxy vira identico ao corpo do dono e o mouse nao gira o corpo.
Futuro (aim/combate/Motion Matching): adicionar um campo aimYawDeg dedicado em
vez de reusar este.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Player remoto parado nao gera DELTA_BATCH (ComputeDelta suprime no server) -> o
proxy fica "mudo": NewestMs congela, renderLagMs cresce 1:1 com o wall-clock ->
extrapola sempre -> "anda no lugar" (moonwalk) e salta quando o player volta.
Provado em log (secsSinceSnap subindo enquanto o remoto esta moving=0). NAO e'
clock errado nem self-proxy (red-herrings descartados); o seed do relogio esta' OK.
- Tick: quando faminto (extrap alem de MaxExtrapolationSeconds+0.15s), zera a vel
visual -> proxy vai pra Idle em vez de moonwalk.
- ApplyEntitySnapshot: anti-stale -- snapshot > 1000ms a frente do topo do buffer
descarta o buffer + re-bootstrapa o ServerClockOffsetMs -> snap limpo (sem span
gigante na interpolacao). Loga "buffer STALE gap=Xms -> reset+reseed".
- Logs DIAG PERMANENTES (Warning, mantidos de proposito -- ver memoria
project_proxy_delta_starvation_jitter): SEED clock + renderLagMs/newestMs/
secsSinceSnap/speed no Tick. Sonda anti-regressao.
Cobre tambem o interserver: shadow proxies parados sofrem a mesma fome.
Validado em jogo (user: "sem jitter nenhum"). Par server: PubV2-DIAG (mesmo Change-Set).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
80 GameplayTags do ZeusServer (Zeus.Status/Ability/Effect/Cue/Attribute/Cooldown)
geradas pelo pipeline build-time (par com o commit de mesmo Change-Set no repo
ZeusServerEngine). O UE le Config/Tags/*.ini no boot e registra as tags, pro
cliente resolver os hashes de GE/Tag/Cue (FNV-1a64) -- fim do "tag nao resolvida".
Regeravel com sync_tags.ps1; nao editar a mao.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lado CLIENTE ZMMO (par com o commit de mesmo Change-Set no repo ZeusServerEngine -- devem
ir juntos, o wire do ENT_SPAWN mudou).
- UZeusAOIComponent: migrado do transporte legacy (SendDebugAoiRequest/OnDebugAoiInfo,
desativado no V1) pro canonico (EmitDebugAoiRequest 6160 / OnDebugAoiInfo 6161). Esfera de
debug 32 -> 48 segments + clamp visual de 500m (resolve "zona sem limite / poucas linhas").
- ZeusWorldSubsystem::OnNetEntitySpawned: recebe vel + grounded + serverTimeMs (delegate
FZeusV1OnEntitySpawned 4 -> 7 params) e semeia o proxy recem-criado via HandlePlayerStateUpdate
-> ancora o relogio de interpolacao + a vel inicial -> proxy nasce ja' animando no re-spawn
(sai/volta do raio AOI segurando W), sem Idle deslizando.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ZeusWorldSubsystem consome ENT_CHAR_INFO (delegate OnCharInfo): aplica
nome/guild no PlayerState do entityId certo (self ou proxy), com cache porque
o CHAR_INFO chega antes do ator existir (server emite antes do ENT_SPAWN).
- FIX loading travado: a etapa "Spawn" do loading dependia do legacy
OnPlayerSpawned, que não dispara mais com V1 -> loading eterno. Agora a etapa
é marcada pelo sinal V1 OnSelfEntityAssigned (ENT_SELF); bind legacy removido.
Travel ainda passa por OnServerTravelRequested (ponte legacy) até a Fase D.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- ZeusCharacter/ZeusWorldSubsystem passam a usar UZeusNetworkingClientSubsystem:
ENT_SELF (entidade própria), INPUT 6077 via EmitInput, spawn/despawn/delta
rebindados pro subsystem novo (legacy vira fallback).
- ZeusPlayerProxy consome velocidade/grounded/serverTimeMs (delta 0x02): anima,
vira na direção do movimento e cola no chão (MOVE_Walking).
- Fix overshoot/inércia: FlushInputAxisToServer considera velocidade residual
(braking) e envia a 30Hz até o dono parar de fato; o proxy desacelera suave,
sem extrapolar ~1m além nem snap-back.
- Char-select -> ConnectWithTicket (handoff ticket) quando bUseZeusNetworkingV1.
Inclui logs [InputDbg] (ZeusCharacter) e DEBUG-PROXY (ZeusPlayerProxy) mantidos
para testes posteriores de input/jitter.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rodando sem Jitter visivel.
- DECLARE/DEFINE LogZeusHandoff/AOI/Proxy/HaloTransition no modulo
ZMMO (nao no plugin) por causa do adaptive non-unity build do UBT
que usa git status do repo do cliente -- plugin em outro repo nao
dispara rebuild quando edit so o header dele.
- ZeusAOIComponent::HandleAoiConfig loga raios recebidos do server
pra cruzar com Net.AOI server-side ("AOI cfg recv interestCm=6000
(60m) despawnCm=8000 (80m)").
- Parte da milestone 2026-06-11: proxy/PIE estaveis apos fix de
double-emit AOI no server (AOIRegistry::ForceTickNow).
ZeusPlayerProxy.cpp -- H3 fix (2026-06-06): EMA com clamp para
ServerClockOffsetMs
================================================================
Antes: offset congelado na 1a amostra de ApplyEntitySnapshot. Em
cross-server handoff, a fonte do ServerTimeMs muda (publisher antigo
emitia 12340000, novo emite 12351000) e o offset fica permanentemente
skewed. Causa tremor pos-handoff + drift cumulativo de clock cliente
vs server.
Depois: cada amostra recalcula candidato (LocalNowMs - Snapshot.ServerTimeMs)
e suaviza via EMA com alpha=0.02 (~50 amostras para convergir) + clamp
max 2ms por amostra (a 30Hz isso converge a 60ms/s, suficiente para
absorver drift normal sem causar tremor visual). 1a amostra continua
bootstrap direto.
Trecho:
const double Alpha = 0.02;
const int64 RawTarget = ServerClockOffsetMs*(1-Alpha) + OffsetCandidate*Alpha;
const int64 Delta = RawTarget - ServerClockOffsetMs;
const int64 ClampedDelta = clamp(Delta, -2, 2);
ServerClockOffsetMs += ClampedDelta;
Asset cleanup L_TestWorld
==========================
DT_Maps.uasset modificado + 3 ExternalActors deletados (provavelmente
limpeza no UE editor ao reorganizar mapa). Empacotado junto pra branch
ficar limpa.
* Content/ZMMO/Data/World/DT_Maps.uasset (M)
* Content/__ExternalActors__/ZMMO/Maps/World/L_TestWorld/2/BR/38W34OMKW0W3L1PGS3Y98G.uasset (D)
* Content/__ExternalActors__/ZMMO/Maps/World/L_TestWorld/4/8L/X3PMRJRGAACIU1WG1P1KJ0.uasset (D)
* Content/__ExternalActors__/ZMMO/Maps/World/L_TestWorld/8/L1/C6M65Q91PG5E7ML91VQZX3.uasset (D)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Acompanha commit server 54f2f9a (P10-FIX-LEGACY). Resolve bug "vejo proxy
de UM mas o outro NAO ve" + "proxy fantasma do proprio player" -- causado
por server emitir S_SPAWN_PLAYER local=0 do proprio entityId via AOI re-emit
(workflow wcyeqgrad finding).
Source/ZMMO/Game/Network/ZeusWorldSubsystem.cpp
================================================
HandlePlayerSpawned guard novo logo apos EntityId==0 check:
if (LocalEntityId != 0 && EntityId == LocalEntityId)
{
UE_LOG(LogZMMO, Verbose,
TEXT("ignoring S_SPAWN_PLAYER for own LocalEntityId=%lld (bIsLocal=%d)"),
LocalEntityId, bIsLocal ? 1 : 0);
return;
}
Sem o guard, server re-emit S_SPAWN_PLAYER local=0 do proprio entityId
(via AOI SetOnEnter callback em catch-up cross-server ou recompute pos-
handoff) criava proxy fantasma do proprio player. GAS/HUD/PlayerArray
roteava via fantasma e o pawn real perdia vinculo de identidade visivel
pros outros players.
Defesa em profundidade -- complementa fix server-side
(AoiReplicationHelpers.cpp:28 SendSpawnPlayerToConn agora tem skip-self
guard antes de construir payload) + SpawnKey dedupe sem IsLocal no plugin
(ZeusNetworkSubsystem.cpp:949 removeu IsLocal do hash).
Config/DefaultZeusV1.ini
=========================
Config inicial para UZeusNetworkingClientSubsystem (P9-6/P9-7 plugin V1).
Aponta para Gateway 127.0.0.1:7777 (fluxo padrao producao). Documenta
alternativa de direct connect 9001 (debug only -- bug Windows multi-NIC
loopback). bUseZeusNetworkingV1=True ativa V1 plugin em paralelo ao
legacy (transport V1 hoje quebrado via Gateway -- channelId nao eh
routing key, Phase 12 territory; gameplay continua via legacy ate la).
Validado smoke 2 PIE 2026-06-08 20:32
======================================
* SP_01: players=2 conns=2 + AOI players=2 maxSet=1 enters=5 hyst=92 stable
* UE: [PIE0] e [PIE1] prefix funcionando (commit server 54f2f9a ZNET_PIE_PREFIX)
* "S_SPAWN_PLAYER duplicate ignored" dedupe pegando re-emit (Batch 2)
* S_CHAR_INFO trocado correto: PIE0 ve Olatudook, PIE1 ve Mateuus
* Saida limpa: UnregisterViewer + Broadcast S_DESPAWN_PLAYER targets=1
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Recebe a config de AOI do servidor (S_DEBUG_AOI_INFO via OnDebugAoiInfo) e
desenha 2 esferas com os raios REAIS: Zona de Interesse (interna, cyan) e
Zona de Despawn (AOI) (externa/histerese, laranja). Pede a config no BeginPlay
e ao ligar o overlay; nao desenha enquanto o raio == 0 (loading).
- Overlay EZeusAOIOverlay::SpawnZone -> DespawnZone (AOI).
- Expoe os raios via interface (GetInterestRadiusCm/GetDespawnRadiusCm) p/ o
painel admin mostrar o numero (read-only — config e' do servidor).
- CVar zeus.debug.spawn -> zeus.debug.despawn.
A interface, o opcode (1700/1701) e o painel vivem no repo Server (plugins).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- UZeusAOIComponent (Game/Network): componente de gameplay do player local com
plus de debug. Overlays via DrawDebug* (esfera AOI real; spawn/cell/handoff
placeholders) dirigidos pela UI via IZeusAOIDebugTarget + console vars. Estado
persiste no componente entre aberturas do menu (IsOverlayEnabled).
- AZeusCharacter: anexa o componente + abre/fecha o painel no F8 (UIOnly trava o
jogo; Esc/F8 fecham); LoadClass lazy do painel no content do PLUGIN
(/ZeusAdminTools/UI/WBP_AdminToolsAIO).
- ZMMO.Build.cs: depende de ZeusAdminToolsRuntime.
- UIProgressBar_Base: rename EaseOutCubic -> EaseOutCubicPB (fix unity-build).
- ZMMO.uproject: remove entrada NwiroIntegrationKit.
A UI e o C++ do plugin ZeusAdminTools vivem no repo Server (plugin autocontido).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bug: handler aceitava qualquer S_CHAR_INFO do server (proprio + catch-up de
proxies pre-existentes) e sobrescrevia o PlayerState local. Resultado: nome
do ultimo proxy recebido virava o nome do char local na tela.
Fix: bail se InEntityId != ZeusEntityId (proxies remotos sao roteados pelo
registry no UZeusWorldSubsystem; nameplate por EntityId fica pra futuro).
UE5 GAS nodes BP ("Get Ability System Component", "Apply Gameplay Effect To
Target", etc.) precisam que o PlayerState exponha o ASC via
IAbilitySystemInterface. Pattern Lyra: PlayerState dona a interface; ASC vive
como subobject do UZeusGASComponent (Component Registry).
Tres acessos:
- GetAbilitySystemComponent (interface, retorna base UAbilitySystemComponent)
- GetZeusAbilitySystemComponent (BlueprintPure, retorna UZeusAbilitySystemComponent
custom com 12 overrides ZeusNetwork)
- GetZeusAttributeSet (BlueprintPure, helper pro AttributeSet tipado)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- ZeusHudWidget: porta de UZeusAttributeComponent legacy pra UZeusGASComponent
(delegate OnSnapshotAppliedRaw via AddUObject; FZeusAttributesSnapshot
construido pelo helper estatico FromPayload do plugin ZeusGAS). Logs
diagnosticos no bind.
- UIPlayerStatus_Window: mesmo porte (snapshot raw + StatAllocReply). Lock
de spam-click preservado.
- ZeusHudHpSpWidget: movido do plugin ZeusAttributes (deletado) pra ZMMO
/Game/UI/InGame/. API preservada (WBP filhos nao precisam mudar).
- ZeusCharacter: tira o dual-seed legacy; so' seedea UZeusGASComponent
via FindComponentByClass no HandleLocalSpawnReady.
- ZeusPlayerState/ZeusCharacter: comentarios atualizados pra refletir o
UZeusGASComponent como dono unico.
- ZMMO.Build.cs: remove dep "ZeusAttributes", adiciona "ZeusGAS" +
"GameplayAbilities".
- ZMMO.uproject: remove module "ZeusAttributes" (delete completo).
- DefaultGame.ini: remove linha legacy comentada do Component Registry.
- DefaultEngine.ini: adiciona [CoreRedirects] pra:
* ZMMOJobs module + ZMMOJobDataAsset class (Package+Class) — 7 DA_Job_*
* ZMMO.ZMMOMapDef struct (DT_Maps row)
* ZMMO.ZMMOLoadingTipRow struct (DT_LoadingTips row)
* ZMMO.ZMMOLoadingProfile/StepDef structs + EZMMOLoadingContext/StepStatus
enums (DA_LoadingProfiles)
- DELETE: Source/ZeusAttributes/ inteiro (5 .cpp + 5 .h + Build.cs +
module.json).
Pegadinha aprendida: ActiveClassRedirects so' renomeia classe (sem
package); CoreRedirects (ClassRedirects/StructRedirects/EnumRedirects/
PackageRedirects) e' obrigatorio quando muda modulo OU quando o asset
referencia USTRUCT/UENUM. Tipo errado nao da erro mas tambem nao funciona.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Servidor-side plugin foi renomeado de ZeusAbilities pra ZeusGAS (vai
absorver atributos + abilities + bridge ZeusNetwork). .uproject precisa
seguir o novo nome senao plugin deixa de carregar.
Server-side commit: ver Server repo branch GameplayAbilitySystem,
commit refactor(plugin): R.7 - rename plugin ZeusAbilities -> ZeusGAS.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Snapshot do trabalho em andamento na branch feat/ui-system: refinamentos do
UIButton_Base (header+impl), atualizacao de styles/themes do botao, mapa de
teste L_ZeusIATest, e demais .uasset/Config tocados durante a sessao de
playtest do meshing. Commit conjunto a pedido do usuario pra deixar a branch
limpa antes do proximo batch.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
V3 Server Meshing (server-side) precisa entityId 64-bit (high32 = FNV-1a do
worldId, low32 = counter local) pra evitar collision cross-ZS. Os delegates do
plugin (OnPlayerSpawned, OnPlayerDespawned, OnCharInfoReceived, OnPlayerStateUpdate,
OnHpSpUpdate, OnLevelUp) e os métodos TryGetLast* migram pra int64; handlers em
ZMMOPlayerCharacter, ZMMOWorldSubsystem, UIFrontEndFlowSubsystem e
ZMMOAttributeNetworkHandler acompanham. FCachedSpawn::EntityId,
FZMMOAttributesSnapshot::EntityId e SeedEntityId também viram int64.
Wire S_SPAWN_PLAYER ainda carrega uint32 (server faz XOR high32^low32 pra
manter unicidade estatística entre ZSs); ampliação do opcode pra uint64 fica
pra PR futuro.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
ZMMOWorldSubsystem mantinha proxies no mapa RemoteEntities apos DESPAWN
apenas marcando SetActorHiddenInGame(true) via SetEntityRelevant(false).
Entry ficava la apontando pra actor escondido — SPAWN subsequente do
mesmo entityId caia no fast-path "reactivar" e tudo bem... ate' o
TWeakObjectPtr ficar stale (GC, World Partition stream-out, etc): a
branch Contains(EntityId) saia com return incondicional sem spawnar
nada. Resultado: SPAWN silenciosamente ignorado, pawn permanente
invisivel ate' algo limpar a key.
Fixes:
1. HandlePlayerDespawned: Actor->Destroy() + RemoteEntities.Remove
(destroi de verdade em vez de so esconder).
2. HandlePlayerSpawned: quando Contains mas weak ptr stale, remove a
entry orfa e cai pro caminho de spawn novo — em vez de return.
Confirmado pelos logs de cliente durante teste de oscilacao do AOI
(servidor enviando DESPAWN+SPAWN ao oscilar ZI/ZD).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Cliente fazia OpenLevel 2x:
1. CharSelect resolve mapId via DT_Maps -> TravelToMapById -> OpenLevel
2. Server confirma com S_TRAVEL_TO_MAP -> HandleServerTravelRequested ->
OpenLevel **de novo**
O segundo OpenLevel destruia o World, PlayerState, AttributeComponent e HUD
que ja tinham sido criados/bindados. AttributeComponent novo iniciava com
snapshot vazio (entity=0, level=1, hp=0/0) — HUD ficava nesse default.
S_ATTRIBUTE_SNAPSHOT_FULL com dados reais chegava DEPOIS do reload, mas
HUD nao tinha sido recriado/reativado no novo mundo, entao HandleAttributesChanged
nunca rodava.
A deduplicacao em ZeusNetworkSubsystem (`S_TRAVEL_TO_MAP duplicate ignored`)
so pegava do 3o TRAVEL em diante — o 2o ja fazia o estrago.
Fix: compara nome curto do World atual (strip prefixo UEDPIE_N_ do PIE) com
o target. Se ja' estao no mesmo mapa, skipa OpenLevel e so seta state pra
InWorld — preservando HUD/PlayerState/AttributeComponent.
FZMMOAttributesSnapshot ganha BaseExpToNext/JobExpToNext espelhando o wire do
server. ApplySnapshot liga ExpBar/JobBar pelo ratio (exp / exp-to-next) e os
readouts mostram a porcentagem (ou "MAX" no cap).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fontes usadas pelos templates do designer (loading_screen.html,
hud_layout_modal_New.html): Cormorant Garamond (titulos serif), JetBrains Mono
(labels/readouts mono) e Manrope (corpo sans). Cada uma com Font composto +
FontFaces estaticos por peso.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
UZMMOHudPlayerVitalsWidget (novo): sub-widget do HUD com 4 UUIProgressBar_Base
(HP/SP/BASE EXP/JOB EXP) + nome/classe/level. ApplySnapshot anima HP/SP via
SetTargetPrimaryLevel e formata os readouts; ApplyHpSp pro tick rapido.
UZMMOHudWidget propaga o snapshot pro PlayerVitals e resolve identidade: nome
do AZMMOPlayerState.CharName + job via UZMMOJobsLibrary.GetJobDisplayName(ClassId).
HpSpBar legado removido do WBP_HUD.
WBP_PlayerVitalsPanel: layout compacto (520w) com colunas alinhadas (label 28 /
bar FILL / readout 116 right-align) independente do tamanho do numero. Sem portrait.
MIs por barra: UI_M_ProgressBar_SP/BaseEXP/JobEXP/Loading (cores do
hud_layout_modal_New.html).
EXP/JOB readout mostra exp absoluto por ora — barras de EXP aguardam o servidor
enviar exp-to-next no snapshot pra calcular a porcentagem.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
FUIStyleProgressBar vira multi-map Hyper-style: TMap<FName, FUIStyleProgressBarVariant>
indexado por variante (HP/MP/XP/Cast/...). Cada variante carrega materiais por
layer (Fill/BG/TrackGrid/Edge/Shimmer) + style (DrawStyle/CornerRadius/Border) +
toggles de efeito.
UUIProgressBar_Base ganha bUseTheme + Variant (dropdown via meta=GetOptions
resolvendo o DT) + RefreshUIStyle() que aplica a variante via ThemeSubsystem
(runtime) ou DT direto (design-time), espelhando o padrao do UUIPanel_Base.
HandleThemeChanged reaplica em troca de tema.
EUIProgressBarStyle movido de UIProgressBar_Base.h para UIStyleTypes.h (usado
pela struct do DT).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Novo material UI_M_ProgressBar_Edge: linha vertical sharp no lado direito
do Fill (U = PrimaryLevel) com halo lateral configuravel.
Params:
- EdgeColour: cor + alpha da linha (default branco-creme 0.85)
- EdgeWidth: largura da linha em UV
- EdgeGlowWidth: largura do halo lateral (0 = sem glow)
- EdgeGlowIntensity: forca do halo (0..1)
- PrimaryLevel: posicao (sincronizada pelo C++)
WBP UI_ProgressBar_Master ganha EdgeImage entre Fill e Shimmer (Overlay).
C++ UUIProgressBar_Base:
- BindWidgetOptional EdgeImage + EdgeMID + UPROPERTYs override
- 5 setters runtime (Visible, Colour, Width, GlowWidth, GlowIntensity)
- ApplyPrimaryToMID propaga PrimaryLevel pro EdgeMID em cada tick de animacao
- UpdateEdgeVisibility() helper auto-oculta Edge quando PrimaryLevel <= 0
ou >= 1 (linha encostaria na borda)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Substitui o SDF de cantos arredondados no material por DrawAs=RoundedBox
nativo do Slate (OutlineSettings.CornerRadii em pixel space, qualidade
perfeita independente do aspect ratio).
Adiciona 3 materiais separados pra layers de efeito:
- UI_M_ProgressBar_BG: fundo solido (1 param BackgroundColour)
- UI_M_ProgressBar_TrackGrid: linhas verticais a cada N divisoes
(GridColour, GridDivisions, GridLineThickness)
- UI_M_ProgressBar_Shimmer: faixa de luz animada (Time node) deslizando
E->D em loop (ShimmerColour, ShimmerWidth, ShimmerSpeed, ShimmerSoftness)
WBP UI_ProgressBar_Master ganha 3 UImage irmaos do FillImage no Overlay
(z-order: BG -> TrackGrid -> Fill -> Shimmer), todos com BindWidgetOptional.
C++ UUIProgressBar_Base:
- Enum EUIProgressBarStyle (Box/Rounded) controla DrawAs dos 4 brushes
- CornerRadius em pixels (0..100), aplicado via OutlineSettings.CornerRadii
- bShowBorder + BorderColour + BorderWidth pra outline so no BG
- bShowTrackGrid / bShowShimmer toggles (visibility do widget)
- ShimmerImage com inset = BorderWidth (slot padding + corner reduzido)
pra nao sobrepor o outline do BG quando passa pelas extremidades
- UPROPERTYs override pra cada cor/param de cada material com
InlineEditConditionToggle, setters runtime que persistem o flag
Inclui MI exemplo UI_M_ProgressBar_HP atualizada.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
FUIStylePanel migra de TMap<EUIPanelTexture, FSlateBrush> (enum legacy) para
TMap<FName, FSlateBrush>. Permite adicionar/remover categorias diretamente
no DT_UI_Styles via dropdown (meta=GetOptions) sem mexer no enum em C++.
PanelBackground, PanelOutline e PanelOutlineEffect viraram *_DEPRECATED.
Versoes novas: PanelBackgroundByName, PanelOutlineByName,
PanelOutlineEffectByName.
PostSerialize migra os legacy -> ByName no PostLoad de cada FUIStyleRow.
Apos o primeiro re-save no editor os deprecated ficam vazios e o codigo
vira no-op. PropertyRedirects em DefaultEngine.ini preservam a leitura
do asset antigo (3 entries: PanelBackground, PanelOutline, PanelOutlineEffect).
Atualiza UIPanel_Base pra ler ByName + DT_UI_Styles, UI_Panel_Master e
UI_PlayerStatus_Window resalvos. Inclui nova textura
T_Panel_Outline_Effect_Square_02.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
UUIProgressBar_Base envolve UImage + MID em vez do UProgressBar nativo.
Material UI_M_ProgressBar expoe PrimaryLevel/SecondaryLevel (modelo
assimetrico: Secondary so aparece se > Primary), 5 cores (Primary +
ColourBottom, Secondary + ColourBottom, Empty) e gradient toggle com
bilinear remap controlado por GradientSplit.
Cores e gradient ficam expostos como UPROPERTY com InlineEditConditionToggle:
quando o toggle esta off usa o valor da MI atribuida no Brush, quando on
sobrescreve via MID em PreConstruct. Setters runtime tambem marcam o flag
pra persistir o override no proximo re-construct.
Wrappers semanticos: ShowHealPreview, ShowDamageLag, ShowBuffer, ClearSecondary.
NativeTick com ease-out cubica e duracoes separadas pra Primary e Secondary.
Inclui MI exemplo UI_M_ProgressBar_HP e WBP UI_ProgressBar_Master refatorado
(UProgressBar nativo substituido por UImage FillImage com brush apontando
para o material pai).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- UIFrontEndFlowSubsystem: HandlePostLoadMap/HandlePlayerSpawned agora
registram o StepId em PendingLoadingSteps_ quando ActiveLoadingScreen
ainda eh null (race com RequestAsyncLoad do WBP_Loading). Lambda do
callback async drena o set apos criar a tela, fechando o loading
retroativamente. Servidor rapido (TryFinalizeEnterWorld) deixava o
cliente preso em "entrando no mundo" quando o async load atrasava.
- UIPlayerStatus_Window: herda de UIDraggableWindow_Base (drag + persist
via UZMMOUISaveGame). Rename CloseBtn -> Button_Close, adiciona
Background_Panel/Container_Header/Container_Stats, NativeOnKeyDown
(Alt+A fecha), NativeGetDesiredFocusTarget=self. Remove bIsBackHandler
pra parar o "Cannot create action binding" no log (projeto nao tem
DefaultBackAction no CommonUISettings).
- UIInGameFlowSubsystem.SetState: skip re-push do HUD quando voltando de
StatusWindow/Inventory/Menu pro Playing (Old != None && != Playing) pra
evitar Construct novo do HUD e o flicker dos textos HP/SP.
- Novos: UIDraggableWindow_Base (drag generico + persistencia) e
UIWindowSaveGame (TMap<FName, FVector2D> por WindowId).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- UUILoadingScreen_Base (Game/UI/Common/) generica: Configure(Context),
MarkStepRunning/Done/Failed, OnLoadingComplete delegate, progress bar
reativa e rotacao automatica de dicas via timer.
- Etapas configuradas por contexto em UZMMOLoadingProfilesDataAsset
(DA_LoadingProfiles). Perfil inicial FrontEndEnteringWorld:
Travel -> MapLoaded -> Spawn.
- Dicas em DT_LoadingTips (FText localizavel + filtro por contexto +
GameplayTag de categoria). 4 dicas seed.
- UIFrontEndFlowSubsystem agora bloqueia a transicao InWorld ate o
HandlePlayerSpawned (bIsLocal=true) — usuario nao ve mundo vazio.
- WBP_Loading em /UI/Shared/Loading/ (neutro, reusavel pelo InGame futuro);
DA_FrontEndScreenSet[EnteringWorld] aponta pra ele.
- DefaultGame.ini wire LoadingProfilesAsset + LoadingTipsAsset.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- PlayerState ganha CharName (Replicated) + SetCharInfo(CharName, GuildName)
- ZMMOPlayerCharacter assina FZeusOnCharInfoReceived; TryApplyCachedCharInfo
resolve race se S_CHAR_INFO chega antes do pawn possuir
- UIPlayerStatus_Window header le PlayerState->CharName (fallback p/ GetPlayerName)
em vez do "Mateuus-61E9B19A4FB2" generico
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Adiciona as 3 texturas que o refactor de panel referencia via
EUIPanelTexture::Rectangle_Square_Gradient_01 (background gradient,
outline e outline effect) em /UI/Themes/Default/Panel/.
- Ignora Content/AutoCreated/ no .gitignore: pasta de saida do
ZeusUMGForge web converter, regenerada sob demanda, nao deve ser
versionada.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
UIPanel_Base: substitui PanelType/Padding por bUseTheme + 3 chaves
(Background/Outline/OutlineEffectKey) lidas de FUIStylePanel. Modo manual
(bUseTheme=false) expoe 3 FSlateBrush diretos via FUIPanelBrushSet pra
override por instancia. Adiciona BindWidgetOptional OutlineEffect (3o
Border sobre Outline pra glow/embossing). Defaults NoDrawType (regra
Hyper: brush vazio nao pinta branco).
UIButton_Base: remove auto-config (Variants enum, Number/Icon/Size/
InputAction/Timer). Vira shell minimal com BindWidgetOptional + helpers
GetActiveUIStyle/GetActiveButtonStyle pra leitura de DT_UI_Styles.
UIStyleTokens: FUIStylePanel ganha PanelOutlineEffect map. FUIPanelBrushSet
vira 3 FSlateBrush diretos. FUIStyleButton refatora pra 7 sub-maps por
variante FName (ButtonStyle=FButtonStyle do Slate, ButtonStroke, ButtonFont,
Text/Icon colors). Tudo com defaults NoDrawType.
UIStyleTypes: adiciona enum EUIPanelTexture::Rectangle_Square_Gradient_01.
Content: UI_Panel_Master e UI_Button_Master_New consomem a API nova;
DT_UI_Styles atualizado com rows/keys novas. UIServerCard_Base ajustado
pro consumer da API nova.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- 3 novas classes C++ (UUIPlayerStatus_Window/StatRow/BonusRow) substituem
UZMMOStatusWindowWidget (removida); StatRow/BonusRow sao reutilizaveis
via BindWidgetOptional + delegate OnPlusClicked(StatId).
- Window bindea no UZMMOAttributeComponent (PlayerState) e popula header
(CharName, Job via UZMMOJobsSubsystem, BaseLevel/JobLevel) + 14 rows
(6 primarios em StatRow com botao "+", 8 derivados em BonusRow).
- Fix spam-click do "+": bPlusButtonsLocked desabilita botoes ate
OnStatAllocReply do server ou proximo snapshot.
- WBPs movidos pra /UI/Screens/PlayerStatus/, material pra /UI/Materials/.
- 58 widgets renomeados seguindo convencao
(Frame_/Layout_/Panel_/Container_/Border_/Text_/Image_/Spacer_/List_).
- DA_InGameScreenSet auto-atualizado pelo move.
- Remove WBP_StatusWindow inline (legado).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Espelha breaking change do server (S_ATTRIBUTE_SNAPSHOT_FULL agora envia
matkBaseMin/matkBaseMax em vez de matkBase unico) para suportar MATK
pre-renewal puro (rathena status_base_matk_min/max).
- FZeusAttributesPayload: MatkBaseMin/Max em vez de MatkBase
- FZMMOAttributesSnapshot: idem (BlueprintReadOnly)
- ZMMOStatusWindowWidget: exibe "MATK min ~ max + equip"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Espelha breaking change do server (S_ATTRIBUTE_SNAPSHOT_FULL agora envia
matkBaseMin/matkBaseMax em vez de matkBase unico) para suportar MATK
pre-renewal puro (rathena status_base_matk_min/max).
- FZeusAttributesPayload: MatkBaseMin/Max em vez de MatkBase
- FZMMOAttributesSnapshot: idem (BlueprintReadOnly)
- ZMMOStatusWindowWidget: exibe "MATK min ~ max + equip"
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Infraestrutura cliente da promocao de classe (Jobs.1). WBP_JobChangePanel
NAO esta neste commit — foi exploracao descartada (criar UI dinamica de
botoes via MCP BP graph esbarrou em limites do CreateWidget node). A
fundacao C++ fica pronta pra ser usada quando voltarmos pra UI.
INFRA C++ NOVA (Source/ZMMOJobs/)
* UZMMOJobChangeNetworkHandler (WorldSubsystem novo) — bind no
OnJobChangeResult do plugin e re-broadcast via FZMMOOnJobChangeResultBP
(dynamic multicast assignavel em BP). WBP futura escuta direto.
* UZMMOJobsSubsystem helpers: GetJobsByTier(EZMMOJobTier) +
GetEligibleNextJobs(currentClassId) — filtra por ParentClassId. Pure.
* UZMMOJobsLibrary BPFL wrappers + SendJobChangeRequest convenience
(delega pro UZeusNetworkSubsystem). Dep ZeusNetwork adicionada no
Build.cs.
ENUM + INPUT
* EZMMOInGameUIState ganha JobChangePanel (entre StatusWindow e
Inventory). DA_InGameScreenSet pendente de receber entry quando
WBP for criada (tecla J vai falhar silenciosamente ate la).
* ZMMOPlayerController: tecla J -> ToggleJobChangePanel ->
Flow->ToggleScreen(JobChangePanel). Espelha pattern do Alt+A do
StatusWindow (InputComponent legacy BindKey + FInputChord).
UI TWEAKS
* WBP_StatusWindow + DT_UI_Styles: ajustes visuais no Editor durante a
sessao (sem mudanca funcional documentavel — provavelmente fontes/
spacing/cores).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
UZMMOGameInstance assinava OnNetworkLog do plugin e re-logava em LogZMMO
com prefix [Zeus]. Resultado: cada linha do plugin aparecia 2x no console
(LogZeusNetwork + LogZMMO). Era diagnostico inicial da fase de bring-up
(sessao 2026-05-07); agora so' polui o log.
Bind removido em BindZeusDelegates. Funcao HandleZeusNetworkLog mantida no
.h/.cpp (UFUNCTION dynamic delegate target) com comentario explicando como
reativar via descomentar a linha do AddDynamic.
Plugin continua logando em LogZeusNetwork (console) + Saved/Logs/ZeusNetwork/
(arquivo proprio) — diagnostico nao foi perdido, so' deduplicado.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
DA_Job_Novice DisplayName e docs de arquitetura (3 ARQUITETURA*.md)
sincronizados com a nova terminologia PT-BR. Server (Novice.json +
JobsDatabase.cpp) sera commitado separado no repo do ZeusServerEngine.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sub-módulo cliente do JobsSystem do server. Pavimenta dados visuais/UI por
job (DisplayName localizado, ícone, anim override, som de level up) sem
acoplar ao ZMMOAttributes.
ARQUITETURA — espelha o peer-module pattern do server (PR #9):
Server: Game/MMO/Modules/JobsSystem (módulo núcleo, LoadOrder=50)
Client: Source/ZMMOJobs/ (LoadingPhase=PreDefault, peer de ZMMOAttributes)
ZMMOAttributes NÃO depende de ZMMOJobs — server envia classId no snapshot,
cliente faz lookup local via Library/Subsystem.
NOVOS ARQUIVOS
C++ module (Source/ZMMOJobs/):
- module.json + ZMMOJobs.Build.cs (deps: Core/Engine/AssetRegistry)
- ZMMOJobsModule.h/.cpp — IMPLEMENT_MODULE
- ZMMOJobDataAsset.h/.cpp — UPrimaryDataAsset (BlueprintType)
campos: ClassId, TechnicalName,
DisplayName, JobIcon (soft),
DefaultAnimInstanceClass,
JobChangeMontage (soft),
LevelUpSoundCue (soft)
- ZMMOJobsSubsystem.h/.cpp — UGameInstanceSubsystem
scan AssetRegistry no Initialize +
cache TMap<int32, DA*> por ClassId
O(1) GetJobData(ClassId)
- ZMMOJobsLibrary.h/.cpp — UBlueprintFunctionLibrary
GetJobDisplayName/GetJobData/IsJobRegistered
fallback "Classe N" se ClassId desconhecido
Content:
- Content/ZMMO/Data/Jobs/DA_Job_Novice.uasset
(ClassId=0, TechnicalName="Novice", DisplayName="Aprendiz")
MODIFICADOS
- ZMMO.uproject: + Module "ZMMOJobs" (LoadingPhase PreDefault)
- Source/ZMMO/ZMMO.Build.cs: + "ZMMOJobs" em PublicDependencyModuleNames
- Source/ZMMO/Game/UI/FrontEnd/UICharCard_Base.cpp:51 — primeiro consumer
do Library: "Classe %d" hardcoded → UZMMOJobsLibrary::GetJobDisplayName(this, ClassId)
Card da seleção de personagem agora mostra "Aprendiz" via DA lookup.
BLUEPRINT ACCESS
Toda a API exposta pra BP via UFUNCTION(BlueprintPure):
- UZMMOJobsLibrary::GetJobDisplayName(Self, ClassId) → FText
- UZMMOJobsLibrary::GetJobData(Self, ClassId) → UZMMOJobDataAsset*
- UZMMOJobsSubsystem::GetJobData(ClassId)
- UZMMOJobDataAsset propriedades BlueprintReadOnly (UMG binding direto)
LOOKUP
AssetRegistry varre /Game/ por UZMMOJobDataAsset no boot do GameInstance.
Chave = campo ClassId do asset (não nome do arquivo — renomear .uasset OK).
Lookup O(1) via TMap. Custo de scan amortizado em 1 vez por sessão (~50ms
pra 50 jobs futuro).
VALIDAÇÃO
Editor:
[Log] DA class found: <class 'ZMMOJobDataAsset'>
[Log] Subsystem class found: <class 'ZMMOJobsSubsystem'>
[Log] Library class found: <class 'ZMMOJobsLibrary'>
[Log] AssetRegistry encontrou 1 ZMMOJobDataAsset(s):
- DA_Job_Novice @ /Game/ZMMO/Data/Jobs/DA_Job_Novice
Próximo módulo cliente: 1 linha no .uproject + .Build.cs + ZMMOJobs.Build.cs
não muda. Pattern estabelecido.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>