Extend square-hole creation flow with visual asset timeout guard
This commit is contained in:
@@ -7,9 +7,10 @@ import type {
|
||||
CustomWorldGenerationProgress,
|
||||
CustomWorldGenerationStep,
|
||||
} from '../../packages/shared/src/contracts/runtime';
|
||||
import type { SquareHoleSessionSnapshot } from '../../packages/shared/src/contracts/squareHoleAgent';
|
||||
import type { CustomWorldStructuredAnchorEntry } from './customWorldAgentGenerationProgress';
|
||||
|
||||
export type MiniGameDraftGenerationKind = 'puzzle' | 'big-fish';
|
||||
export type MiniGameDraftGenerationKind = 'puzzle' | 'big-fish' | 'square-hole';
|
||||
|
||||
export type MiniGameDraftGenerationPhase =
|
||||
| 'idle'
|
||||
@@ -17,6 +18,10 @@ export type MiniGameDraftGenerationPhase =
|
||||
| 'big-fish-draft'
|
||||
| 'big-fish-levels'
|
||||
| 'big-fish-runtime'
|
||||
| 'square-hole-draft'
|
||||
| 'square-hole-cover'
|
||||
| 'square-hole-shapes'
|
||||
| 'square-hole-ready'
|
||||
| 'puzzle-images'
|
||||
| 'puzzle-select-image'
|
||||
| 'ready'
|
||||
@@ -86,12 +91,39 @@ const BIG_FISH_STEPS = [
|
||||
},
|
||||
] as const satisfies ReadonlyArray<MiniGameStepDefinition>;
|
||||
|
||||
const SQUARE_HOLE_STEPS = [
|
||||
{
|
||||
id: 'square-hole-draft',
|
||||
label: '整理玩法草稿',
|
||||
detail: '收拢题材、形状、洞口与加分选项。',
|
||||
weight: 28,
|
||||
},
|
||||
{
|
||||
id: 'square-hole-cover',
|
||||
label: '生成封面与背景',
|
||||
detail: '生成作品封面和运行背景。',
|
||||
weight: 32,
|
||||
},
|
||||
{
|
||||
id: 'square-hole-shapes',
|
||||
label: '生成形状贴图',
|
||||
detail: '为每个可投放形状生成贴图。',
|
||||
weight: 40,
|
||||
},
|
||||
] as const satisfies ReadonlyArray<MiniGameStepDefinition>;
|
||||
|
||||
function clampProgress(value: number) {
|
||||
return Math.max(0, Math.min(100, Math.round(value)));
|
||||
}
|
||||
|
||||
function getStepDefinitions(kind: MiniGameDraftGenerationKind) {
|
||||
return kind === 'puzzle' ? PUZZLE_STEPS : BIG_FISH_STEPS;
|
||||
if (kind === 'puzzle') {
|
||||
return PUZZLE_STEPS;
|
||||
}
|
||||
if (kind === 'square-hole') {
|
||||
return SQUARE_HOLE_STEPS;
|
||||
}
|
||||
return BIG_FISH_STEPS;
|
||||
}
|
||||
|
||||
function getActiveStepIndex(
|
||||
@@ -132,7 +164,12 @@ export function createMiniGameDraftGenerationState(
|
||||
): MiniGameDraftGenerationState {
|
||||
return {
|
||||
kind,
|
||||
phase: kind === 'big-fish' ? 'big-fish-draft' : 'compile',
|
||||
phase:
|
||||
kind === 'big-fish'
|
||||
? 'big-fish-draft'
|
||||
: kind === 'square-hole'
|
||||
? 'square-hole-draft'
|
||||
: 'compile',
|
||||
startedAtMs: Date.now(),
|
||||
completedAssetCount: 0,
|
||||
totalAssetCount: 0,
|
||||
@@ -152,6 +189,18 @@ function resolveBigFishPhaseByElapsedMs(
|
||||
return 'big-fish-draft';
|
||||
}
|
||||
|
||||
function resolveSquareHolePhaseByElapsedMs(
|
||||
elapsedMs: number,
|
||||
): MiniGameDraftGenerationPhase {
|
||||
if (elapsedMs >= 6_500) {
|
||||
return 'square-hole-shapes';
|
||||
}
|
||||
if (elapsedMs >= 2_400) {
|
||||
return 'square-hole-cover';
|
||||
}
|
||||
return 'square-hole-draft';
|
||||
}
|
||||
|
||||
export function buildMiniGameDraftGenerationProgress(
|
||||
state: MiniGameDraftGenerationState | null,
|
||||
nowMs = Date.now(),
|
||||
@@ -169,6 +218,13 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
...state,
|
||||
phase: resolveBigFishPhaseByElapsedMs(elapsedMs),
|
||||
}
|
||||
: state.kind === 'square-hole' &&
|
||||
state.phase !== 'failed' &&
|
||||
state.phase !== 'ready'
|
||||
? {
|
||||
...state,
|
||||
phase: resolveSquareHolePhaseByElapsedMs(elapsedMs),
|
||||
}
|
||||
: state;
|
||||
|
||||
const steps = getStepDefinitions(normalizedState.kind);
|
||||
@@ -190,6 +246,8 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
? 1
|
||||
: normalizedState.kind === 'big-fish'
|
||||
? 0.55
|
||||
: normalizedState.kind === 'square-hole'
|
||||
? 0.42
|
||||
: 0;
|
||||
const overallProgress =
|
||||
normalizedState.phase === 'failed'
|
||||
@@ -223,6 +281,8 @@ export function buildMiniGameDraftGenerationProgress(
|
||||
? 0
|
||||
: normalizedState.kind === 'big-fish'
|
||||
? Math.max(0, 7_000 - elapsedMs)
|
||||
: normalizedState.kind === 'square-hole'
|
||||
? Math.max(0, 12_000 - elapsedMs)
|
||||
: null,
|
||||
activeStepIndex,
|
||||
steps: buildMiniGameProgressSteps(steps, activeStepIndex, normalizedState),
|
||||
@@ -306,3 +366,46 @@ export function buildBigFishGenerationAnchorEntries(
|
||||
}))
|
||||
.filter((entry) => entry.value.trim());
|
||||
}
|
||||
|
||||
export function buildSquareHoleGenerationAnchorEntries(
|
||||
session: SquareHoleSessionSnapshot | null | undefined,
|
||||
): CustomWorldStructuredAnchorEntry[] {
|
||||
if (!session) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const draft = session.draft;
|
||||
const shapeCount =
|
||||
draft?.shapeOptions.filter((option) => option.imageSrc?.trim()).length ??
|
||||
session.config.shapeOptions.filter((option) => option.imageSrc?.trim())
|
||||
.length;
|
||||
const totalShapeCount =
|
||||
draft?.shapeOptions.length || session.config.shapeOptions.length;
|
||||
|
||||
const entries: Array<MiniGameAnchorSource | null> = [
|
||||
{
|
||||
key: 'square-hole-title',
|
||||
label: '作品名称',
|
||||
value: draft?.gameName || `${session.config.themeText}方洞挑战`,
|
||||
},
|
||||
{
|
||||
key: 'square-hole-theme',
|
||||
label: '题材与规则',
|
||||
value: `${session.config.themeText}|${session.config.twistRule}`,
|
||||
},
|
||||
{
|
||||
key: 'square-hole-options',
|
||||
label: '选项资产',
|
||||
value: totalShapeCount > 0 ? `形状贴图 ${shapeCount}/${totalShapeCount}` : '',
|
||||
},
|
||||
];
|
||||
|
||||
return entries
|
||||
.filter((entry): entry is MiniGameAnchorSource => Boolean(entry))
|
||||
.map((entry) => ({
|
||||
id: entry.key,
|
||||
label: entry.label,
|
||||
value: entry.value,
|
||||
}))
|
||||
.filter((entry) => entry.value.trim());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user