fix(studio): B2′ 真人试玩闭环 3 处修复 — 布局高度链/demo兜底非致命/game_end补completed
浏览器实玩(staging+真无头Chrome)首次暴露、curl/单测均未现形的 3 个真 bug:
1) 布局:#app/.app-root 改 height:100% 建确定高度链——原 min-height 链断,子页 .feed/.play 的 height:100% 塌成 0,封面/画布 0 高不可点(真机也塌)。
2) GamePlayer:取包/manifest 校验失败回退 demo 是「可恢复」场景,不再 emit('error')(父级 Play 把 error 当致命态 v-else-if 隐藏宿主显示「加载失败」,与 demo 兜底冲突),仅 console.warn。
3) runtime:clicker finish() 补发 completed:true+duration_ms——后端 quality_score 完玩率口径依赖 props.completed,缺它真玩也推不动 quality(数据回路失效)。
实证:浏览器玩 A-小卖部通关→quality 0→60→feed 从 B 领头(30)翻转为 A 登顶(60)。vue-tsc -b 绿。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
ab0037cd4b
commit
d279898192
@ -32,7 +32,8 @@ const showTabBar = computed(() => !route.meta?.hideTabBar)
|
||||
.app-root {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
/* 用动态视口高度,移动端地址栏收缩时不抖动 */
|
||||
/* height:100% 填满 #app(确定高度链),使子页 height:100% 可解析;min-height:100dvh 作下限兼顾移动端动态视口收缩不抖动 */
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
background: var(--bg);
|
||||
|
||||
@ -118,9 +118,11 @@ async function resolvePackage(): Promise<GamePackage> {
|
||||
const fetcher = props.fetchPackage ?? getRuntimePackage;
|
||||
respVO = await fetcher(vid, props.mode);
|
||||
} catch (e) {
|
||||
// 取清单失败:抛给上层 error,并以 demo 兜底(不白屏,便于自测链路)
|
||||
// 取清单失败:可恢复场景——demo 兜底即可正常试玩,故不向上 emit('error')
|
||||
// (父级 Play 把 error 当致命态、会 v-else-if 隐藏宿主显示「加载失败」,与 demo 兜底冲突)。仅 console.warn 记录。
|
||||
const message = e instanceof Error ? e.message : '取包清单失败';
|
||||
emit('error', { message });
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[GamePlayer] 取包清单失败,回退 demo 兜底(不致命):', message);
|
||||
return buildDemoPackage(props.gameId, props.versionId, traceId.value);
|
||||
}
|
||||
|
||||
@ -129,9 +131,11 @@ async function resolvePackage(): Promise<GamePackage> {
|
||||
try {
|
||||
return await fetchAndVerifyManifest(respVO.manifestUrl, respVO.checksum);
|
||||
} catch (e) {
|
||||
// 拉取/校验失败:上报 error,退回 demo 兜底(去无条件 demo,仅失败时兜底)
|
||||
// 拉取/校验失败:可恢复场景——退回 demo 兜底即可正常试玩,故不向上 emit('error')
|
||||
// (父级 Play 把 error 当致命态、会 v-else-if 隐藏宿主显示「加载失败」,与 demo 兜底冲突)。仅 console.warn 记录。
|
||||
const message = e instanceof Error ? e.message : 'manifest 取包/校验失败';
|
||||
emit('error', { message });
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn('[GamePlayer] manifest 校验失败,回退 demo 兜底(不致命):', message);
|
||||
const demo = buildDemoPackage(props.gameId, props.versionId, respVO.traceId || traceId.value);
|
||||
demo.templateId = respVO.templateId || demo.templateId;
|
||||
return demo;
|
||||
|
||||
@ -73,6 +73,7 @@ export function startRuntime(
|
||||
let running = true; // 主循环开关
|
||||
let rafId = 0; // requestAnimationFrame 句柄
|
||||
let started = false; // 是否已发 game_start
|
||||
let startMs = 0; // 本局开始时间戳(game_start 时记;用于 game_end 的 duration_ms)
|
||||
// 目标分数:优先取 gameConfig.target,缺省 5(demo 玩法 = 点满即结束)
|
||||
const target =
|
||||
typeof pkg.gameConfig?.target === 'number' ? (pkg.gameConfig.target as number) : 5;
|
||||
@ -143,6 +144,7 @@ export function startRuntime(
|
||||
if (!running) return;
|
||||
if (!started) {
|
||||
started = true;
|
||||
startMs = Date.now();
|
||||
life('game_start');
|
||||
}
|
||||
score += 1;
|
||||
@ -160,7 +162,9 @@ export function startRuntime(
|
||||
running = false;
|
||||
cancelAnimationFrame(rafId);
|
||||
canvas.removeEventListener('pointerdown', onPointer);
|
||||
life('game_end', { score });
|
||||
// game_end 必须带 completed + duration_ms:后端 quality_score 完玩率口径依赖 props.completed
|
||||
// (达 target 即通关 = completed:true);缺它则 completeRate=0、quality 永不上升,数据回路失效(B2′ 实测)。
|
||||
life('game_end', { score, completed: true, duration_ms: startMs ? Date.now() - startMs : 0 });
|
||||
}
|
||||
|
||||
// 绑定交互
|
||||
|
||||
@ -80,7 +80,9 @@ a {
|
||||
|
||||
/* 应用根容器:撑满视口、单列竖屏 */
|
||||
#app {
|
||||
min-height: 100%;
|
||||
/* 用 height(而非 min-height)建立确定高度链:使子页 .feed/.play 的 height:100% 能解析。
|
||||
否则祖先全是 min-height → 子页百分比高度无确定基准 → 塌成内容高,封面/画布 0 高不可点(B2′ 实测)。 */
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user