feat(client): unify Player + creatures under one Mobile base (fixes PvP targeting) (#149) #151
No reviewers
Labels
No labels
alpha:wave-0
alpha:wave-1
alpha:wave-2
alpha:wave-3
area:assets
area:combat
area:ecology
area:infra
area:render
area:scripting
area:ui
area:world
enhancement
epic
migration
post-alpha
roadmap
tech-debt
type:bug
type:chore
type:design
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
marco/IsoMmo!151
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/client-mobile-unify"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fixes the root cause behind "you can't click a friend to attack" (surfaced by the PvP-arena review, #109): the client kept players and creatures in two unrelated
sealedtypes + two dicts (ClientWorld.Players/.Mobiles), and click-to-target only scanned the creature dict — so clicking a player did nothing. Every interaction had to remember both collections, a whole class of latent bugs.This mirrors the server's model (
Mobile→PlayerMobile+ creatures) on the client:Mobilebase (Entities/Mobile.cs): the shared server-driven state + behaviour — name, tile, glide-between-tiles, facing, tint, overhead/body points,Contains,Attack,PlayHit,Update. AbstractDraw/Contains/UpdateVisual.Creature : Mobile(the formerMobile) — creature art + one-shot hit reaction.Player : Mobile— appearance/equipment/speech/power-words/shield/swing; it now has aContainshit-box (it never did — that's why players weren't clickable).ClientWorld.Mobiles(Dictionary<Guid, Mobile>);Self = Mobiles[SelfId] as Player; the five duplicatedPlayers-then-Mobileshelpers collapse to one lookup each. Ids already share theGuidspace, so no collision. Corpses/items stay separate (not mobiles).GameInputController): the pick iterates the one collection, excluding self → clicking a player or a creature engages it. That's the fix.WorldKind.PlayervsWorldKind.Mobilesplit collapses into one polymorphicDrawpass (extend-by-type, not switch).IsTarget(red highlight) is kept apart from the dispatcher-set statusTint(ghost), combined at draw (DrawTint), so unifying the update loop doesn't clobber a ghost's tint — and a live player-target now highlights red too.No wire change — ingestion stays per-DTO (
PlayerState → Player,MobileState → Creature) writing into the one dict;ProtocolVersionuntouched.Closes #149. Unblocks the PvP-arena work (#109) and is reused by spell-target / tile-highlight.
Screenshots / recording
No-regression check (fresh DB, debug harness): the self player renders correctly through the new unified
Mobilepath — sprite + name + tree occlusion — with biomes and ground items intact; the HUD/debugplayers N · mobiles Msplit (via the newPlayerCount) works.Commands:
login test;goto 24 26;screenshot.How it was tested
just lint(CSharpier + analyzers, zero warnings) andjust test(407 tests) green; whole solution builds incl. client + tools.Player : Mobile, debug status shows the new player/creature counts.Checklist
just lintpasses (CSharpier + analyzers, zero warnings)just testis green