Skip to content

feat(ui): implement approved cartoon Solo duel board - #65

Draft
orbyteon wants to merge 18 commits into
mainfrom
feature/cartoon-solo-duel-20260824
Draft

feat(ui): implement approved cartoon Solo duel board#65
orbyteon wants to merge 18 commits into
mainfrom
feature/cartoon-solo-duel-20260824

Conversation

@orbyteon

@orbyteon orbyteon commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Goal

Rebuild the playable Solo number-duel board in the approved HOL cartoon composition while preserving all existing GameManager, NumberManager, DuelRules and typed presentation-state behavior.

Production composition

  • approved neon background, stars, confetti and outer frame
  • real Back control plus HOL logo and dynamic player/wins chip
  • large cyan player and magenta AI opponent cards with approved characters
  • production VS burst
  • purple round/prompt ribbon using the real GameManager.turnText
  • left interaction board with current-number display, real input, 3×4 keypad and gold Submit
  • right opponent rail with modular speech bubble, real AI response, histories and live range/tip
  • mascots 7 and 3
  • real Higher / Correct / Lower controls retained at the bottom

Playability and authority

The PR does not rewrite duel rules or AI decisions. It reparents and styles the real runtime/scene controls, and keeps:

  • secret entry
  • player/AI turns
  • range narrowing
  • histories
  • answer acknowledgement
  • one Submit control
  • clear/backspace keypad semantics
  • result/rematch state
  • two-step Back confirmation

Regression coverage

The existing functional SoloBoardPresenterPlayModeTests continue to exercise the full state machine. New visual coverage locks exact 1080×1920 geometry, modular sprite assignments, 12 real keypad buttons, the real GameManager prompt reference, one submit control, answer controls, typography and no procedural Graphics.

No PvP, PlayFab, CloudScript, package, monetization, scene-YAML or release-version changes.


Note

Medium Risk
Presentation-only, but it reparents live GameManager/NumberManager input, prompt, range, history, and answer buttons. Missing art now aborts the board via IsReady, so layout or asset issues can hide playable controls.

Overview
Rebuilds the Solo number-duel board as the approved cartoon composition (neon shell, character cards, VS burst, prompt ribbon, interaction card, opponent rail, mascots) without changing GameManager, NumberManager, or DuelRules.

HolDuelBoardLayout now loads required production sprites/fonts, gates build on IsReady, and seats the real scene controls (input, submit, Higher/Correct/Lower, turnText, opponent name, AI bubble, range/tip) into a 1080×1920 safe-area root. Opponent identity is the name only; the player chip shows name plus wins.

Adds play-mode visual coverage that locks geometry, sprite assignments, one submit control, and no procedural Graphics. New speech-bubble art is included.

Reviewed by Cursor Bugbot for commit 87700cf. Bugbot is set up for automated code reviews on this repo. Configure here.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 150ce3a5cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

visualRoot = (RectTransform)RuntimeUI.CreateObject(
VisualRootName, board).transform;
Stretch(visualRoot);
visualRoot.SetAsFirstSibling();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the production root above legacy siblings

When a solo match starts, NumberManager.SubmitNumber activates the scene-authored PlayerGuessText and AIguesses objects, but those objects are not reparented or disabled here. Because Unity renders later siblings on top, forcing the production root to be the first sibling makes those legacy labels overlay the new player/opponent cards; the scene-authored result button similarly appears above the new shell. Reparent or disable every retained legacy object, or otherwise place the presentation owner above them.

AGENTS.md reference: AGENTS.md:L128-L130

Useful? React with 👍 / 👎.

if (child == null || parent == null) return;
if (child.parent != parent)
child.SetParent(parent, false);
child.gameObject.SetActive(true);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve answer-button visibility while reparenting

On initial panel activation, GameManager.Start hides all three answer buttons before the invoked Build runs, but MoveIfFound sends each button through this helper and unconditionally reactivates it. Consequently Higher, Correct, and Lower are all visible and clickable during the secret-entry phase until gameplay hides them again; preserve each child's active state while moving it or explicitly render answer visibility from the current phase.

AGENTS.md reference: AGENTS.md:L72-L73

Useful? React with 👍 / 👎.

Comment on lines +433 to +434
numberManager.playerNumberText.rectTransform,
new Vector2(0f, 390f), new Vector2(500f, 45f));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Separate the current-number value from its heading

