Files
maplecontest/docs/card-ui-standardization.md

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:

  1. CardRoot covers the full card rect.
  2. CardRoot owns both click and hover.
  3. Child entities are display only.
  4. Child entities must not become the primary input target.

Required Component Rules

Card root

  • UITransformComponent
  • SpriteGUIRendererComponent
  • ButtonComponent
  • UITouchReceiveComponent

Recommended sprite settings:

  • RaycastTarget: true
  • card frame sprite on root

Card children

  • Cost, Name, Desc: text only
  • Art: 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:

  1. Resolve path
  2. Resolve slot from path
  3. Resolve cardId from current backing list
  4. 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/Reward1
  • ShopHud/Card1
  • DeckInspectHud/Grid/Card1
  • DeckAllHud/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.ui loads cleanly
  • card roots exist at expected paths
  • root card sprite has RaycastTarget: true
  • child art sprite has RaycastTarget: false
  • root has both ButtonComponent and UITouchReceiveComponent

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

The next implementation step should be:

  1. diff DeckInspectHud/Grid/Card1 against RewardHud/Reward1
  2. make only DeckInspectHud root card structure match
  3. regenerate UI
  4. boot test
  5. then bind hover for inspect cards only

That keeps the blast radius small.