后室层级生成器B A C K R O O M S   L E V E L   G E N E R A T O R

档案库:M.E.G. 中央数据库(模拟) | 全部字段由生成器随机决定,无人工参数 | 输出内容均为虚构创作
已生成主层级:0
本次条目数:0(含子层级)
最近生成:—
随机内容包括:层群与编号、生存难度、安全性、稳定性、实体数量、环境形态与内部构造、层级特性、实体清单、可获取物资、 入口层级、出口类型(含秒死 / 永世折磨 / 永世宜居 / 无出口)、团体与前哨、子层级数量(子层级可再生成两位小数的子层级)、 是否被删除(约 10%)、是否被重写(约 22%)。
生存难度 / 安全性 / 稳定性 / 实体数量四者按后室档案规范联动生成,不会出现互相矛盾的组合。
编号规则:主层级 Level X | 一级子层级 Level X.Y | 二级子层级 Level X.YZ(两位小数),子层级拥有独立完整的全部字段。
「已删除」层级坠入破碎之地;「已重写」层级同时列出重写前与重写后的档案对照。
, nameCn: "锈蚀矿道", nameEn: "The Rusted Mines", size: "未知", structure: "人工开凿的矿道与天然溶洞交错", floor: "碎石与废弃轨道", wall: "岩壁与腐朽木支撑", ceiling: "钟乳石与塌方区", light: "矿灯与自发光的苔藓", sound: "石块掉落与深处挖掘声", smell: "硫磺与尘土", temp: "约 11°C", phe: ["重力异常", "无信号", "窥视感", "温度骤变"], tags: ["黑暗", "塌方风险", "矿物资丰富"] }, { type: "镜厅", nameCn: "镜之回廊", nameEn: "Hall of Mirrors", size: "约 2 平方公里后无限", structure: "由镜面构成的回廊,倒影与本体行为不一致", floor: "黑白棋盘大理石", wall: "整面落地镜", ceiling: "镜面天花板(映出下方)", light: "无光源,来自镜面自身", sound: "玻璃震动的高频嗡鸣", smell: "玻璃清洁剂", temp: "约 20°C", phe: ["镜像复制", "复制排斥", "集体幻觉", "实体拟态"], tags: ["反射异常", "自我认知危害", "陷阱"] }, { type: "雪原", nameCn: "白色雪原", nameEn: "The White Expanse", size: "疑似无限", structure: "平坦无垠的雪地,偶尔出现公路牌与废弃车辆", floor: "厚达两米的积雪", wall: "无墙壁,视野被风雪限制在十米内", ceiling: "铅灰色低云", light: "昏暗的散射光", sound: "风雪呼啸与远处引擎声", smell: "冰冷的金属味", temp: "约 -18°C,暴风雪时 -40°C", phe: ["温度骤变", "记忆衰减", "磁场紊乱"], tags: ["严寒", "开阔", "体温威胁"] }, { type: "学校", nameCn: "末日校园", nameEn: "The Last School", size: "约 5 平方公里", structure: "教学楼、操场与宿舍组成的封闭园区,教室永远在上课", floor: "水磨石与塑胶跑道", wall: "绿黑板与张贴的旧海报", ceiling: "吊扇(从不转动)", light: "日光灯与走廊应急灯", sound: "上课铃与听不清的讲课声", smell: "粉笔灰与消毒水", temp: "约 21°C", phe: ["记忆衰减", "声音倒放", "昼夜循环", "实体拟态"], tags: ["人造", "童年记忆异常", "实体伪装"] }, { type: "数据空间", nameCn: "数据深渊", nameEn: "The Data Abyss", size: "概念性无限", structure: "由发光网格与漂浮数据块构成的非实体空间", floor: "不存在地面,流浪者可悬浮行走", wall: "流动的二进制瀑布", ceiling: "与地面完全对称", light: "蓝色自发光", sound: "调制解调器噪音与断线音", smell: "无气味(嗅觉在此失效)", temp: "无温度概念", phe: ["重力丧失", "语言丧失", "无信号", "液态记忆"], tags: ["数字", "非物理", "意识危害"] }, { type: "游乐园", nameCn: "锈蚀游乐园", nameEn: "Rustland Park", size: "约 8 平方公里", structure: "过山车、旋转木马与摊位,设施会自行启动", floor: "沥青与彩色塑胶", wall: "围栏与褪色的卡通立牌", ceiling: "露天(但看不到天空)", light: "彩灯与探照灯", sound: "欢快音乐(音调逐渐走低)", smell: "棉花糖与机油", temp: "约 22°C", phe: ["声音倒放", "集体幻觉", "静止效应", "实体拟态"], tags: ["陷阱", "实体伪装", "设施危害"] }, { type: "列车", nameCn: "云端列车", nameEn: "The Cloudliner", size: "单列车厢,长度不定", structure: "一列永不停靠的列车,窗外是流动的云海与破碎站台", floor: "车厢地毯与连接处铁板", wall: "车厢内饰与车窗", ceiling: "行李架与顶灯", light: "暖色车厢灯", sound: "车轮节奏声与广播报站(站名不存在)", smell: "空调与旧皮革", temp: "约 24°C", phe: ["时间流速不均", "门后偏移", "广播噪音", "无限循环"], tags: ["移动", "封闭", "时间异常"] }, { type: "医院", nameCn: "白色病房", nameEn: "The White Ward", size: "约 3 平方公里", structure: "走廊、病房与手术室,病床永远整理整齐", floor: "白色 PVC 地胶", wall: "瓷砖与医疗海报", ceiling: "吊顶与输液轨道", light: "无影灯与走廊夜灯", sound: "心电监护仪的滴答声", smell: "消毒水与腐败", temp: "约 20°C", phe: ["精神污染", "老化加速", "静止效应", "门后偏移"], tags: ["医疗物资", "精神危害", "实体出没"] }, { type: "森林", nameCn: "迷雾森林", nameEn: "The Foggy Grove", size: "疑似无限", structure: "树龄惊人的密林,树木排列方式违反自然规律", floor: "腐叶与裸露树根", wall: "树干(间距恒定)", ceiling: "树冠,看不见天空", light: "散射的灰白光", sound: "鸟鸣(但林中无鸟)", smell: "湿木与菌类", temp: "约 12°C", phe: ["空间错位", "无限循环", "窥视感", "褪色效应"], tags: ["自然", "迷路风险", "可采集"] }, { type: "仓库", nameCn: "无尽仓储", nameEn: "The Endless Warehouse", size: "疑似无限", structure: "成排货架与集装箱,编号为永不重复的随机数", floor: "环氧地坪", wall: "波纹钢板", ceiling: "高达 30 米的钢架", light: "高空钠灯(大量损坏)", sound: "叉车声与卷帘门升降声", smell: "纸箱与柴油", temp: "约 16°C", phe: ["物资自发刷新", "空间错位", "无信号", "复制排斥"], tags: ["物资极丰富", "昏暗", "安全区可能"] }, { type: "天空", nameCn: "浮空回廊", nameEn: "The Skywalk", size: "无法测量", structure: "悬浮在虚空中的石制回廊与断桥,下方是无底深渊", floor: "风化石板", wall: "残缺栏杆与拱门", ceiling: "无尽的灰白天空", light: "无方向的柔和光", sound: "风声与自己掉落物件的遥远回声", smell: "稀薄臭氧", temp: "约 10°C", phe: ["重力异常", "重力丧失", "静止效应", "窥视感"], tags: ["坠落风险", "开阔", "孤立"] } ]; const GROUPS = [ { n: "M.E.G.(探险者总署)", a: "友好", s: "设有正式前哨与补给站", d: "后室规模最大的探索与救援组织,愿意以物资换取情报。" }, { n: "B.N.T.G.(后室贸易集团)", a: "交易", s: "设有商队与临时集市", d: "以杏仁水与武器为主要通货,交易时严格遵守自己的契约。" }, { n: "后室殖民者", a: "友好", s: "拥有固定农业据点", d: "试图在本层级建立长期定居点的流浪者联盟,接受新成员。" }, { n: "阿尔戈斯之眼", a: "中立", s: "仅有观测点", d: "只记录不干涉,任何求助都会被礼貌地拒绝并记录。" }, { n: "杏仁水公司", a: "交易", s: "控制着一处涌泉", d: "垄断周边水源,禁止私采,护送队装备精良。" }, { n: "沉默修会", a: "中立", s: "无固定据点", d: "拒绝一切交流的信徒,会为陌生人留下食物后离开。" }, { n: "守夜人", a: "友好", s: "设有灯塔式警戒站", d: "专门警告后来者危险区域的组织,情报极其可靠。" }, { n: "儿童(The Children)", a: "未知", s: "行踪不定", d: "行为难以预测,有时无偿救助,有时毫无理由地攻击。" }, { n: "杰瑞的信徒", a: "敌对", s: "设有祭坛", d: "狂热的宗教团体,会将外来者视为祭品。" }, { n: "红色石匠", a: "极不友好", s: "据点位置保密", d: "极度排外,攻击任何靠近其工地的流浪者。" }, { n: "派对客集群", a: "敌对", s: "无固定据点,游荡", d: "以猎杀为乐,会伪装成庆祝活动引诱流浪者。" }, { n: "悲尸军团", a: "敌对", s: "占据废弃建筑", d: "受绝望驱动的成群实体,会主动追击任何活物。" }, { n: "数据教团", a: "未知", s: "仅在网络中出现", d: "声称层级本身是有意识的,试图与之对话。" }, { n: "蛾类崇拜者", a: "敌对", s: "巢穴深处", d: "将死亡飞蛾视为神明,会献祭闯入者。" } ]; const EXIT_METHOD = [ "卡入(Noclip)特定墙角或地板", "从高处坠入虚空", "在指定房间内入睡后醒来", "潜入泳池底部穿过排水口", "打开标有特定编号的门", "穿过镜子并在倒影中保持不动", "逆行穿过走廊(不可回头)", "爬入通风管道并持续爬行", "进入电梯并按下不存在的楼层", "游过整片水域到达对岸", "跟随广播信号走到源头", "关闭所有光源后静候十分钟", "撕开墙纸并钻入墙体", "跳下悬崖并在坠落中失去意识", "沿铁轨行走至信号消失处", "在地图上标记一个位置后徒步前往", "被实体杀死(死亡后于其他层级苏醒)", "烧毁一件随身物品", "脱下所有衣物后穿过雾墙", "长时间凝视同一扇窗" ]; const EXIT_COND = ["需独自一人", "需三至五人同行", "需携带杏仁水", "需电量耗尽的手电", "需在层级内停留超过 72 小时", "需在黑暗中完成", "需无任何金属物品", "需在特定时间段(约每 26 小时一次)", "需处于受伤状态", "需放弃一件个人物品作为交换", "无附加条件", "需先解开墙上的谜题", "需保持沉默直至穿越完成"]; const TORMENT_STYLE = [ "空间会不断重排,使任何前进都回到原点,同时持续播放受害者亲属的声音", "伤口永不愈合,且痛觉被放大数倍,杏仁水无法缓解", "时间被无限拉长,一分钟被感知为一周,饥饿与干渴永远无法真正满足", "体温持续流失却无法死亡,流浪者会保持清醒直到精神彻底瓦解", "每隔数小时会被传送回起点,且保留全部痛苦记忆", "实体不会杀死流浪者,只会不断造成伤害并将其拖回层级中心", "重力周期反转,坠落与撞击反复发生,骨骼与意识同时碎裂" ]; const ETERNAL_GOOD = [ "物资自发刷新,气候宜人且无实体出没,可长期舒适定居,代价是永远无法离开", "层级内有完整的居住设施与稳定水源,居民已建立小型社会,唯一的遗憾是无法返回前室", "时间在此停滞,居民不会衰老也不会饥饿,代价是永远看不到新的面孔", "环境优美且绝对安全,所有出口均已永久关闭,定居者普遍心态平和并拒绝救援" ]; const INSTA_DEATH = [ "切入本层级后平均存活 4 秒,流浪者会在完成一次呼吸前被空间结构直接撕碎", "本层级内部为绝对真空与极端低温,进入者的躯体在 2 秒内碎裂", "层级内的空气为高浓度腐蚀性气体,任何生物在 6 秒内溶解", "进入者的意识会被瞬间剥离并塞入墙壁,躯体在 3 秒内碳化", "层级本身即为一处死亡陷阱,重力在此处为无限大,任何物质都会被压缩成一个点", "切入瞬间即触发层级特性:流浪者会被分解为基本粒子并散布到多个层级" ]; const DELETE_REASON = [ "层级结构在一次未记录的层级碰撞后彻底崩溃,剩余部分坠入破碎之地", "被未知实体完全吞噬,数据库记录仅余碎片", "因层级内核损坏而被管理员手动移除", "在一次全域重写事件中被判定为冗余并删除", "被相邻层级的扩张挤压吞并,编号保留但本体已不存在", "由于观测者全部失踪,该层级失去存在的锚点而消散" ]; const REWRITE_WHO = [ "由 M.E.G. 中央档案处重新审定", "由匿名管理员提交修订(来源 IP 无法追踪)", "因数据库损坏后自动修复程序重建内容", "由层级自身的结构性修正(自我重写)", "由某不明团体篡改(原始版本已备份但无法访问)", "因一次编辑战争后的折中版本", "由后室本身的纠错机制覆盖", "由一位自称来自本层级的实体提交" ]; const EXPLORE = ["已完全测绘", "部分探索(约 60% 区域已记录)", "极少探索(仅有一次成功记录)", "仅存理论推演,无实测数据", "探索数据互相矛盾,无法确认", "曾完全探索,但该记录已被作废"]; const TAGS_EXTRA = ["宜居候选", "非欧几里得", "无限", "孤立", "实体密集", "无补给", "疑似人造", "自然生成", "时间异常", "空间异常", "已归档", "争议条目", "档案残缺", "需谨慎引用", "高危心理危害"]; /* ===================== 编号 ===================== */ function genRootId() { const r = Math.random(); let n, group; if (r < .68) { n=R(0, 999); group="主层群" ; } else if (r < .80) { n=-R(1, 60); group="负层群" ; } else if (r < .90) { n=R(1000, 1499); group="层群 II" ; } else if (r < .97) { n=R(3000, 9999); group="隐藏层群" ; } else { n=R(0, 999); group="未分类层群" ; } return { id: "Level " + (n < 0 ? "-" + Math.abs(n) : n), group: group }; } /* 子层级编号:一级 X.Y,二级 X.YZ(两位小数) */ function subId(parent, depth, i) { return depth===0 ? parent + "." + i : parent + i; } /*=====================联动核心=====================*/ function tierOf(cls) { return cls.tier; } function ruleFor(cls) { const t=cls.tier; if (t===-1 || t===-3) return TIER_UNK; // 未定级 / 不可测 if (t===-2) return TIER[R(0, 5)]; // 变化 if (t===9) return TIER[6]; return TIER[t]; } function maxThreatFor(tier) { if (tier <=0) return 2; // 至多中危 if (tier===1) return 2; if (tier===2) return 3; // 至多高危 return 4; } function rollEntities(cls, entLevel) { const rule=ENT_RULE[entLevel]; if (rule.n===0) return []; let pool=ENTITY_DB; if (rule.harmlessOnly) pool=ENTITY_DB.filter(e=> e.thr === "无害"); else { const mt = maxThreatFor(cls.tier); const lim = (cls.tier < 0) ? 3 : mt; const f=ENTITY_DB.filter(e=> THR_ORDER[e.thr] <= lim); // 高难度时剔除无害实体,低难度时剔除致命实体 const f2=(cls.tier>= 3) ? f.filter(e => e.thr !== "无害") : f; pool = f2.length ? f2 : f; } const n = (entLevel === "无有害实体") ? R(1, 2) : rule.n; const out = pickN(pool, Math.min(n, pool.length)); if (out.length === 0) { // 兜底:确保实体数量与「实体数量」字段一致 return pickN(rule.harmlessOnly ? ENTITY_DB.filter(e => e.thr === "无害") : ENTITY_DB, 1); } return out; } /* 依据难度重抽安全性/稳定性/实体数量,并同步实体清单 —— 保证四项自洽 */ function syncDerived(lv) { const rule = ruleFor(lv.cls); lv.safety = P(rule.safe); lv.stability = P(rule.stab); lv.entdens = P(rule.ent); lv.entities = rollEntities(lv.cls, lv.entdens); lv.tierRule = rule; } function exitWeights(cls) { const t = cls.tier; if (t <= 0) return [["normal", 70], ["eternal", 18], ["noexit", 10], ["torment", 2], ["insta", 0]]; if (t===1) return [["normal", 72], ["eternal", 12], ["noexit", 12], ["torment", 4], ["insta", 0]]; if (t===2) return [["normal", 66], ["eternal", 4], ["noexit", 16], ["torment", 12], ["insta", 2]]; if (t===3) return [["normal", 58], ["eternal", 2], ["noexit", 18], ["torment", 18], ["insta", 4]]; if (t===4) return [["normal", 44], ["eternal", 0], ["noexit", 20], ["torment", 28], ["insta", 8]]; if (t>= 5) return [["normal", 22], ["eternal", 0], ["noexit", 18], ["torment", 36], ["insta", 24]]; return [["normal", 50], ["eternal", 6], ["noexit", 18], ["torment", 20], ["insta", 6]]; } function pickExitType(cls) { const w = exitWeights(cls), t = w.reduce((s, x) => s + x[1], 0); let r = Math.random() * t; for (const x of w) { if (r < x[1]) return x[0]; r -=x[1]; } return "normal" ; } /*=====================层级生成=====================*/ function genLevel(idLabel, depth) { const env=P(ENVIRONMENTS); const lv={ id: idLabel, depth: depth, env: env }; lv.nameCn=P([env.nameCn, env.nameCn + "(第二形态)" , env.nameCn + "·深层" , "被遗忘的" + env.nameCn, env.nameCn + "·残响" ]); lv.nameEn=env.nameEn + (C(.18) ? " " + P(["Variant", "Sector B" , "Remnant" , "Echo" , "Prime" ]) : "" ); lv.cls=wpick(CLASS_LIST); syncDerived(lv); lv.phenomena=[...new Set(pickN(PHENOMENA, R(1, 4)).concat(C(.6) ? ["- " + P(env.phe)] : []))]; lv.resources = (lv.cls.tier >= 4 && C(.5)) ? [] : pickN(RESOURCES, R(1, 5)); lv.tags = pickN(TAGS_EXTRA, R(1, 3)).concat(env.tags || []); if (lv.safety === " 宜居") lv.tags.unshift("宜居层"); if (lv.entdens==="实体横行" || lv.entdens==="大量实体" ) { if (!lv.tags.includes("实体密集")) lv.tags.push("实体密集"); } if (lv.entdens==="实体绝迹" ) lv.tags=lv.tags.filter(t=> t !== "实体密集"); lv.tags = [...new Set(lv.tags)]; lv.explore = P(EXPLORE); lv.size = env.size; lv.details = { floor: env.floor, wall: env.wall, ceiling: env.ceiling, light: env.light, sound: env.sound, smell: env.smell, temp: env.temp, structure: env.structure }; // 入口 lv.entries = []; for (let i = 0; i < R(1, 4); i++) { const from=C(.12) ? "未知(随机切入)" : ("Level " + (C(.85) ? R(0, 999) : R(1000, 1400))); lv.entries.push(" 在 " + from + " 中" + P(EXIT_METHOD) + "。" ); } // 出口(与难度联动) lv.exitType=pickExitType(lv.cls); lv.exits=[]; if (lv.exitType==="normal" ) { const n=(lv.cls.tier <=1) ? R(2, 3) : R(1, 2); for (let i=0; i < n; i++) lv.exits.push({ m: P(EXIT_METHOD), c: P(EXIT_COND), to: (C(.18) ? "随机层级" : "Level " + R(0, 999)) }); if (lv.cls.tier>= 4) lv.exitNote = "注意:以下出口均未在实战中被成功验证,逃生成功率极低。"; } else if (lv.exitType === "noexit") { lv.exitNote = "截至目前,M.E.G. 未记录到任何成功的离开案例。所有尝试离开的流浪者均已失联,推测本层级不存在出口。"; } else if (lv.exitType === "insta") { lv.insta = P(INSTA_DEATH); } else if (lv.exitType === "torment") { lv.torment = P(TORMENT_STYLE); lv.tormentNote = "本层级不存在任何出口,且任何逃离尝试都会触发层级特性将流浪者拉回。滞留者无一例外进入不可逆的精神崩溃状态。"; } else if (lv.exitType === "eternal") { lv.eternal = P(ETERNAL_GOOD); lv.eternalNote = "本层级不存在出口,但环境宜人且资源充足,部分流浪者已选择永久定居,并拒绝被救援。"; } // 团体(数量与友好度按难度联动) lv.groups = []; const rule = lv.tierRule || ruleFor(lv.cls); let gn = R(rule.gn[0], rule.gn[1]); if (gn > 0) { let pool = GROUPS; if (rule.friendly[1] >= 2) pool = GROUPS.filter(g => ["友好", "交易", "中立", "未知"].includes(g.a)); if (rule.friendly[1] === 0) pool = GROUPS.filter(g => ["敌对", "极不友好", "未知"].includes(g.a)); const gs = pickN(pool, gn); gs.forEach(g => lv.groups.push({ n: g.n, a: g.a, s: g.s, d: g.d, size: R(4, 900) + " 人" })); } else { lv.groups = [{ n: "无已知团体", a: "—", s: "—", d: "本层级尚未发现任何有组织的人类或实体团体。危险等级过高,无组织愿意在此设立据点。", size: "—" }]; } lv.desc = buildDesc(lv); // 子层级(数量随机;二级子层级为两位小数 X.YZ,不再往下延伸) lv.subs = []; if (depth < 2) { const n=(depth===0) ? R(0, 5) : (C(.45) ? R(1, 3) : 0); for (let i=1; i <=n; i++) lv.subs.push(genLevel(subId(idLabel, depth, i), depth + 1)); } // 是否被删除(随机):命中后本层级连同其全部子层级一并坠入破碎之地 lv.deleted=false; if (C(0.10)) { lv.deleted=true; lv.delReason=P(DELETE_REASON); lv.oldCls=lv.cls; lv.oldSafety=lv.safety; lv.oldStab=lv.stability; lv.oldEnt=lv.entdens; lv.cls=CLASS_DELETED; lv.safety="已删除" ; lv.stability="已崩解" ; lv.entdens="实体绝迹(结构已破碎)" ; lv.entities=[]; lv.exitType="broken" ; lv.exits=[]; lv.resources=[]; lv.groups=[{ n: "无(据点已被破碎之地吞没)" , a: "—" , s: "—" , d: "原据点居民下落不明,最后一次通讯为一串重复的坐标。" , size: "0(推定)" }]; lv.desc=buildDesc(lv); // 级联破碎:父层级坠入破碎之地后,所有后代层级同步销毁,并取消其重写状态 (function crush(parent) { parent.subs.forEach(s=> { const self = s.deleted; if (!self) { s.oldCls = s.cls; s.oldSafety = s.safety; s.oldStab = s.stability; s.oldEnt = s.entdens; } s.deleted = true; s.deletedWithParent = parent.id; s.rewritten = false; if (!self) s.delReason = "其父级层级 " + parent.id + " 已被删除,本子层级随之失去存在锚点,一并坠入破碎之地。"; s.cls = CLASS_DELETED; s.safety = "已删除"; s.stability = "已崩解"; s.entdens = "实体绝迹(结构已破碎)"; s.entities = []; s.exitType = "broken"; s.exits = []; s.resources = []; s.groups = [{ n: "无(据点已被破碎之地吞没)", a: "—", s: "—", d: "原据点居民下落不明,最后一次通讯为一串重复的坐标。", size: "0(推定)" }]; s.desc = buildDesc(s); crush(s); }); })(lv); } // 是否被重写(随机) lv.rewritten = false; if (!lv.deleted && C(0.22)) { const before = { cls: lv.cls, safety: lv.safety, stability: lv.stability, entdens: lv.entdens, phenomena: lv.phenomena.slice(), groups: JSON.parse(JSON.stringify(lv.groups)), entities: lv.entities.slice(), exitType: lv.exitType, exits: JSON.parse(JSON.stringify(lv.exits)), nameCn: lv.nameCn, nameEn: lv.nameEn, resources: lv.resources.slice(), desc: lv.desc.slice() }; const changes = []; if (C(.7)) { const o = lv.cls; let nv = wpick(CLASS_LIST); let guard = 0; while (nv.c === o.c && guard++ < 10) nv=wpick(CLASS_LIST); lv.cls=nv; changes.push(["生存难度", o.c + " · " + o.l, nv.c + " · " + nv.l]); const os=lv.safety, ost=lv.stability, oe=lv.entdens; syncDerived(lv); if (lv.safety !==os) changes.push(["安全性", os, lv.safety]); if (lv.stability !==ost) changes.push(["稳定性", ost, lv.stability]); if (lv.entdens !==oe) changes.push(["实体数量", oe, lv.entdens]); } if (C(.45)) { const o=lv.safety; const rule=ruleFor(lv.cls); const nv=P(rule.safe); if (o !==nv) { lv.safety=nv; changes.push(["安全性", o, nv]); } } if (C(.45)) { const o=lv.stability; const rule=ruleFor(lv.cls); const nv=P(rule.stab); if (o !==nv) { lv.stability=nv; changes.push(["稳定性", o, nv]); } } if (C(.45)) { const o=lv.entdens; const rule=ruleFor(lv.cls); const nv=P(rule.ent); if (o !==nv) { lv.entdens=nv; lv.entities=rollEntities(lv.cls, nv); changes.push(["实体数量", o, nv]); } } if (C(.32)) { const o=lv.nameCn; lv.nameCn=P([env.nameCn + "·修订版" , "新" + env.nameCn, env.nameCn + "(归档三号)" , "无名" + env.type]); changes.push(["层级名称", o, lv.nameCn]); } if (C(.75) && lv.phenomena.length) { const rm=lv.phenomena.splice(Math.floor(Math.random() * lv.phenomena.length), 1)[0]; let ad=P(PHENOMENA), g=0; while (lv.phenomena.includes(ad) && g++ < 20) ad=P(PHENOMENA); lv.phenomena.push(ad); changes.push(["层级特性", "移除:" + rm, "新增:" + ad]); } if (C(.55) && lv.entities.length && lv.entdens !=="实体绝迹" ) { const e=lv.entities[Math.floor(Math.random() * lv.entities.length)]; lv.entities=lv.entities.filter(x=> x !== e); // 补入一条不同的新实体,保证清单与「实体数量」字段始终自洽 const pool = lv.entities.map(x => x.cn); let cand = ENTITY_DB.filter(x => !pool.includes(x.cn) && x.cn !== e.cn); if (!cand.length) cand = ENTITY_DB.filter(x => x.cn !== e.cn); const ad = P(cand); lv.entities.push(ad); changes.push(["实体清单", "曾记录:" + e.cn + "(" + e.thr + ")", "改为记录:" + ad.cn + "(" + ad.thr + ")"]); } if (C(.6)) { if (lv.groups[0].n === "无已知团体") { const ng = P(GROUPS); lv.groups = [{ n: ng.n, a: ng.a, s: ng.s, d: ng.d, size: R(4, 900) + " 人" }]; changes.push(["团体情况", "无已知团体", "新增据点:" + ng.n + "(" + ng.a + ")"]); } else if (lv.groups.length > 1) { const g = P(lv.groups); lv.groups = lv.groups.filter(x => x !== g); changes.push(["团体情况", g.n + "(据点存在)", "据点已被撤销 / 失联"]); } else { const g = lv.groups[0], o = g.a; g.a = P(["友好", "中立", "交易", "敌对", "极不友好", "未知"]); changes.push(["团体态度", g.n + ":" + o, g.n + ":" + g.a]); } } if (C(.45)) { const o = exitLabel(lv); const nt = pickExitType(lv.cls); let g = 0; while (nt === lv.exitType && g++ < 10) {/*保持不同*/ } if (nt !==lv.exitType) { lv.exitType=nt; lv.exits=[]; if (nt==="normal" ) { lv.exits=[{ m: P(EXIT_METHOD), c: P(EXIT_COND), to: "Level " + R(0, 999) }]; } if (nt==="insta" ) lv.insta=P(INSTA_DEATH); if (nt==="noexit" ) lv.exitNote="所有出口在重写后失效,此前的离开记录被判定为伪造。" ; if (nt==="torment" ) { lv.torment=P(TORMENT_STYLE); lv.tormentNote="重写后本层级的出口被永久封死,滞留者将承受层级特性带来的持续折磨。" ; } if (nt==="eternal" ) { lv.eternal=P(ETERNAL_GOOD); lv.eternalNote="出口虽被关闭,但层级在重写后变得宜居,居民多数选择留下。" ; } changes.push(["出口状态", o, exitLabel(lv)]); } } if (C(.4)) { const o=lv.resources.length ? lv.resources.join("、") : "无可用物资" ; lv.resources=C(.5) ? pickN(RESOURCES, R(1, 4)) : []; const nv=lv.resources.length ? lv.resources.join("、") : "无可用物资" ; if (o !==nv) changes.push(["可获取物资", o, nv]); } if (changes.length===0) changes.push(["层级特性", "(无实质改动)" , "仅档案格式被重新排版" ]); lv.rewritten=true; lv.before=before; lv.changes=changes; lv.rwWho=P(REWRITE_WHO); lv.rwTime=R(1, 28) + "/" + R(1, 12) + "/20" + R(10, 26); lv.desc=buildDesc(lv); } return lv; } function exitLabel(lv) { if (lv.exitType==="normal" ) return "存在已知出口 × " + lv.exits.length; return ({ noexit: "无出口" , insta: "秒死(进入即死亡)" , torment: "永世折磨(无出口)" , eternal: "永世但不折磨(宜居牢笼)" , broken: "无出口(层级已破碎)" })[lv.exitType] || "未知" ; } function buildDesc(lv) { const e=lv.env, d=lv.details; const wallTxt=/^无/.test(d.wall) ? ("四周" + d.wall + ",上方则是" + d.ceiling) : (d.wall.includes(",") ? ("墙壁为" + d.wall + ",天花板为" + d.ceiling) : ("墙壁由" + d.wall + "构成,天花板为" + d.ceiling)); const p1=lv.id + " 表现为一处" + lv.size + "的" + e.type + "环境,中文常译为「" + lv.nameCn + "」。" + d.structure + "。地面为" + d.floor + "," + wallTxt + "。" ; const p2="该层级的光照条件为:" + d.light + "。环境中持续存在" + d.sound + ",空气中弥漫着" + d.smell + "。温度记录为" + d.temp + "。由于" + P(["空间布局始终无法与地图吻合", "关键区域的记录会在离开后失效" , "不同探险队对同一区域的描述互相矛盾" , "层级结构会随观测者数量而变化" ]) + ",测绘工作几乎无法完成,M.E.G. 将其探索状态标记为「" + lv.explore + "」。" ; const p3="【实体情况】" + (ENT_RULE[lv.entdens] ? ENT_RULE[lv.entdens].desc : "实体数据缺失。" ) + (lv.entities.length ? ("已确认存在的实体包括:" + lv.entities.map(x=> x.cn).join("、") + ",遭遇时建议保持静止并避免眼神接触。") : ""); const p4 = lv.resources.length ? ("可在此处找到的物资有:" + lv.resources.join("、") + ",部分物资会随时间自发刷新,建议建立临时据点并优先补充杏仁水。") : ("本层级几乎不存在可用物资,任何进入者都应在切入前携带至少三日的补给,否则生存概率将急剧下降。"); const p5 = lv.deleted ? ("该层级已被删除,残余结构坠入破碎之地,原档案中的一切评级均已作废。") : ("综合评级:安全性「" + lv.safety + "」——" + (SAFETY_DESC[lv.safety] || "评级缺失") + " 结构稳定性「" + lv.stability + "」——" + (STAB_DESC[lv.stability] || "数据缺失")); return [p1, p2, p3, p4, p5]; } /* ===================== 渲染 ===================== */ function barIdx(v, arr) { const i = arr.indexOf(v); return i < 0 ? arr.length - 1 : i; } function barColor(v, arr, revGood) { const i=barIdx(v, arr), r=i / (arr.length - 1); return r <=0.34 ? "g" : (r <=0.67 ? "y" : "r" ); } function renderLevel(lv, depth) { let h="" ; h +='
'; h += '
' + lv.id + '
'; h += '
' + lv.nameCn + ' ' + lv.nameEn + '
'; h += '' + lv.cls.c + ' · ' + lv.cls.l + ''; if (lv.deleted) h += '已删除 · 破碎之地'; else if (lv.rewritten) h += '档案已被重写'; else h += '档案有效'; if (lv.safety === "宜居") h += '宜居层'; h += '
'; h += '
'; lv.tags.forEach(t => { h += '' + t + '' ; }); h +='' + lv.explore + '' ; h +='子层级 ' + lv.subs.length + ' 个' ; h +='
' ; h +='
' ; h +='
' ; h +='
生存难度 SURVIVAL DIFFICULTY
' + lv.cls.c + '' + lv.cls.l + ':' + lv.cls.d + '
' ; h +='
安全性 SECURITY
' + lv.safety + '' + (SAFETY_DESC[lv.safety] || "该层级已被删除,安全性评级失效。" ) + '' + '
' ; h +='
稳定性 STABILITY
' + lv.stability + '' + (STAB_DESC[lv.stability] || "该层级已被删除,结构不复存在。" ) + '' + '
' ; h +='
实体数量 ENTITY COUNT
' + lv.entdens + '' + (ENT_RULE[lv.entdens] ? ENT_RULE[lv.entdens].desc : "—" ) + '' + '
' ; h +='
' ; h +='

■ 层级描述 / DESCRIPTION

' ; lv.desc.forEach(p=> { h += '

' + p + '

'; }); h += '

■ 内部构造 / STRUCTURE

'; h += '
环境参数' + '整体结构:' + lv.details.structure + '
地面:' + lv.details.floor + '
墙壁:' + lv.details.wall + '
天花板:' + lv.details.ceiling + '
' + '光照:' + lv.details.light + '
声音:' + lv.details.sound + '
气味:' + lv.details.smell + '
温度:' + lv.details.temp + '
'; h += '

■ 实体清单 / ENTITIES(' + lv.entdens + ')

'; h += '
' + (ENT_RULE[lv.entdens] ? ENT_RULE[lv.entdens].desc : '实体数据缺失。') + '
'; if (lv.entities.length) { h += ''; lv.entities.forEach(e => { h += '' + '' + ''; }); h += '
实体 威胁等级 行为特征
' + e.cn + '
' + e.en + '
' + e.thr + '' + e.beh + '
'; } else { h += '
— 本层级暂无已确认的实体记录 —
'; } h += '
'; h += '

■ 层级特性 / PHENOMENA

'; h += '

■ 入口 / ENTRANCES

'; h += '

■ 出口 / EXITS

'; if (lv.exitType === "normal") { h += '
◈ 存在已知出口
'; lv.exits.forEach(x => { h += '· 通过' + x.m + '(条件:' + x.c + ')可抵达 ' + x.to + '。
'; }); if (lv.exitNote) h += '
' + lv.exitNote + '
'; h += '
'; } else if (lv.exitType === "noexit") { h += '
◈ 无已知出口
' + lv.exitNote + '
任何声称离开过本层级的记录均无法验证。
'; } else if (lv.exitType === "insta") { h += '
☠ 秒死区域 · 进入即死亡
' + lv.insta + '
档案备注:请勿尝试切入本层级,M.E.G. 已将其标记为禁止进入。
'; } else if (lv.exitType === "torment") { h += '
☠ 永世折磨 · 无出口且持续痛苦
' + lv.torment + '

' + lv.tormentNote + '
'; } else if (lv.exitType === "eternal") { h += '
◈ 永世但不折磨 · 宜居牢笼
' + lv.eternal + '

' + lv.eternalNote + '
'; } else if (lv.exitType === "broken") { h += '
☠ 无出口(层级已破碎)
本层级已被删除,所有入口与出口均已失效,残余结构漂浮于破碎之地中。
'; } h += '

■ 团体与前哨 / GROUPS & OUTPOSTS

'; lv.groups.forEach(g => { const c = (g.a === "友好") ? "friendly" : (g.a === "敌对" || g.a === "极不友好") ? "hostile" : "neutral"; h += '
' + g.n + ' —— 态度:' + g.a + ' | 规模:' + g.size + '
' + '据点状态:' + g.s + ' | ' + g.d + '
'; }); if (lv.deleted) { h += '
' + (lv.deletedWithParent ? ('☠ 已被删除 · 随父级层级 ' + lv.deletedWithParent + ' 一并坠入破碎之地') : '☠ 本层级已被删除 · 坠入破碎之地') + '
' + '删除原因:' + lv.delReason + '。
删除前:生存难度 ' + lv.oldCls.c + '(' + lv.oldCls.l + ') | 安全性 ' + lv.oldSafety + ' | 稳定性 ' + lv.oldStab + ' | 实体数量 ' + lv.oldEnt + '。
' + '
破碎之地是所有被删除层级残骸的汇聚之所,进入者无法返回任何正常层级。
'; } if (lv.rewritten) { h += '
⟳ 本层级档案已被重写(REWRITTEN)
' + '
重写者:' + lv.rwWho + ' | 记录时间:' + lv.rwTime + '
' + ''; lv.changes.forEach(c => { h += ''; }); h += '
项目 重写前(原始档案) 重写后(当前档案)
' + c[0] + ' ' + c[1] + ' ' + c[2] + '
'; h += '
【重写前完整档案】生存难度 ' + lv.before.cls.c + ' · ' + lv.before.cls.l + ' | 安全性 ' + lv.before.safety + ' | 稳定性 ' + lv.before.stability + ' | 实体数量 ' + lv.before.entdens + ' | 名称「' + lv.before.nameCn + '」 | 特性:' + lv.before.phenomena.join(";") + ' | 实体:' + (lv.before.entities.length ? lv.before.entities.map(e => e.cn).join("、") : "无确认记录") + ' | 团体:' + lv.before.groups.map(g => g.n + "(" + g.a + ")").join("、") + ' | 出口:' + (lv.before.exitType === "normal" ? ("正常出口 × " + lv.before.exits.length) : ({ noexit: "无出口", insta: "秒死", torment: "永世折磨", eternal: "永世但不折磨" }[lv.before.exitType] || "未知")) + '
'; h += '
【重写后完整档案】生存难度 ' + lv.cls.c + ' · ' + lv.cls.l + ' | 安全性 ' + lv.safety + ' | 稳定性 ' + lv.stability + ' | 实体数量 ' + lv.entdens + ' | 名称「' + lv.nameCn + '」 | 特性:' + lv.phenomena.join(";") + ' | 实体:' + (lv.entities.length ? lv.entities.map(e => e.cn + "(" + e.thr + ")").join("、") : "无确认记录") + ' | 团体:' + lv.groups.map(g => g.n + "(" + g.a + ")").join("、") + ' | 出口:' + exitLabel(lv) + '
'; h += '
'; } h += '

■ 子层级 / SUB-LEVELS(' + lv.subs.length + ' 个)

'; if (lv.subs.length) { lv.subs.forEach((s, i) => { h += '
▸' + s.id + ' —— ' + s.nameCn + ' [' + s.cls.c + ']' + ' 安全性 ' + s.safety + ' | 稳定性 ' + s.stability + ' | ' + s.entdens + '' + (s.deleted ? ' [已删除' + (s.deletedWithParent ? '·随父级破碎' : '·破碎之地' ) + ']' : '' ) + (s.rewritten ? ' [已重写]' : '' ) + (s.subs.length ? ' (含 ' + s.subs.length + ' 个子层级)' : '' ) + '
' + renderLevel(s, depth + 1) + '
' ; }); } else { h +='
本层级目前未记录任何子层级。
' ; } h +='
' ; return h; } /*=====================文本导出=====================*/ function levelText(lv, ind) { const pad=" " .repeat(ind); let t="" ; t +=pad + "【" + lv.id + "】" + lv.nameCn + "(" + lv.nameEn + ")\n" ; t +=pad + "状态:" + (lv.deleted ? ("已删除 · " + (lv.deletedWithParent ? (" 随父级 " + lv.deletedWithParent + " 一并坠入破碎之地") : "破碎之地" )) : "档案有效" ) + (lv.rewritten ? " · 已被重写" : "" ) + "\n" ; t +=pad + "生存难度:" + lv.cls.c + " · " + lv.cls.l + "(" + lv.cls.d + ")\n" ; t +=pad + "安全性:" + lv.safety + "(" + (SAFETY_DESC[lv.safety] || "评级失效" ) + ")\n" ; t +=pad + "稳定性:" + lv.stability + "(" + (STAB_DESC[lv.stability] || "结构不复存在" ) + ")\n" ; t +=pad + "实体数量:" + lv.entdens + "(" + (ENT_RULE[lv.entdens] ? ENT_RULE[lv.entdens].desc : "—" ) + ")\n" ; t +=pad + "标签:" + lv.tags.join("、") + " | 探索状态:" + lv.explore + "\n\n" ; t +=pad + "■ 描述\n" ; lv.desc.forEach(p=> { t += pad + " " + p + "\n"; }); t += pad + "■ 内部构造\n"; t += pad + " 结构:" + lv.details.structure + "\n" + pad + " 地面:" + lv.details.floor + "\n" + pad + " 墙壁:" + lv.details.wall + "\n" + pad + " 天花板:" + lv.details.ceiling + "\n" + pad + " 光照:" + lv.details.light + "\n" + pad + " 声音:" + lv.details.sound + "\n" + pad + " 气味:" + lv.details.smell + "\n" + pad + " 温度:" + lv.details.temp + "\n"; t += pad + "■ 实体清单\n"; if (lv.entities.length) lv.entities.forEach(e => { t += pad + " - " + e.cn + "(" + e.en + ")|" + e.thr + "|" + e.beh + "\n"; }); else t += pad + " - 无已确认实体记录\n"; t += pad + "■ 特性\n"; lv.phenomena.forEach(p => { t += pad + " - " + p + "\n"; }); t += pad + " 物资:" + (lv.resources.length ? lv.resources.join("、") : "无") + "\n"; t += pad + "■ 入口\n"; lv.entries.forEach(e => { t += pad + " - " + e + "\n"; }); t += pad + "■ 出口:" + exitLabel(lv) + "\n"; if (lv.exitType === "normal") lv.exits.forEach(x => { t += pad + " - " + x.m + "(" + x.c + ")→ " + x.to + "\n"; }); if (lv.exitType === "noexit") t += pad + " " + lv.exitNote + "\n"; if (lv.exitType === "insta") t += pad + " " + lv.insta + "\n"; if (lv.exitType === "torment") t += pad + " " + lv.torment + "\n"; if (lv.exitType === "eternal") t += pad + " " + lv.eternal + "\n"; t += pad + "■ 团体\n"; lv.groups.forEach(g => { t += pad + " - " + g.n + "(" + g.a + "|规模 " + g.size + "|" + g.s + ")" + g.d + "\n"; }); if (lv.deleted) t += pad + "■ 删除记录:" + lv.delReason + "(删除前:" + lv.oldCls.c + " / " + lv.oldSafety + " / " + lv.oldStab + " / " + lv.oldEnt + ")\n"; if (lv.rewritten) { t += pad + "■ 重写记录(" + lv.rwWho + "," + lv.rwTime + ")\n"; lv.changes.forEach(c => { t += pad + " - " + c[0] + ":" + c[1] + " → " + c[2] + "\n"; }); } t += "\n"; if (lv.subs.length) { t += pad + "■ 子层级(" + lv.subs.length + " 个)\n"; lv.subs.forEach(s => { t += levelText(s, ind + 1); }); } return t; } function countLevels(lv) { let n = 1; lv.subs.forEach(s => { n += countLevels(s); }); return n; } /* ===================== 交互 ===================== */ let current = null, total = 0; const $ = id => document.getElementById(id); $("gen").addEventListener("click", () => { $("out").innerHTML = '
正在解析档案…
'; setTimeout(() => { const root = genRootId(); current = genLevel(root.id, 0); current.cluster = root.group; let h = '
所属:' + root.group + ' | 生成时间:' + new Date().toLocaleString("zh-CN") + ' | 本次共生成 ' + countLevels(current) + ' 个层级条目(主层级 1 个 + 子层级 ' + (countLevels(current) - 1) + ' 个)
'; h += renderLevel(current, 0); $("out").innerHTML = h; $("out").classList.remove("flash"); void $("out").offsetWidth; $("out").classList.add("flash"); total++; $("cnt").textContent = total; $("cnt2").textContent = countLevels(current); $("last").textContent = current.id; }, 240); }); $("copy").addEventListener("click", () => { if (!current) { alert("请先生成一个层级。"); return; } const txt = "【后室层级档案 · 生成器输出】\n所属:" + current.cluster + "\n生成时间:" + new Date().toLocaleString("zh-CN") + "\n\n" + levelText(current, 0); navigator.clipboard.writeText(txt).then(() => { const b = $("copy"); b.textContent = "已复制 ✓"; setTimeout(() => { b.textContent = "复制文本"; }, 1600); }).catch(() => { prompt("复制失败,请手动复制:", txt); }); }); $("save").addEventListener("click", () => { if (!current) { alert("请先生成一个层级。"); return; } const txt = "【后室层级档案 · 生成器输出】\n所属:" + current.cluster + "\n生成时间:" + new Date().toLocaleString("zh-CN") + "\n\n" + levelText(current, 0); const blob = new Blob([txt], { type: "text/plain;charset=utf-8" }); const a = document.createElement("a"); a.href = URL.createObjectURL(blob); a.download = current.id.replace(/ /g, "_") + "_后室层级档案.txt"; a.click(); URL.revokeObjectURL(a.href); }); window.addEventListener("load", () => { $("gen").click(); });