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>
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>
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>
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>
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>
- UZMMOHudWidget ganha LevelUpToastContainer (BindWidgetOptional UWidget)
e LevelUpToastText (BindWidgetOptional UTextBlock) — both Collapsed por
default; HandleLevelUp os mostra com text "LEVEL UP! Lv N" e dispara
timer FTimerHandle pra esconder após LevelUpToastDurationSec (2.5s).
- WBP_HUD: Border escuro semi-transparente (R=0.05,G=0.04,B=0.10,A=0.85)
com TextBlock dourado (R=1.0,G=0.85,B=0.30) fonte 32, slot top-center
com padding top=120, visibility default Collapsed.
- Snapshot pós-level-up (vem logo após S_LEVEL_UP) atualiza HP/SP/level via
HpSpBar automaticamente — toast é só feedback visual instantâneo.
Polish futuro (não desta frente): SFX cue + particle aura dourada +
animação de fade in/out via UMG.
- ZMMOStatusWindowWidget (UCommonActivatableWidget, modo Menu): grid 2 colunas
estilo RO. Esquerda: stats primários com botões + por stat (RequestStatAlloc).
Direita: derivados ATK/MATK/DEF/MDEF/HIT/FLEE/CRIT/ASPD vindos do snapshot
do server — cliente NUNCA recalcula (anti-cheat foundation).
- Botão + envia C_STAT_ALLOC → server valida cost RO (floor((stat-1)/10)+2),
aplica + recalcula derivados + SaveCharFull async, manda
S_ATTRIBUTE_SNAPSHOT_FULL + reply. UI atualiza em tempo real via
OnAttributesChanged.
- ZMMOAttributeComponent ganha RequestStatAlloc + NotifyStatAllocReply +
delegate OnStatAllocReply para feedback de rejeição.
- ZMMOAttributeNetworkHandler: HandleStatAllocReply roteia pro componente do
player local (reply não traz EntityId — sempre quem fez o request).
- PlayerController: hotkey Alt+A (FInputChord legacy + BindKey, sem precisar
de IA asset). ToggleStatusWindow via UUIInGameFlowSubsystem.
- WBP_StatusWindow: layout 2 colunas via MCP set_widget_tree (43 widgets) +
BgBorder escuro semi-transparente + centralizado no overlay.
- DA_InGameScreenSet: StatusWindow → WBP_StatusWindow.
Espelho simétrico do front-end pattern (UUIFrontEndFlowSubsystem +
DA_FrontEndScreenSet + UUIPrimaryGameLayout_Base) para a UI in-game.
Pavimenta caminho pra Inventory, Skills, StatusWindow, EscapeMenu, etc.
## UI in-game system (Source/ZMMO/Game/UI/InGame/)
- EZMMOInGameUIState enum (None, Playing, StatusWindow, Inventory,
SkillTree, EscapeMenu, Loading) em Data/UI/InGameTypes.h
- UUIInGameScreenSet DataAsset: TMap<EZMMOInGameUIState, TSoftClassPtr<...>>
- UUIInGameFlowSubsystem (GameInstanceSubsystem) com SetState/ToggleScreen
- DA_InGameScreenSet em Content/ZMMO/UI/InGame/ mapeia Playing->WBP_HUD
- Layer routing: Playing -> UI.Layer.Game | menus -> GameMenu | loading -> Modal
## AHUD pattern (idiomatic UE5)
- AZMMOHUD : AHUD em Source/ZMMO/Game/Modes/
- AZMMOGameMode::HUDClass = AZMMOHUD::StaticClass()
- AZMMOHUD::BeginPlay chama UIInGameFlowSubsystem::StartInGame
- Pawn não cria mais HUD (separação de responsabilidades)
## PlayerState + Component Registry (Open-Closed)
- AZMMOPlayerState : APlayerState em Source/ZMMO/Game/Modes/
- AZMMOGameMode::PlayerStateClass = AZMMOPlayerState::StaticClass()
- UPROPERTY Config TArray<TSubclassOf<UActorComponent>> ComponentClasses
- DefaultGame.ini: +ComponentClasses=/Script/ZMMOAttributes.ZMMOAttributeComponent
- Ctor lê via GConfig (mais robusto que UPROPERTY Config + parsing) e
instancia cada componente como CreateDefaultSubobject
Por que componentes no PlayerState e não no Pawn:
- Sobrevive ao despawn (morte/respawn)
- Spectator-friendly
- 1:1 com player (Pawn pode trocar: vehicle, mount, possession)
- Padrão MMO clássico (rathena, TrinityCore)
Adicionar novo módulo (Inventory, Skills, Guild) = 1 linha no
DefaultGame.ini, sem editar AZMMOPlayerState.cpp.
## HUD composite
- UZMMOHudWidget : UCommonActivatableWidget em ZMMO core (UI/InGame/)
- WBP_HUD em Content/ZMMO/UI/HUD/ herda UZMMOHudWidget
- HpSpBar (UZMMOHudHpSpWidget — sub-modulo ZMMOAttributes) embedded via
BindWidgetOptional. Sub-widgets futuros: PlayerInfo, Minimap, QuickBar,
Buffs, Chat, TargetInfo
- UZMMOHudHpSpWidget volta a ser UUserWidget puro (sub-widget, não root)
- UZMMOHudWidget::NativeOnActivated:
- SetVisibility(HitTestInvisible) — mouse passa direto pro Pawn
- BindToLocalPlayer: busca AttributeComponent no PC->PlayerState
- Subscreve OnAttributesChanged/OnHpSpChanged/OnLevelUp
- Propaga snapshots pra sub-widgets via HpSpBar->ApplySnapshot
- GetDesiredInputConfig override: ECommonInputMode::Game (sem cursor,
movimento livre). Menus override pra GameAndMenu/Menu.
## NetworkHandler refatorado (AttributeComponent agora no PlayerState)
- ZMMOAttributeNetworkHandler::FindComponentForEntity: busca via
GameState->PlayerArray (O(N_players)), não TActorIterator (O(N_actors))
- ZMMOAttributes.Build.cs += CommonUI, CommonInput
## EnsureRootLayout (fix crítico)
- OpenLevel invalida widgets no viewport ("InvalidateAllWidgets")
- RootLayout (criado pelo FrontEndFlow no boot) sobrevive como UObject
(LocalPlayerSubsystem) mas fica órfão fora do viewport
- Push do WBP_HUD no Stack_Game funcionava mas widget pai (RootLayout)
estava fora do viewport → invisível
- UUIFrontEndFlowSubsystem::EnsureRootLayout (público) recria via
UIManagerSubsystem (idempotente)
- UUIInGameFlowSubsystem::StartInGame chama EnsureRootLayout antes do push
## PlayerCharacter simplificado
- Removido AttributeComponent (vai pro PlayerState via Registry)
- Removido HudHpSpWidgetClass + spawn manual de HUD
- HandleLocalSpawnReady só faz seed do EntityId via PlayerState
- UI lifecycle agora é responsabilidade do AZMMOHUD::BeginPlay
## Verificação (smoke test)
PIE: Login -> CharSelect -> Lobby -> EnterWorld
↓
LogZMMO: AZMMOPlayerState ctor: 1 componente(s) no registry
LogZMMO: ZMMOPlayerState: componente registrado [0] ZMMOAttributeComponent
LogZMMO: FrontEndFlow::EnsureRootLayout: RootLayout recriado
LogZMMO: InGameFlow: state None -> Playing
LogZMMO: InGameFlow: tela Playing pushed em UI.Layer.Game (widget=WBP_HUD_C_0)
LogZMMO: ZMMOHudWidget activated (HpSpBar=WBP_HUD_HpSpBar_C_0)
↓
HUD aparece com Lv 5 / HP 10/200 / SP 5/20 (valores do DB)
Regen funciona (HP/SP enchem a cada 6s/8s)
Movimento normal (input flui pro Pawn)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Realoca as 13 texturas de painel do Hyper p/ /Game/ZMMO/UI/CommonUI/Textures/Panels/ (remove as procedurais)
- DT_UI_Styles.PanelBackground com as 9 entradas fiéis ao Hyper Survival_Gold (DrawAs=Image, Margin 0, tint por chave); PanelOutline vazio como no Hyper
- FUIPanelBrushSet (espelha Struct_UI_Style_Panels): só os 2 mapas
- UUIPanel_Base expõe Panels EditAnywhere (Details como no Hyper), semeado do tema; modo-textura só SetBrush (sem padding/visibility inventados)
- Design-time carrega DT_UI_Styles direto (Designer pinta igual ao runtime)
- Fix: outline ausente usa NoDrawType (antes pintava centro branco com FSlateBrush default)
- Remove membro morto Content/UNamedSlot (Hyper não usa NamedSlot)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Estrutura principal de front-end estilo Lyra portada para C++ proprio do
ZMMO (sem CommonGame), seguindo o padrao C++ Abstract -> WBP concreto:
- EZMMOFrontEndState / EZMMOLobbyPage e GameplayTags UI.Layer.* nativos
- UUIActivatableScreen_Base: base de tela (input config, hook de tema,
voltar) espelhando o padrao de UUIButton_Base
- UUIPrimaryGameLayout_Base: switch principal (4 stacks CommonUI/camada)
- UUIManagerSubsystem (LocalPlayer): dono do root layout, idempotente
- UUIFrontEndFlowSubsystem (GameInstance): maquina de estados + driver
de rede (Boot->Connecting->Login->ServerSelect->Lobby->EnteringWorld
->InWorld); Lobby e o hub logado, paginas internas = EZMMOLobbyPage
- UUIFrontEndScreenSet (DataAsset): mapa estado->tela, forge-ready
- AZMMOFrontEndGameMode + AZMMOFrontEndPlayerController
- GameInstance: bAutoConnectOnStart=false (conexao dirigida pelo fluxo)
- Build.cs: +GameplayTags; ARQUITETURA.md PR-first (s2.1/2.2/3.3/4.8/5)
- Assets: L_FrontEnd (GameMode via World Settings), WBP_PrimaryGameLayout,
DA_FrontEndScreenSet; Config wiring
WBPs de pagina (Boot/Login/...) virao do Zeus UMG Forge depois (s4.8).
Smoke test PIE OK: root layout no viewport, fluxo Boot->Connecting,
no-op+log para telas nao configuradas, sem crash.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 UTexture2D procedurais (grunge: base escura + value-noise 2 oitavas + vinheta + manchas + moldura arcana) em Content/ZMMO/UI/CommonUI/Textures/Panels (Square/Horizontal/Vertical + Outline_Gold; sRGB, UI, no-mip). DT_UI_Styles linha Default: Style.Panel.PanelBackground/PanelOutline com FSlateBrush (DrawAs Box/9-slice, Margin 0.22) -> ResourceObject resolvido p/ as texturas (verificado via read_data_table). UI_Panel_Master tree = Background(Border)->Outline(Border) (identico ao Hyper, sem NamedSlot). UI_Test_Panel: PanelA/B/Wide com PanelTexture (Square/Horizontal/Vertical_01). Play L_Test_UI mostra paineis texturizados (modo textura usa FUIStyle do subsystem em runtime).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Border do painel encolhia (NamedSlot vazio + slot Overlay nao-Fill). Agora cada SizeBox tem o UI_Panel_Master como filho unico -> SizeBox forca 360x200 / 740x160 -> Background preenche a celula e mostra o tema. Botoes (Confirmar/Cancelar Danger/Fechar Ghost) em BtnRow separada. Limite MCP: slot Fill / NamedSlot exigem o Designer.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BP_TestUIHUD: BeginPlay -> CreateWidget(UI_Test_Buttons, ctx/owner=GetOwningPlayerController) -> AddToViewport. BP_TestPC: bShowMouseCursor + click/mouseover events (p/ Hover/Pressed). GM_BP_TestGM: HUDClass=BP_TestUIHUD, PlayerControllerClass=BP_TestPC. L_Test_UI (Content/ZMMO/Debug/Maps): basic level com GameMode override = GM_BP_TestGM. Abrir L_Test_UI e dar Play exibe os botoes e permite testar estados. PIE confirmou HUD spawnado.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WBP em /Game/ZMMO/UI/Debug com 6 UI_Button_Master: Primary, Secondary, Danger, Ghost (so borda), Disabled (bIsEnabled=false), AlignLeft+Square (TextAlign=Left, bRoundedBackground=false). Compila 0 erros. Use o botao Play do WBP / PIE p/ exercitar Hover/Pressed/Disabled.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- UMG nao permite WBP-com-arvore herdar de WBP-com-arvore: a base abstrata e SO a classe C++ UUIButton_Base. UI_Button_Master reparentado direto p/ /Script/ZMMO.UIButton_Base; WBP UI_Button_Base (redundante) deletado. - UI_Button_Master: arvore propria (SizeBox_Master/Bg/ContentOverlay/ButtonText/Number_Text/Image_Icon/InputActionWidget) via set_widget_tree; ButtonTextValue='Button Text'. - BS_Button_Transparent (novo CommonButtonStyle: brushes NoDraw + padding 0) atribuido ao Style -> remove o fundo branco padrao do UCommonButtonBase; so o Bg (FUIStyle) aparece. - DT_UI_Styles linha Default: Button agora com cores Aurora Arcana (Primary dourado etc.). - ARQUITETURA.md §3.3 corrigido (regra UMG: C++ abstrato -> WBP concreto, variantes sao WBPs irmaos). Compila 0 erros; visual confirmado (dourado + BUTTON TEXT, sem moldura).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Camada de estilo data-driven do cliente ZMMO, portando o nucleo do projeto de referencia (Hyper) para C++ conforme ARQUITETURA.md (BP Struct proibido):
- Source/ZMMO/Data/UI: UIStyleTypes.h (enums EUI*), UIStyleTokens.h (tokens primitive/semantic/component), UIStyleRow.h (FUIStyle + FUIStyleRow). - ZMMOThemeSubsystem: GetActiveUIStyle() resolve DT_UI_Styles por ThemeId com fallback Default. - Fontes: 8 UFontFace Inline (Cinzel/Rajdhani) em Content/ZMMO/UI/Fonts + DT_UI_Styles preenchido. - ARQUITETURA.md: prefixo de widget UI_, classes base UUI*_Base (UCLASS Abstract) sem prefixo ZMMO. - Config/DefaultGame.ini: UIStyleTable apontando DT_UI_Styles. - Scripts/import_fonts.py (importador idempotente). Inclui tambem o scaffolding do modulo ZMMO ainda nao versionado (Source/ZMMO/Data, Game/UI, Content/ZMMO, uproject, Build.cs).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Remove os pacotes de exemplo Variant_Combat, Variant_Platforming e Variant_SideScrolling (mais os External Actors/Objects associados) que vieram do template Third Person e nao fazem parte do cliente ZMMO. Ajusta Config/DefaultEditor.ini de acordo.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Estrutura inicial do cliente Unreal Zeus MMO alinhada ao padrao
"cliente solto + servidor valida input/velocidade" (ADR 0038):
- Source/ZMMO/Game/Entity/ — IZMMOEntityInterface, AZMMOEntity (base
AActor para Mob/NPC/Object), AZMMOPlayerCharacter (player local com
CMC livre, Enhanced Input, envio de C_INPUT_AXIS), AZMMOPlayerProxy
(snapshot-only para players remotos).
- Source/ZMMO/Game/Controller/ — AZMMOPlayerController com IMC defaults
(IMC_Default + IMC_MouseLook) e suporte opcional a virtual joystick.
- Source/ZMMO/Game/Modes/ — AZMMOGameMode (defaults para PlayerCharacter
/ PlayerController), UZMMOGameInstance (auto-connect ao servidor Zeus
em Init e logging dos eventos OnConnected/OnDisconnected/...).
- Source/ZMMO/Game/Network/ — UZMMOWorldSubsystem (registry
EntityId -> AActor*, dispatch dos delegates OnPlayerSpawned/Despawned/
StateUpdate; ignora snapshots locais do cliente solto).
- Config/DefaultEngine.ini — GlobalDefaultGameMode aponta para
/Script/ZMMO.ZMMOGameMode; GameInstanceClass para
/Script/ZMMO.ZMMOGameInstance; redirects para a nova hierarquia.
- ZMMO.Build.cs — depende de ZeusNetwork; PublicIncludePaths para a
nova arvore Game/Entity|Controller|Modes|Network.
- Content — assets do template ThirdPerson (Mannequins, IAs/IMCs,
Lvl_ThirdPerson + TestWorld). Os Variant_* levels ficam no commit
inicial mas serao limpos numa proxima sessao com aprovacao explicita
(Master Rule para .umap/.uasset).
Notas:
- BP_ThirdPersonCharacter/GameMode/PlayerController ainda apontam para
a hierarquia antiga e estao a aguardar aprovacao para remocao
(Master Rule).
- README.md descreve a arquitectura e o smoke test de conexao.