三款自研玩法(手速 / 策略 / 合作)+ 三局两胜场次 + 场终战报 + MatchCore 统一内核 + 结算契约 v1。同屏上下分区、P2 区倒置为两人对坐的设计意图。全部素材自研,零竞品复用。
触屏:上半区归 P2、下半区归 P1,双指并发互不串扰。
键盘:极速回弹 A / D(P1)、← / →(P2);三格连珠 1~9 落子;同步开关 F(P1)+ J(P2)在 0.8 秒内同时按。
推荐路径:点「开一场 · 三局两胜」→ 打完一局 →「下一局」→ 场终战报 →「再来一局」/「发给搭子(纯自愿)」。
玩法配置化:GameDefRepo.override('rebound_rush', {target_score: 3}) 可改目标分而不发版;白名单外字段显式抛错。
远端权威源(默认关闭):?authority=remote&endpoint=http://127.0.0.1:18765 让每局结算真实 POST 到 Java 服务;
默认仍是本地内存结算、同屏零网络。远端超时 / 断网 / 非 2xx 一律显式入队待补报,绝不回退本地结算伪装成功。
| 项 | 基线 v0 | 定稿 v1(本 Demo 实现) |
|---|---|---|
| 入口 | submitResult(uid, gameId, score) | submitMatchResult(SubmitMatchResultReq) |
| 返回 | {ok: bool},失败静默 | MatchSettlement,失败显式抛 3 类异常 |
| 幂等 | 无 | client_match_id unique,重放返回首次结算 |
| 玩家槽 | 单 uid,同屏无 uid 直接丢局 | 双槽 slot 0/1,支持 guest_id / is_ai / uid |
| 模式 | 无区分 | local / ai / online / async 共用状态机,只在 InputAdapter 与 AuthorityProxy 分化 |
| 过程 | 只看最终分数 | events 摘要 + events_hash 签名校验,脏摘要抛 RiskFlaggedError |
| 场次 / 关系 | 无 | session_score 聚合、pair_key 排序拼接、默契 / 对抗值与 WAP 判定 |
7 处关联调用点全部按 v1 契约一次性建齐,业务层不并存两套契约;老客户端 v0 由网关 /v0/result 适配 30 天后下线。
| 自检项 | 实现位置 / 手法 |
|---|---|
| ① 大卡浮层 | --card-shadow:双层柔影 + inset 0 1px 0 #fff 顶缘高光 |
| ② 黏土钮三层影 | --clay-shadow:4px 底部厚度 + 外投影 + 内顶高光 + 内底暗缘;:active 下沉 3px |
| ③ 输入框内凹 | --sunk-shadow:上暗下亮 inset 对偶 + 外底亮线 |
| ④ 球面径向高光 | .sphere / .ball / .cell .m:32%/26% 高光点 + 内暗缘 |
| ⑤ 相框 + 接触阴影 | .report-card 9px 白框 + 0 10px 20px 接触影;.frame-card .thumb 白框 + 接触影 |
• 局内零广告:MatchCore.finish() 调 assertNoInGameAd() 扫描广告位,命中即抛 RiskFlaggedError;CSS 另设 .ad-slot{display:none!important}。
• 无分享解锁 / 无奖励:玩法解锁只由 applyUnlocks() 在「对局达成」触发;分享按钮只记埋点 + toast,share_card_url 恒为 undefined(运营规范 5.1.1 / 5.1.2 / 5.1.4)。
• 再来一局无遮挡:场终主按钮四周无任何广告位或跳转层(特别规范 2.10.2)。
• 未知 ≠ 正常:未知玩法、脏摘要、未知 session、滞后数据一律抛错或显式标记 stale / unavailable,绝不返回看起来正常的默认值。