3.6 KiB
Card UI Standardization
Goal
Make every card-shaped UI use the same input structure so hover tooltip, click, drag, and future interactions behave the same way everywhere.
Target surfaces:
- hand cards
- reward cards
- shop cards
- draw pile / discard pile / exhaust pile viewer cards
- all deck / class deck / codex cards
Standard Card Entity Shape
Each visible card should have one root entity that owns input.
CardRoot
- UITransformComponent
- SpriteGUIRendererComponent
- ButtonComponent
- UITouchReceiveComponent
- Cost
- Name
- Desc
- Art
Rules:
CardRootcovers the full card rect.CardRootowns both click and hover.- Child entities are display only.
- Child entities must not become the primary input target.
Required Component Rules
Card root
UITransformComponentSpriteGUIRendererComponentButtonComponentUITouchReceiveComponent
Recommended sprite settings:
RaycastTarget: true- card frame sprite on root
Card children
Cost,Name,Desc: text onlyArt: sprite only
Recommended child sprite settings:
RaycastTarget: false
That keeps hover/click ownership on the root card entity.
Path Rules
Use the same path naming pattern everywhere:
- hand:
/ui/.../CardHand/Card1 - reward:
/ui/.../RewardHud/Reward1 - shop:
/ui/.../ShopHud/Card1 - inspect:
/ui/.../DeckInspectHud/Grid/Card1 - all deck:
/ui/.../DeckAllHud/Grid/Card1
The important part is that each list has a stable root card path ending in a numeric slot. That lets controller code resolve hover target -> slot -> card id without special cases.
Controller Rules
Once UI is standardized, controller logic should follow this shape:
- Resolve
path - Resolve
slotfrompath - Resolve
cardIdfrom current backing list - Show tooltip from
cardId
Preferred shared methods:
GetHoveredCardId(path)HoverCardByPath(path)UnhoverCardByPath(path)
The hand should just become one caller of the same shared path-based hover logic rather than having its own special tooltip flow.
Safe Rollout Order
Do not standardize every card surface at once.
Step 1
Document current structures for:
RewardHud/Reward1ShopHud/Card1DeckInspectHud/Grid/Card1DeckAllHud/Grid/Card1
Step 2
Make DeckInspectHud/Grid/CardN match RewardHud/RewardN component structure.
Step 3
Verify game boot and UI load before changing controller hover bindings.
Step 4
Make DeckAllHud/Grid/CardN match the same structure.
Step 5
After both surfaces are stable, bind hover events in controller code.
Validation Checklist
Before testing hover behavior:
- game boots with no
LEA-3015 CannotLoad DefaultGroup.uiloads cleanly- card roots exist at expected paths
- root card sprite has
RaycastTarget: true - child art sprite has
RaycastTarget: false - root has both
ButtonComponentandUITouchReceiveComponent
After binding hover:
- hand tooltip still works
- reward tooltip still works
- shop tooltip still works
- inspect tooltip works
- all deck tooltip works
- no duplicated tooltip flicker
- no drag regression on hand cards
What Not To Do
- do not hand-edit
ui/DefaultGroup.ui - do not change multiple card surfaces in one shot
- do not mix root-input cards with child-input cards
- do not add hover logic before confirming the target card entity actually receives input
Recommended Next Change
The next implementation step should be:
- diff
DeckInspectHud/Grid/Card1againstRewardHud/Reward1 - make only
DeckInspectHudroot card structure match - regenerate UI
- boot test
- then bind hover for inspect cards only
That keeps the blast radius small.