v0.8.2: 工单大清理 - 编年史分页+限时挑战+星潮深化+云排行榜+手写叙事+socket多人星潮+UI打磨

工单 #8 编年史上限+分页:
- engine.ts: slice(-50)→slice(-200)
- ChronicleDialog.tsx: 加分页(每页10条)+上一页/下一页+页码显示

工单 #5 限时挑战 (subagent 10-a):
- beacon.ts: BeaconTimedChallenge + getTimedSlotKey(4h时段) + generateTimedChallenge
- BeaconPanel.tsx: amber主题限时区块 + 倒计时 + <30min紧急状态
- gameStore: trackBeacon 加 timedJustCompleted + claimTimedBeacon action

工单 #3 星潮类型深化 (subagent 10-a):
- starTide.ts: +3种星潮 surge(emerald)/eclipse(rose)/prism(fuchsia)
- TideModifiers: +targetLenBonus/bossWinRateBonus/autoDecodeIntervalMult
- decode.ts: generatePuzzle 加 targetLenBonus 参数
- achievements: ach_tides_all 阈值 6→9

工单 #4/P2 云排行榜 (subagent 10-b):
- mini-services/leaderboard-service/ (端口3030, Hono+bun, 内存1000条)
- API: GET/POST /api/leaderboard + /stats + CORS + 防刷
- beacon.ts: fetchCloudLeaderboard/submitCloudScore
- BeaconPanel: 本地Top20/全球Top100 双tab + YOU徽章高亮

工单 #9 手写叙事 (subagent 10-c):
- chronicle.ts: EPOCH_LORE 5纪元×3节点=15段手写叙事(80-150字/段)
- buildLore 优先手写节点, fallback 模板, 11个变量替换

P3 socket 多人星潮 (subagent 10-c):
- mini-services/star-tide-service/ (端口3031, socket.io)
- 每10-15min广播global-tide, 60s持续, 6种类型权重
- useGlobalTide hook + triggerGlobalTide action
- StarTideIndicator 加 🌐 全球星潮标记

P2 UI打磨:
- page.tsx: CrystalOrb 区加装饰全息环(3层旋转) + 四角标记 + 顶部状态条 + 底部铭文

QA: lint零错误 + dev HTTP200 + VLM 8/10 + 2个mini-service运行中(3030/3031)
This commit is contained in:
2026-06-23 23:57:41 +00:00
parent 6d7c52daa9
commit 191434e6ad
55 changed files with 9026 additions and 129 deletions
+25 -2
View File
@@ -27,6 +27,7 @@ import {
} from "@/components/game/StarTide";
import { useGameLoop } from "@/hooks/useGameLoop";
import { useAudioSync } from "@/hooks/useAudio";
import { useGlobalTide } from "@/hooks/useGlobalTide";
import { useGameStore } from "@/store/gameStore";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { Button } from "@/components/ui/button";
@@ -54,6 +55,7 @@ import { generateDailyChallenge, loadDailyProgress, loadLeaderboard } from "@/li
export default function Page() {
useGameLoop();
useAudioSync();
useGlobalTide();
const [prestigeOpen, setPrestigeOpen] = useState(false);
const [settingsOpen, setSettingsOpen] = useState(false);
const [constellationOpen, setConstellationOpen] = useState(false);
@@ -73,6 +75,7 @@ export default function Page() {
const crystals = useGameStore((s) => s.crystals);
const crystalCap = useGameStore((s) => s.crystalCap);
const activeTide = useGameStore((s) => s.activeTide);
const globalTide = useGameStore((s) => s.globalTide);
const energy = useGameStore((s) => s.energy);
const hasActiveExpedition = useGameStore((s) => !!s.activeExpedition && !s.activeExpedition.finished);
const chronicleCount = useGameStore((s) => s.chronicle?.length ?? 0);
@@ -148,7 +151,8 @@ export default function Page() {
}
if (activeTide) {
const tm = TIDE_EVENTS[activeTide.type];
goal = `${tm.icon} 星潮「${tm.name}」进行中 · ${tm.desc}`;
const prefix = globalTide ? "🌐 全球星潮 · " : "";
goal = `${prefix}${tm.icon} 星潮「${tm.name}」进行中 · ${tm.desc}`;
}
if (canPrestige) goal = "✦ 接触进度已满,可发起飞升进入新周目";
@@ -249,6 +253,25 @@ export default function Page() {
{/* 装饰光圈 */}
<div className="pointer-events-none absolute -top-20 -left-20 h-60 w-60 rounded-full bg-emerald-500/10 blur-3xl" />
<div className="pointer-events-none absolute -bottom-20 -right-20 h-60 w-60 rounded-full bg-fuchsia-500/10 blur-3xl" />
{/* v0.8.2 装饰全息环(填充留白,提升视觉层次) */}
<div className="pointer-events-none absolute inset-6 rounded-full border border-emerald-400/10 animate-[spin_60s_linear_infinite]" />
<div className="pointer-events-none absolute inset-10 rounded-full border border-dashed border-fuchsia-400/10 animate-[spin_90s_linear_infinite_reverse]" />
<div className="pointer-events-none absolute inset-16 rounded-full border border-rose-400/8" />
{/* 四角全息标记 */}
<div className="pointer-events-none absolute top-3 left-3 h-4 w-4 border-l border-t border-emerald-400/30 rounded-tl" />
<div className="pointer-events-none absolute top-3 right-3 h-4 w-4 border-r border-t border-fuchsia-400/30 rounded-tr" />
<div className="pointer-events-none absolute bottom-3 left-3 h-4 w-4 border-l border-b border-amber-400/30 rounded-bl" />
<div className="pointer-events-none absolute bottom-3 right-3 h-4 w-4 border-r border-b border-rose-400/30 rounded-br" />
{/* 顶部状态条 */}
<div className="pointer-events-none absolute top-3 left-1/2 -translate-x-1/2 flex items-center gap-2 text-[9px] font-mono text-muted-foreground/60">
<span className="h-1 w-1 rounded-full bg-emerald-400 animate-pulse" />
<span>CRYSTAL CORE · ONLINE</span>
<span className="h-1 w-1 rounded-full bg-fuchsia-400 animate-pulse" />
</div>
{/* 底部铭文 */}
<div className="pointer-events-none absolute bottom-3 left-1/2 -translate-x-1/2 text-[8px] font-mono text-muted-foreground/40 tracking-[0.3em] uppercase">
echo · nexus · archaeology
</div>
<div data-tut="crystal-orb" className="contents">
<CrystalOrb />
</div>
@@ -433,7 +456,7 @@ function StatsPanel() {
{ label: "洞见倍率", value: `×${s.insightMult.toFixed(2)}` },
{ label: "累计探险", value: `${s.totalExpeditions}` },
{ label: "BOSS 击破", value: `${s.bossKills ?? 0}` },
{ label: "星潮亲历", value: `${(s.starTidesEncountered ?? []).length} / 6` },
{ label: "星潮亲历", value: `${(s.starTidesEncountered ?? []).length} / 9` },
{ label: "编年史条目", value: `${(s.chronicle ?? []).length} 纪元` },
{ label: "探险能量", value: `${Math.floor(s.energy)} / ${s.energyMax}` },
{ label: "信标最高分", value: beaconBest !== null ? formatNum(beaconBest) : "—" },