At the authored 1080×1920 layout, CurrentNumberHeading is centered at y=410 with height 48, while this value is centered at y=390 with height 45, so their visible bounds overlap by about 26 pixels (and the value also reaches into the input's top edge). The localized heading and live PlayerName: ? value therefore render through one another during secret entry; assign them distinct non-overlapping bounds.

AGENTS.md reference: AGENTS.md:L95-L98

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

@codex Please fix all three unresolved review blockers in this PR without changing duel logic: (1) keep SoloDuelVisualRoot above legacy scene siblings or fully retire/reparent every retained legacy presentation object, (2) preserve the original active state of Higher/Correct/Lower while reparenting so secret-entry does not expose them, and (3) separate CurrentNumberHeading, the live player-number label, and GuessInput into non-overlapping 1080×1920 bounds. Add/adjust PlayMode assertions for initial answer-button visibility, sibling ordering/no legacy overlays, and non-overlapping bounds. Run full EditMode/PlayMode/Android CI and do not merge until green.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@cursor

cursor Bot commented Aug 24, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_9622d297-3e9a-4ff2-aa0a-c3b52f4c4d4b)

@cursor

cursor Bot commented Aug 24, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_47eeb76e-0d78-4e22-8583-e2d3004f1792)

Copy link
Copy Markdown
Owner Author

@codex address all three unresolved review threads on the current PR head. Keep GameManager, NumberManager, DuelRules, scene callbacks and the one HolDuelBoardLayout presentation owner authoritative. Required fixes: (1) remove/absorb every legacy sibling that can render above the production root, including scene-authored guess labels and the result control, without hiding required result/rematch functionality; (2) preserve the pre-reparent active state of Higher/Correct/Lower and keep their visibility driven only by the current duel phase; (3) give CurrentNumberHeading, the live player-number value and the input distinct non-overlapping 1080x1920 bounds. Add focused PlayMode regressions for legacy-overlay absence, ChooseSecret answer-button invisibility, AnswerOpponent single-button visibility, and non-overlapping text/input bounds. Rebase/synchronize onto current main, run full EditMode, PlayMode, Android compile, Production Visual Integrity and exact-head native EN/EL portrait captures. Do not merge until every gate is green and all review threads are resolved.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 18440ee892

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

bodyFont = Resources.Load<TMP_FontAsset>(BodyFontResource);
}

void LateUpdate()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the second LateUpdate presentation owner

SoloDuelPresentationHardener is not merely infrastructure: on every frame it changes hierarchy, layout, visibility, typography, and production button artwork after HolDuelBoardLayout renders. This creates the exact competing late presentation pass the change is required to avoid and makes final UI state dependent on script execution order; absorb these invariants into HolDuelBoardLayout so it remains the single deterministic presentation owner.

AGENTS.md reference: AGENTS.md:L121-L125

Useful? React with 👍 / 👎.

Comment on lines +187 to +192
GameObject result = gameManager.stopGameButton;
if (result != null)
{
RectTransform rect = result.transform as RectTransform;
ReparentPreservingState(rect, safeRoot);
Place(rect, ResultButtonPosition, ResultButtonSize);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep the Lock button inside the production root

When PanelGAME activates, GameManager.Start creates LockButton under the stop button's original parent before this hardener reaches LateUpdate, but this block reparents only stopGameButton. Because line 124 then places the full-screen, raycast-blocking production root above all remaining siblings, the Lock button becomes hidden and untappable when RefreshLockButton activates it after the player's first turn; seat the Lock control in the production root along with the result control.

AGENTS.md reference: AGENTS.md:L72-L73

Useful? React with 👍 / 👎.

Comment on lines +26 to +29
static readonly Vector2 InputPosition = new Vector2(0f, 270f);
static readonly Vector2 InputSize = new Vector2(500f, 110f);
static readonly Vector2 MessagePosition = new Vector2(0f, 208f);
static readonly Vector2 MessageSize = new Vector2(500f, 36f);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Move the validation message clear of the input

At 1080×1920, the input at y=270 with height 110 occupies y=215–325, while the message at y=208 with height 36 occupies y=190–226, so they overlap by 11 pixels. This also makes the newly added AssertNoVerticalOverlap(input, message) fail deterministically, preventing the required PlayMode gate from becoming green; move one bound so the ranges no longer intersect.

AGENTS.md reference: AGENTS.md:L97-L108

Useful? React with 👍 / 👎.

@orbyteon
orbyteon marked this pull request as draft August 26, 2026 00:33

Copy link
Copy Markdown
Owner Author

CTO stabilization hold: this visual PR is temporarily returned to draft while PR #71 restores the trustworthy PlayMode baseline and fail-closed production-art behavior. Preserve the branch; do not merge or add architecture changes until the current main stabilization gate is green. Afterward, rebase onto the stabilized baseline and revalidate the real callback-bearing controls, native captures, and PlayMode suite.

Copy link
Copy Markdown
Owner Author

CTO integration hold (2026-08-26): this visual branch is preserved but returned to draft until the production-safety baseline in #72 is green and merged. After that, refresh it from current main, resolve architecture/test conflicts, and rerun the exact merge-candidate gates before review. Do not merge this branch on its current diverged baseline.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant