下载 App

《我真没让他们建城啊!》开发者日志 04

修改于10/1624 浏览
—— 先让每局都不一样,再让他们学会反抗 今天被玩家的话打断了三次。 第一次他说「有些不好玩」,第二次说「中段不知道往哪投」, 第三次说「我知道我想玩什么了」。 这三句话,把这一天的方向从头改到了尾。
日期: 2026-10-12 当前进度: 每局地图随机化;文明编年史 + 世界态势面板;叛神/觉醒系统上线(慈神 0 觉醒 vs 暴神引爆对抗);跨局图鉴存档;叛神全套像素视觉
写在前面:一次「不好玩」的诊断 02 和 03 我都在讲「怎么让世界更可信」——先让人看懂,再让数据说话,最后让世界可复现。那是内部的功夫。
今天第一次直面一个更硬的问题:它好玩吗?
玩家给了一句非常笼统的反馈:「有些不好玩啊。」
这种话最怕的就是拍脑袋改。所以我没有直接动手,而是先问清楚「不好玩」是哪一种。他勾了四个:每局都一样、看着无聊、看不懂在发生什么、结局没意义。
四个全中。那就不是某一个旋钮的问题,是内容与反馈的系统性缺口。于是今天做了四件事,每一件对应一个诊断:
诊断 做了什么 每局都一样 每局注入真实种子 + 地图骨架随种子变化 看不懂在发生什么 文明编年史(HUD 按 C)+ 结算页时间线 中段不知道往哪投 世界态势面板(常驻可点击定位) 结局没意义 跨局图鉴存档 + 叛神系统(有胜负了) 但真正让今天变得不一样的,是玩家最后那句话——「我知道我想玩什么了」。他说:
人天生喜欢破坏和创造。小人并不会意识到存在一个上帝,我希望给他们加一个规则,当他们的不幸值增加,有概率反抗玩家,反抗神。知识大爆炸,玩家需要对抗这些小人。因为玩家可以选择是参与创造或者参与破坏。
这句话把游戏从「看风景」推到了「有对手」。
一、每局都一样:一个被忽略了一整局的 bug 1.1 先复现,再动手 「每局都一样」这种反馈,最容易被当成「玩家玩腻了」。但它是可以验证的——我写了个探针,不设种子连开两局,打印开局世界指纹:
text
复制 RUN[A] fp0=18346247 RUN[B] fp0=18346247 ← 一模一样 指纹完全相同。 不是玩家玩腻了,是真的每局同一张地图。
1.2 两个叠加的原因 查下去发现是两个问题叠在一起,而且第二个更隐蔽。
原因一:主游戏从头到尾没调用过 math.randomseed。
只有 BalanceTests 和 _proc/ 下的测试脚本设过种子。引擎默认种子固定,所以 math.random 序列每局一样——NPC 出生分布、狼群落点、随机事件选择,全都一样。
原因二:地图骨架本身是写死的。 这一条才是关键——就算换了 math.random 种子,地形大形也不会变:
lua
复制 -- 修复前 local riverX = 36.0 for cy = 0, grid - 1 do local wx = math.floor(riverX + math.sin(cy * 0.22) * 3.0) -- 无种子 ... end -- 两片森林用不含种子的固定哈希 if W.terrain[idx] == Config.T_GRASS and Config.Hash2(cx * 3 + 1, cy * 5 + 2) < 0.62 then 河流永远在第 36 列,两片森林永远长在同一片区域,资源簇坐标固定在配置里。换种子也没用,因为地形根本不吃种子。
1.3 修复:种子要喂进骨架里 lua
复制 -- main.lua:每局取真实种子(os.time 混高精度时钟,同秒重开也不同) local function NewMapSeed() local ok, t = pcall(function() return os.time() end) ... local jitter = math.floor(os.clock() * 1000) % 100000 return math.floor(t) % 1000000 * 100000 + jitter end lua
复制 -- World.Generate:河流的基准列/摆幅/频率/倾斜/相位全部由种子派生 local riverBase = 32.0 + Config.Hash2(mapSeed, 101) * 8.0 local riverAmp = 2.0 + Config.Hash2(mapSeed, 103) * 3.0 local riverFreq = 0.16 + Config.Hash2(mapSeed, 107) * 0.12 森林的范围与疏密、资源簇的中心位置(±4 Cell 抖动)也全部接上种子。
关键取舍:测试脚本不注入种子时,回落到配置里的固定种子。 这样 03 辛苦建立的跨进程可复现性一点没丢——测试仍然逐字节一致,只有真实游玩每局不同。
1.4 验证:结局差异才是重玩动力 12 个种子 × 300 秒,0 失败,而且结局差异很大:
text
复制 OK seed=111111 pop=49 roads=70 era=3 disc=8 OK seed=222222 pop=70 roads=107 era=1 disc=7 OK seed=333333 pop=65 roads=98 era=4 disc=10 OK seed=777777 pop=59 roads=92 era=4 disc=10 ... SUMMARY ok=12 fail=0 纪元 1~4、现象 4~10、人口 49~70。同一套规则,每局跑出不同的历史——这正是重玩动力该有的样子。
二、看不懂 & 不知道往哪投:两块面板 2.1 编年史:数据一直在记,界面完全没用 「看不懂在发生什么」这条,查下去发现一个很荒诞的事实:数据全都在记,界面上一条都没用。
W.deathLog、W.migrationLog、W.eventLog、W.firstTimings——死亡、迁徙、事件、纪元晋级,全都在后台累积。但 Render.lua 只在结算页显示几个聚合数字:交易 78 次、死亡 52 人。过程一条都看不到。
所以写了 Systems.BuildChronicle(),把这些聚成一条按时间排序的叙事线。但直接铺开会刷屏——实测 600 秒有 64 条死亡记录,其中绝大多数是老死。于是做了两个降噪:
老死(old)不进编年史:太频繁,会淹没叙事 同因死亡按 20 秒窗口聚合:否则一次狼群入侵刷出十几条「有人死于狼口」 效果:54 条 → 29 条,一条完整的故事线:
text
复制 67.1s 路 「第一条道路」出现了 131.1s 墓 「墓地」出现了 289.1s 瘴 瘴气:低洼密集处毒雾弥漫 299.1s 村 「村落」出现了 307.9s 迁 有 11 人结伴迁徙 327.2s ☠ 有 4 人死于狼口 344.1s 🌾 他们走进了农耕时代 358.9s 迁 难民成群离开了家园 2.2 态势面板:设计文档要求了,但从来没做 「中段不知道往哪投」这条,查设计文档时发现一行:
§12 世界事件状态:右上角只显示当前最重要的一件事。例如 🐺 狼群正在接近北部。点击展开。
这个一直没实现。 玩家只有转瞬即逝的横幅和 toast——中段一旦平静下来,屏幕上就没有任何持续的、可行动的信号。
于是做了「世界态势」面板:常驻显示现在最该关注的几件事,每条都能点击,镜头直接跳到事发地。
text
复制 🌍 世界态势 · 点击可定位 🐺 狼群在活动 —— 投食物分散,或投狼群互斗 ← 点击跳转 💀 近期有 25 人死亡 —— 这里出了大事 ← 点击跳转 平静期则给一条可行动的引导(按进度递进):
还没交易过 → 「把食物投在两聚落之间,看他们走出商路」 聚落不足 2 个 → 「投食物引他们去远处,再养出一个聚落」 还没战争 → 「把两个部落拉近些,迟早会打起来」 2.3 顺手修的一个老 bug 做面板时发现:Camera.RegisterUI(id, x, y, w, h, nil) 传 nil 回调等于没注册。所以选中工具后点面板,会穿透到世界、误放工具——图鉴和编年史面板都有这毛病。加了个空回调统一修掉。
三、叛神:让他们学会反抗 这是今天最重的一块。
3.1 设计:苦难是觉醒的唯一条件 玩家的原话是「不幸值增加,有概率反抗」。所以核心是一本苦难账,每聚落独立记。
但设计过程中撞到一个很关键的问题,我把它单独拎出来讲,因为它差点让整个系统不成立:
最初我要求「至少农耕时代才能觉醒」。 听起来合理——得先有余力想「为什么」吧。
实测结果:暴神打崩了经济 → 时代停滞 → 觉醒永远不发生 → 只剩灭族。
text
复制 [暴神] seed=111111 天罚=6 pop=0 觉醒=0 结束=extinction [暴神] seed=555555 天罚=7 pop=0 觉醒=0 结束=extinction 镇压到灭族,反抗根本没机会成型。这和设计意图正好相反。
所以改掉了:AwakenEraMin = 1。苦难本身就是觉醒的唯一条件,不需要文明先富起来。改完之后,对抗链条立刻活了。
3.2 两个量:创伤只涨不消,怨气会消退 第二个坑更隐蔽。最初我用一个值 value 同时干两件事,结果发现永远点不醒:
text
复制 t=155 炮1 不幸=55 t=215 炮2 不幸=1 ← 60 秒后掉回 1 怨气以 0.35/秒消退,两次天罚间隔就退干净了。于是拆成两个量:
grief(创伤):只涨不消。觉醒看它——创伤不会被时间抹掉。 value(怨气):会消退。回心转意看它——持续的善可以让怨气平息。 这个拆分是整个系统的地基。
3.3 核心张力:慈神 vs 暴神 修完之后,两条路线的差异非常清楚(同种子 600 秒):
玩法 觉醒 叛神者 通天塔 慈神(投食物) 0 0 0 暴神(降天罚) 8 18 70% 当慈神完全不会引发反抗;当暴神则引爆完整对抗链。 玩家的选择第一次真正有了代价。
而且「善」是有回报的:每次恩赐会累积信仰,抬高该聚落的觉醒门槛——不是抹掉创伤,而是让他们更愿意相信神是善的。
3.4 反抗长什么样 叛神者(Agent 的 rebel 状态)去拆神的造物——篝火、图腾、钟、宝藏。不碰他们自己建的房子,这个边界很重要:他们恨的是神,不是自己的生活。
而如果长期无人压制,觉醒聚落会开始造通天塔。塔建到顶——
「神权崩塌:他们造了一座塔,爬上去,看见了你。」
这就是这一局的失败条件。
3.5 一个必须加的细节:叛神者抗天罚 最初天罚能直接劈死叛神者。结果是一轮镇压就灭族,对抗无从谈起。
所以让叛神者对天罚有抗性——他们已经不信神了,落雷吓不住他们,只重伤不死。镇压要变成「对抗」,而不是「单方面屠杀」。
四、图鉴存档:为什么要玩第二局 这块是玩家点名要先修的,理由他说得很清楚:「影响的是为什么要玩第二局这个根本问题。」
查文档,Day 17-18 明确写着:
加入:文明现象图鉴。至少 15 个。这是玩家玩第二局的重要动力。
但代码里零持久化——全项目没有任何存档调用。关掉游戏,31 种现象全部清零,第二局打开还是满屏 ???。驱动被剪断了。
修复的核心是一个设计决策:把「本局的发现」和「这辈子的发现」彻底分开。
Systems.discovered —— 本局发现了什么,每局清空 Collection.unlocked —— 这辈子见过什么,永久保存 混用会导致第二局的「首次发现」被误判成重复。分开之后,才能区分出「★ 首次收录」和「本局又见」。
验证必须跨进程——同进程内读写会假阳性:
text
复制 第一次运行:PHASE5 文件内容: {"runs":1,"total":3,"unlocked":["road","village","war"],...} 第二次运行:PHASE1 loaded=true count=3 runs=1 ← 真的读回来了 PHASE2 首次收录 road=false ← 已收录的正确识别为重复 端到端再验一次:一局发现 14 种,其中 12 种首次收录(road/village/war 已在库里,正确排除),累计 3+12=15。同种子重跑,首次收录 = 0。
五、叛神的视觉:从「看不见」到「一眼认出」 系统做完之后,玩家指出一个很准的问题:「这是你最新、最独特的系统,却最看不见。」
确实——只有 HUD 上一个数字和态势面板的文字,地图上完全没表现。按项目的美术规范(烘焙像素精灵,不用矢量),补了 6 张:
通天塔 4 级(22×26 → 26×40 → 30×56 → 34×74)
关键设计:画布尺寸逐级变大,所以塔是真的「长高」,不是同一张图缩放。锥形塔身,塔顶那只眼睛 2 级起睁开——那是他们想爬上去看见的东西。>75% 时整塔泛红光 + 加速脉动,这是明确的失败警告。
叛神者(站立 + 移动两帧)
红头带 + 举拳 + 破袍下摆 + 怒目斜线。红头带是唯一识别特征,我特意合成了一张模拟场景图确认它在人群里一眼可辨。
配套的还有:觉醒聚落头顶红金光环(「他们看见了你」)、被拆造物的左右摇晃 + 耐久条(绿→黄→红,让玩家判断还能撑几下)。
5.1 一个差点污染确定性的坑 Apostasy.AttackStructure 最初写的是:
struct.shakeT = 0.25 -- 倒计时 如果渲染侧每帧 -dt 来衰减它,就改了世界状态——这会破坏 03 辛苦建立的跨进程可复现性。改成绝对时间戳:
struct.shakeUntil = W.time + 0.25 -- 渲染只读 03 那条原则今天再次生效:模拟是权威的,表现只能看,不能碰。
六、今天踩到的坑
  1. 「觉醒要有时代门槛」——一个听起来合理、实际致命的直觉。 它会让「镇压」直接通向「灭族」,反抗永远来不及发生。设计直觉必须用数据验,不能靠推演。
  2. 一个值干两件事,会互相抵消。 怨气既要驱动觉醒、又要能消退,结果就是永远点不醒。拆成「只涨不消的创伤」和「会消退的怨气」之后,系统才成立。
  3. 觉醒会疯狂抖动。 门槛太接近时,实测 155 秒内觉醒 9 次、回心转意 8 次,非常出戏。加了回心转意的滞后(门槛降到 0.25 倍 + 需连续保持 25 秒)才稳住。
  4. 按 tribeId 选叛神者,一个人都选不出来。 归属要驻留 60 秒才生效,早期居民 tribeId 全是 0。改成按到聚落中心的距离选。
  5. Lua 的 local function 不提升。 DrawBabels 放在文件后面,但被更早的 DrawWorld 调用,LSP 直接报 undefined-global。顺序必须正确。
  6. 烘焙器里不能引用 W。 叛神者带尾本来想用 W.animT 做飘动,但烘焙脚本没有 W,会 nil 崩。带尾改成静态,飘动交给渲染侧。
七、当前状态 项 数值 代码 14 个玩法模块,8724 行 Lua(含测试工具共 8906 行) 神之手工具 12 个(资源 / 危险 / 诱因 / 天罚) 文明现象图鉴 34 条(今天新增 3 条叛神线) 像素精灵 33 张(今天新增 6 张) 音效注册 51 条 八、下一步 [ ] 叛神音效:觉醒/建塔/拆造物目前是静默的(或复用别的音),AudioManager 里 0 条叛神音效 [ ] 通天塔警告期:>75% 已有红光,可再加全场闪烁 + 音效 [ ] 小地图:64×64 地图 + 相机缩放,玩家仍不知道全局格局 [ ] 教学覆盖新系统:引导只教了「投食物」和「看道路」,叛神/天罚/态势面板/编年史都没教 [ ] 发布素材:project.json 里 icon/screenshots/promotional_image 全为空,且标题被截断成「我真没让他们建」(少了「城啊!」) [ ] 战争率:把冲突判定限定在不同部落之间 [ ] 收纪元阈值:蒸汽时代比预期更易达到 写在最后 03 我写的是:一个自己会进化的世界,前提是一个能被你反复重放的世界。
今天补上了它的下一句:
一个能被反复重放的世界,还得有值得你重放的理由。
如果每局都是同一张地图、同一个结局、同一批「???」,那么「可复现」就只是一项技术成就,而不是一个好玩的游戏。
所以今天最有价值的产出,不是任何一行代码,而是那张表:
玩法 觉醒 叛神者 通天塔 慈神 0 0 0 暴神 8 18 70% 同一套规则,玩家做了不同的选择,世界给出了完全不同的回应。
这才是我一开始想做的东西——不是「一个会自己运转的模拟」,而是**「一个会因为你的存在而改变的模拟」**。
他们一直不知道你的存在。今天,他们抬头了。#聚光灯gamejam开发者日志
00:10
群迹·上取其下,下取其上截图
群迹·上取其下,下取其上
#聚光灯gamejam开发者日志 向大家汇报一下今日进度,目前在和蚁群的默认移动算法进行斗智斗勇。或许是我的AI对蚂蚁有别样的理解,其实最初写出的方案更接近于围绕着恒星公转的行星。 哦我还以为文章里可以插入多支视频视频,想要展示一些其它的运动方式,可惜了。那么就简单在上方传一个比较典型的,有点类似于蟑螂的运行方式。 目前仍在解决蚁群的随机运动,和玩家可操纵性之间的平衡问题。以及如各位所见,目前的
3 赞
1 回复
00:39
【开发日志3】主场景与玩法无缝化衔接截图
【开发日志3】主场景与玩法无缝化衔接
大家好我是鸭。这里是墨江里的一群鸭,嘎嘎嘎~ 今天主要时间用来搭建主场景了,感觉有点浪费时间啊……理论上来说要进入到搜打撤玩法的unity场景搭建了。 不想打字了,大家看看画面表现效果吧~ #TapTap聚光灯独立游戏
11 赞
1 回复
00:34
《荒原复苏指南》开发日志④:关卡演示堂堂袭来!!截图
《荒原复苏指南》开发日志④:关卡演示堂堂袭来!!
- 人类曾因掌握元素合成技术而一度辉煌,又因滥用元素能量而逐渐从内里衰败。 - 30世纪80年代。社会文化充斥着激进乐观主义与庞大机械美学,在这里,污染和能源共生,幸福与痛苦并存。官方广播和宣传画里依旧在宣扬“科学将战胜一切”、“元素能量将再造新农田”的口号,而世界主城却已经因为污染过度而濒临崩溃、空间挤压严重。为了寻找新的生存空间与无污染能源,官方启动了“重构拓荒计划”。 - 玩家将作为前线拓展
14 赞
5 回复
00:30
《失心》游戏开发者日志01|游戏UI迭代及实机演示截图
《失心》游戏开发者日志01|游戏UI迭代及实机演示
进入《失心》之前,玩家首先看到的是我们工作室 UNLOOK 的标识。我们将原来的标识转成 SVG,并让其中的红色瞳点转动、观察,再逐步显露完整字形,希望这个短暂的开场能带出一点好奇和不安。 这次《失心》的开局 UI,我们围绕小灵通(因为游戏的主要交互道具就是小灵通)做了几轮调整,希望玩家从打开游戏开始,就能感受到故事里的年代和气氛(故事年代背景为2000s)。 早期版本先确定了一个方向:把菜单放进
13 赞
10 回复
《气味之城》开发日志#1|为什么"涌现"和猫是天作之合截图
《气味之城》开发日志#1|为什么"涌现"和猫是天作之合
大家好,我是一个人报名了 2026 聚光灯 21 天游戏创作挑战 的独立开发者。今年主题公布那一刻我就笑出了声——涌现。因为我已经想做这个游戏很久了: 《气味之城》:你不是猫神,你只是一只猫。 先说一个所有养猫人都懂的事实:你永远无法"教会"一只猫任何它自己不想学会的事。但你家猫可能自己学会了——听见冰箱开门就瞬移到厨房;你心情不好时过来踩奶;凌晨三点准时在你身上练马拉松。没人教过它,这些行为是它
3 赞
4 回复
00:07
雨天決行 开发者日志02-人工智能的自我修养截图
雨天決行 开发者日志02-人工智能的自我修养
又和大家见面啦!第二篇日志,说实话一开始不知道该怎么编排,但团队里惊喜的成果越来越多,我们已经迫不及待把更新的内容端上来给大家啦!那么事不宜迟,快来看看都有什么新情报吧ദ്ദി˶ー̀֊ー́ )✧ 一.美术(重磅升级) 以主美小为的生命力作为燃料(bushi)本次美术组取得了大进程!首先是各个ui界面的优化和细化,上次大家看到时还只是初具雏形的草稿,现在大多都完整起来了哦! 同时,随着配色的补全,手
42 赞
36 回复
聚光灯 GameJam 开发日志 02|“涌现”有了,但不好玩截图
聚光灯 GameJam 开发日志 02|“涌现”有了,但不好玩
#聚光灯gamejam开发者日志 一个被我们亲手放弃的原型 上一篇日志还在讨论“涌现”到底应该怎么做。 这几天,我们没有急着把先前的一个创意一路堆下去,而是先做了一个可以真正运行、真正试玩的原型。 然后—— 它被放弃了。 听起来进度好像倒退了,但现在回头看,这几天可能反而是整个项目里非常重要的一段。 因为我们第一次比较明确地知道了: “概念上符合涌现”和“真的好玩”,完全是两回事。 游戏原型:一
2 赞
[2026聚光灯开发日志]Day19 收尾&游戏简单介绍截图
[2026聚光灯开发日志]Day19 收尾&游戏简单介绍
deadline之前的工作效率是最高的(雾) 本来想草率的画一些东西来着,可惜我画的太烂,于是干脆改成极简风格直接大部分用默认贴图了(悲) 游戏整体上是 探索-法术编程-杀敌获取资源-资源解锁词条和提升数值-探索 的循环 1.法术编程部分 语句分为三种:正常施法,修饰性词条,循环语句,一个法杖有十个语句槽。 1.0 元素 不同元素会附着在实体(玩家与敌方)身上,根据附着量不同有不同的效果,多种元素
蜡忆余彩:开发日志【01】一张“灵魂涂鸦”是怎么被美术救活的?截图
蜡忆余彩:开发日志【01】一张“灵魂涂鸦”是怎么被美术救活的?
最开始,我们只是想做一张“小孩子画的画”。结果我给美术发过去的第一版,大概长这样【p1】 【p1】 嗯。太阳,大树,三个火柴人,还有一张不知道为什么像烧烤架一样的桌子。 从绘画水平上来说,确实非常符合“儿童画”这个要求哈哈哈哈哈哈。 但这张看起来非常随便的草图,其实后来变成了我们整个游戏里最重要的一件道具。 这张看起来最简单的画,后来反而成了我们整个游戏里最不能随便画的一张图。 因为它不只是场
31 赞
16 回复
00:30
《涌》第一次30秒实机演示截图
《涌》第一次30秒实机演示
整段都是游戏实机录的,没有单独做动画,中间夹着几段打精英怪和 Boss 的镜头,封面就是片子最后那一帧——血写的「涌」。 声音分两层:打斗声全是游戏里的真实音效,背景音乐是后面加的。 30 秒不长,希望大家喜欢。还有更多内容后面做好了也会录视频! #聚光灯gamejam开发者日志
4 赞
6 回复