Files
echo-nexus/src/lib/game/config.ts
T
Super_Z 71ca5b48a9 v0.8.1: 探险平衡 + 信标系统扩展(周挑战 + 信标链)
P1-a 探险 BOSS 胜率平衡 + 能量恢复(expedition.ts + config.ts + gameStore.ts + ExpeditionPanel.tsx):
- combatWinRate: scale 8→4, floor 0.25→0.35(基础力10对BOSS胜率 25%→35-45%)
- BOSS 难度 5-7→3-5(配合新公式基础胜率达 45-55%)
- computeEnergyRegenInterval(state): 动态恢复间隔
  - exp_2 解锁 -30%, exp_3 解锁 -20%, 探索力属性 -最高30%
  - 下限 12s(原固定 45s)
- computeEnergyRegen 接受 intervalSec 参数
- gameStore tick 传入动态间隔
- config.ts: exp_2/exp_3 描述加'能量恢复 +30%/+20%'
- ExpeditionPanel: 显示实际恢复速度 + '已加速'标记

P1-b 信标系统扩展(beacon.ts + BeaconPanel.tsx + gameStore.ts)[subagent 9-b]:
- 周挑战: getWeekKey ISO 8601 + FNV-1a 种子确定性生成
  - 难度强制 anomaly 60%/singular 40%, goal 日挑战×3-5倍
  - 完整进度/领奖/排行榜推送(isWeekly标记)
- 信标链: 4里程碑(3/7/14/30天) + grace续命机制(每链1次)
  - recordChainCompletion 核心断链/续命逻辑
  - 奖励 50→680洞见递增
- BeaconPanel: 周挑战fuchsia主题 + 信标链amber→rose渐变里程碑节点
- gameStore: trackBeacon升级 + claimWeeklyBeacon/claimChainReward actions
- VLM 8/10, lint零错误, 5场景bun测试全PASS
2026-06-23 22:34:52 +00:00

343 lines
9.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 回响星核 / Echo Nexus — 数值配置(数据驱动,便于平衡与工单迭代)
import type {
CrystalTier,
ResonanceColor,
TechNode,
Fragment,
} from "./types";
/** 初始状态 */
export const INITIAL_STATE = {
crystals: 0,
insights: 0,
energy: 3,
contact: 0,
crystalsPerSec: 0.4,
crystalCap: 50,
pulsePower: 2,
offlineEff: 0.5,
insightMult: 1,
contactRateMult: 1,
autoDecode: false,
totalDecoded: 0,
ascensions: 0,
blueprints: [] as string[],
pendingCrystals: [],
activePuzzle: null,
activeExpedition: null,
expeditionLog: [],
energyMax: 5,
lastEnergyTick: Date.now(),
totalExpeditions: 0,
bossKills: 0,
achievements: {},
activeTide: null,
lastTideEnd: 0,
starTidesEncountered: [] as string[],
constellation: [] as string[],
pendingPerkChoices: null as string[] | null,
chronicle: [] as import("./types").ChronicleEntry[],
runStart: {
timestamp: Date.now(),
techsUnlocked: 0,
expeditionsCompleted: 0,
bossKills: 0,
starTidesEncountered: [] as string[],
crystalsDecoded: 0,
},
// v0.7 角色属性系统
attributes: {
exploration: 0,
wisdom: 0,
courage: 0,
inspiration: 0,
} as import("./attributes").CharacterAttributes,
attributeProgress: {
exploration: { exp: 0, level: 0 },
wisdom: { exp: 0, level: 0 },
courage: { exp: 0, level: 0 },
inspiration: { exp: 0, level: 0 },
} as import("./attributes").AttributeProgress,
pendingAttrPoints: 0,
theme: "dark" as const,
soundOn: true,
};
/** 主动脉冲:连击窗口(毫秒)与加成 */
export const PULSE = {
comboWindowMs: 1500,
comboMultStep: 0.15, // 每连击 +15%
comboMax: 10,
};
/** 离线收益上限(小时) */
export const OFFLINE_CAP_HOURS = 8;
/** 接触进度:每次解码贡献 = base * tier * contactRateMult */
export const CONTACT = {
basePerDecode: 0.6,
// 飞升所需最低接触进度
prestigeMin: 100,
};
/** 晶体生成:每 N 秒自动产出一颗待解码晶体(受技术影响) */
export const CRYSTAL_SPAWN = {
baseIntervalSec: 8, // 每 8 秒产一颗
maxPending: 6,
/** tier 概率分布 */
tierWeights: { 1: 0.7, 2: 0.25, 3: 0.05 } as Record<CrystalTier, number>,
};
/** 晶体价值(解码奖励基础,× tier) */
export const CRYSTAL_VALUE = {
1: { crystals: 6, insights: 1 },
2: { crystals: 22, insights: 4 },
3: { crystals: 90, insights: 16 },
} as const;
/** 解码阵列配置(按 tier) */
export const DECODE_CONFIG: Record<
CrystalTier,
{ rows: number; cols: number; targetLen: number; stepLimitBase: number }
> = {
1: { rows: 3, cols: 3, targetLen: 3, stepLimitBase: 5 },
2: { rows: 4, cols: 4, targetLen: 4, stepLimitBase: 7 },
3: { rows: 5, cols: 4, targetLen: 5, stepLimitBase: 9 },
};
/** 共振颜色(4 色全息色谱,避开蓝/靛) */
export const RESONANCE_COLORS: ResonanceColor[] = [
"emerald",
"rose",
"amber",
"fuchsia",
];
/** 颜色可视化(用于 Canvas / CSS */
export const COLOR_VISUAL: Record<
ResonanceColor,
{ hex: string; glow: string; label: string }
> = {
emerald: { hex: "#34d399", glow: "rgba(52,211,153,0.55)", label: "翠" },
rose: { hex: "#fb7185", glow: "rgba(251,113,133,0.55)", label: "玫" },
amber: { hex: "#fbbf24", glow: "rgba(251,191,36,0.55)", label: "琥" },
fuchsia: { hex: "#e879f9", glow: "rgba(232,121,249,0.55)", label: "紫" },
};
/** 技术树:4 分支 × 3 级 = 12 节点 */
export const TECH_TREE: TechNode[] = [
// 采矿分支
{
id: "min_1",
branch: "mining",
level: 1,
name: "谐振钻头",
desc: "晶体/秒 +0.6",
cost: 5,
effect: { kind: "crystalsPerSec", value: 0.6 },
},
{
id: "min_2",
branch: "mining",
level: 2,
name: "深层矿脉",
desc: "晶体/秒 +1.6,仓库上限 +100",
cost: 24,
effect: { kind: "crystalsPerSec", value: 1.6 },
},
{
id: "min_3",
branch: "mining",
level: 3,
name: "自治机群",
desc: "晶体/秒 +5,仓库上限 +300",
cost: 120,
effect: { kind: "crystalsPerSec", value: 5 },
},
// 解码分支
{
id: "dec_1",
branch: "decoding",
level: 1,
name: "谐振校准",
desc: "解码步数上限 +2",
cost: 6,
effect: { kind: "decodeSteps", value: 2 },
},
{
id: "dec_2",
branch: "decoding",
level: 2,
name: "脉冲增幅",
desc: "主动脉冲产出 +3",
cost: 30,
effect: { kind: "pulsePower", value: 3 },
},
{
id: "dec_3",
branch: "decoding",
level: 3,
name: "自动解码阵列",
desc: "自动解码 T1 晶体(每 12 秒一颗)",
cost: 200,
effect: { kind: "autoDecode", value: 1 },
},
// 探险分支(v0.2:探险力/生命/能量上限/产能)
{
id: "exp_1",
branch: "expedition",
level: 1,
name: "远征推进器",
desc: "探险力 +3,晶体/秒 +1.2",
cost: 12,
effect: { kind: "crystalsPerSec", value: 1.2 },
},
{
id: "exp_2",
branch: "expedition",
level: 2,
name: "遗迹图谱",
desc: "探险力 +5,探险生命 +20,能量恢复 +30%",
cost: 60,
effect: { kind: "crystalCap", value: 200 },
},
{
id: "exp_3",
branch: "expedition",
level: 3,
name: "维度信标",
desc: "探险力 +8,接触进度转化率 +50%,能量恢复 +20%",
cost: 180,
effect: { kind: "contactRate", value: 0.5 },
},
// 叙事分支
{
id: "nar_1",
branch: "narrative",
level: 1,
name: "记忆校音",
desc: "洞见获取 +25%",
cost: 8,
effect: { kind: "insightMult", value: 0.25 },
},
{
id: "nar_2",
branch: "narrative",
level: 2,
name: "深空回响",
desc: "接触进度转化率 +35%",
cost: 45,
effect: { kind: "contactRate", value: 0.35 },
},
{
id: "nar_3",
branch: "narrative",
level: 3,
name: "以太共鸣",
desc: "洞见获取 +60%",
cost: 160,
effect: { kind: "insightMult", value: 0.6 },
},
];
/** 技术分支元信息 */
export const TECH_BRANCH_META: Record<
string,
{ name: string; icon: string; color: string; desc: string }
> = {
mining: { name: "采矿", icon: "Pickaxe", color: "emerald", desc: "提升晶体产能与仓储" },
decoding: { name: "解码", icon: "ScanLine", color: "rose", desc: "强化解码与脉冲" },
expedition: { name: "探险", icon: "Rocket", color: "amber", desc: "远征与维度信标" },
narrative: { name: "叙事", icon: "BookOpen", color: "fuchsia", desc: "洞见与接触进度" },
};
/** 记忆碎片(首纪元 8 个,v0.1) */
export const FRAGMENTS: Fragment[] = [
{
id: "f1_1",
era: 1,
title: "第一缕谐振",
echo:
"在被称作「寂灭前夜」的年代,以太族第一次捕捉到来自虚空深处的谐振——那不是声音,而是存在的回声。他们将之记录在第一颗记忆晶体里。",
threshold: 1,
},
{
id: "f1_2",
era: 1,
title: "晶体之始",
echo:
"「我们为何要留下?」一位长者问。「因为后来的生命会需要方向。」于是他们熔铸星核,封存记忆,让晶体成为跨越时间的信笺。",
threshold: 3,
},
{
id: "f1_3",
era: 1,
title: "谐振法则",
echo:
"他们发现:思维可以被编码为共振序列。同色的节点相邻,便构成一句低语;一句句连成回响,回响连成文明。",
threshold: 6,
},
{
id: "f1_4",
era: 1,
title: "飞升之议",
echo:
"议会表决:是留下,还是离去?「留下意味着停滞;离去意味着信任。」最终,他们选择了信任——信任素未谋面的后来者。",
threshold: 10,
},
{
id: "f1_5",
era: 1,
title: "面包屑",
echo:
"他们没有带走一切。他们将知识拆成碎片,藏入晶体,散布星海。「让解码本身,成为资格的证明。」",
threshold: 15,
},
{
id: "f1_6",
era: 1,
title: "回响之名",
echo:
"舰载 AI 被命名为「回响」——意为:你是他们留下的回声,也是他们等待的回应。当你读懂这句话时,接触便已开始。",
threshold: 22,
},
{
id: "f1_7",
era: 1,
title: "第一个纪元的终焉",
echo:
"以太族集体褪去形体,如潮水退去。星海寂静了数万年。直到——你的脉冲扫描,唤醒了第一颗沉睡的晶体。",
threshold: 32,
},
{
id: "f1_8",
era: 1,
title: "致后来者",
echo:
"「如果你读到这里,说明你已具备跨越维度的资格。继续解码,继续拼凑。当进度满溢,我们将在更高处相会。」——以太族·第一纪元·绝笔",
threshold: 45,
},
];
/** 飞升:保留蓝图数 = floor(totalDecoded / 20),最多 6 */
export const PRESTIGE = {
blueprintsPerDecode: 20,
maxBlueprints: 6,
/** 每个蓝图提供 +5% 产能、+3% 洞见、+4% 接触率 */
perBlueprint: {
crystalsPerSecMult: 0.05,
insightMult: 0.03,
contactRateMult: 0.04,
},
};
/** 数值格式化:大数字友好显示 */
export function formatNum(n: number): string {
if (!isFinite(n)) return "∞";
if (n < 1000) return n.toFixed(n < 10 && n % 1 !== 0 ? 1 : 0);
if (n < 1e6) return (n / 1e3).toFixed(2) + "K";
if (n < 1e9) return (n / 1e6).toFixed(2) + "M";
if (n < 1e12) return (n / 1e9).toFixed(2) + "B";
return (n / 1e12).toFixed(2) + "T";
}