This commit is contained in:
kawagiri 2026-05-21 02:00:00 +08:00
parent b8fe4f43d2
commit 26260d2565
47 changed files with 11817 additions and 2514 deletions

View File

@ -1,5 +1,5 @@
{
"nextId": 184,
"nextId": 216,
"bugs": [
{
"id": 2,
@ -1810,6 +1810,326 @@
"module": "",
"createdAt": 1779010659607,
"updatedAt": 1779011755203
},
{
"id": 184,
"title": "房主让人接管->退出的",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779041151039,
"updatedAt": 1779041151039
},
{
"id": 185,
"title": "间谍能冲军营",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779110366469,
"updatedAt": 1779110366469
},
{
"id": 186,
"title": "溅射死的不算粗身?",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779112000854,
"updatedAt": 1779112000854
},
{
"id": 187,
"title": "刚破盟 直接进城了",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779112538669,
"updatedAt": 1779112538669
},
{
"id": 188,
"title": "咲夜保护 吞逃脱",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779115660854,
"updatedAt": 1779115660854
},
{
"id": 189,
"title": "咲夜传送后, 同一个英雄反复可以再动",
"description": "",
"status": "fixed",
"priority": "medium",
"module": "",
"createdAt": 1779120570907,
"updatedAt": 1779261918116
},
{
"id": 190,
"title": "小兵icon mipmap模式不一致",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779170032992,
"updatedAt": 1779170032992
},
{
"id": 191,
"title": "不算bug开一把教程这边设置会重置成2人EASY",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779171379190,
"updatedAt": 1779171379190
},
{
"id": 192,
"title": "没走水科技恋恋能直接生成在水上",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779171627240,
"updatedAt": 1779171627240
},
{
"id": 193,
"title": "阿空不会被反击是不是也可以加到说明里()",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779172231412,
"updatedAt": 1779172231412
},
{
"id": 194,
"title": "恋恋复活随机位置固定",
"description": "",
"status": "fixed",
"priority": "medium",
"module": "",
"createdAt": 1779176372668,
"updatedAt": 1779261464103
},
{
"id": 195,
"title": "早苗限行后无法攻击",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779192513928,
"updatedAt": 1779192513928
},
{
"id": 196,
"title": "炮兵于炮兵一样是什么东西啊",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779197239026,
"updatedAt": 1779197239026
},
{
"id": 197,
"title": "隐身单位导致好感度降低",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779205471534,
"updatedAt": 1779205471534
},
{
"id": 198,
"title": "新手教程在战绩里",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779205637960,
"updatedAt": 1779205637960
},
{
"id": 199,
"title": "steam商店图片不对还是旧的",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779213125499,
"updatedAt": 1779213125499
},
{
"id": 200,
"title": "探索者判断山会过不去",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779253618811,
"updatedAt": 1779253618811
},
{
"id": 201,
"title": "对于恐惧机制有点小建议, 目前恐惧是直接扣除生命值,导致永远亭的满月机制会被无视,巨人更是会直接秒杀。 并且禁止治疗效果是无视数值完全抵消一次治疗,这样就算永琳有一万层过量治疗,也会无法治疗并且失去所有过量治疗层数。 这样过度的克制带来的游戏体验是很差的我觉得各势力的特性需要可以各展所长至少不要被过于廉价的手段ban掉才能给玩家合理的游戏体验。",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779256771144,
"updatedAt": 1779256771144
},
{
"id": 202,
"title": "不过说到这个you得提个细节能不能建设的时候点击地皮而非部队始终显示城池边框建设分不清这一格是哪个城市的情况太多了每次去看震真的很不优雅更何况这玩意还有bug如果你点击兵下面的地城市是不会震一下的",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779258204466,
"updatedAt": 1779258204466
},
{
"id": 203,
"title": "既然如此再提一个细节,建议城市升级时可以点击顶上的升级标志来让视角回到这座城让玩家看清升级的哪座城市。很多道路连接的城市升级常常找不到城在哪里()",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779258680823,
"updatedAt": 1779258680823
},
{
"id": 204,
"title": "满血也可以休息",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779278567139,
"updatedAt": 1779278567139
},
{
"id": 205,
"title": "经典模式第几名算胜利?",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779280956049,
"updatedAt": 1779280956049
},
{
"id": 206,
"title": "城市挡住格子",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779281151488,
"updatedAt": 1779281151488
},
{
"id": 207,
"title": "征服30回合结束了",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779283551700,
"updatedAt": 1779283551700
},
{
"id": 208,
"title": "炮兵城防功能描述 骑兵没有说有城防",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779284046485,
"updatedAt": 1779284046485
},
{
"id": 209,
"title": "文文行动 英雄界面 还是白底",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779289341159,
"updatedAt": 1779289341159
},
{
"id": 210,
"title": "顺带发现的两个独立隐患(不一定跟当前 bug 相关,记录一下) 1. MapData.cs:255 引用赋值PlayerSettlements = other.PlayerSettlements。这是浅引用运行时如果有代码改 MapConfig.PlayerSettlements会污染 MatchConfigManager.LevelData 内存里的原始配置,下次开局还会用到被污染的数据。 2. DominationMatchSettlement 语义模糊:注释\"任意玩家结算且为胜,游戏结束\"和你期望的\"杀光只剩1人\"不一致。同一份 PlayerSettlements 注给所有玩家(含 AI意味着只要某个 AI 自己达成胜利条件,也会触发整局结束。",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779289761137,
"updatedAt": 1779289761137
},
{
"id": 211,
"title": "树林额外掉移动力 说明",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779292218558,
"updatedAt": 1779292218558
},
{
"id": 212,
"title": "聯機房主出生點疑似更容易靠近地圖中間加上必定先手導致1v1優勢有點大感覺需要再調整。",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779293636362,
"updatedAt": 1779293636362
},
{
"id": 213,
"title": "百科公式各阵营的资源生成系数",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779293836237,
"updatedAt": 1779293836237
},
{
"id": 214,
"title": "背盟不会自动结束",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779297052266,
"updatedAt": 1779297052266
},
{
"id": 215,
"title": "6.修复了我方首都被地方占领时仍能在回合结束后产生外交金币的bug???",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"createdAt": 1779298656244,
"updatedAt": 1779298656244
}
]
}

View File

@ -0,0 +1,126 @@
language,Description,Title
schinese,"5/18[版本V0.7.1k]更新说明
[版本V0.7.1k]
发布日期 26.5.18
------- [bug修复] -------
1.修复了投降后可以继续存档的bug
2.修复了击杀藤原妹红时若同时发生连环恐惧伤害可能错误产生两个妹红火焰的bug
3.修复了击杀小恶魔祭司时,若同时发生连环恐惧伤害,可能错误产生两个小恶魔祭司(狮神形态)的bug
4.修复了古明地帝国奇观建筑说明文字丢失的bug
5.修复了被巨人单位挤出城市的间谍单位移动后无法隐身的bug
6.修复了星熊勇仪在攻击时因推人错误进入敌方港口的bug
------- [优化] -------
1.优化了多处UI文字超框(多语言环境下)的问题
2.现在游戏默认设置为轮播BGM可以在设置界面中关闭BGM轮播
3.在游戏内查看其他界面时拖动滚轮,将不再导致大地图一同缩放
4.优化了游戏中背景图片覆盖不全问题
5.增加了解锁第二/三个英雄的快捷点击按钮
6.优化了部分技能/科技的描述文字
7.优化了继续游戏/重玩本回合loading界面图片与所选阵营不匹配的问题
------- [新增内容] -------
1.新增蓬莱山帝国历史时刻插图
我们仍在持续修复其他bug以及各种翻译问题并一直关注各个渠道中大家的反馈。你的反馈、耐心与支持是我们最大的动力谢谢你们",5/18[版本V0.7.1k]更新说明
tchinese,"5/18[版本V0.7.1k]更新說明
[版本V0.7.1k]
發佈日期 26.5.18
------- [bug修復] -------
1.修復了投降後可以繼續存檔的bug
2.修復了擊殺藤原妹紅時若同時發生連環恐懼傷害可能錯誤產生兩個妹紅火焰的bug
3.修復了擊殺小惡魔祭司時,若同時發生連環恐懼傷害,可能錯誤產生兩個小惡魔祭司(獅神形態)的bug
4.修復了古明地帝國奇觀建築說明文字遺失的bug
5.修復了被巨人單位擠出城市的間諜單位移動後無法隱身的bug
6.修復了星熊勇儀在攻擊時因推人錯誤進入敵方港口的bug
------- [優化] -------
1.優化了多處UI文字超框(多語言環境下)的問題
2.現在遊戲預設設置為輪播BGM可以在設置介面中關閉BGM輪播
3.在遊戲內查看其他介面時拖動滾輪,將不再導致大地圖一同縮放
4.優化了遊戲中背景圖片覆蓋不全的問題
5.增加了解鎖第二/三個英雄的快捷點擊按鈕
6.優化了部分技能/科技的描述文字
7.優化了繼續遊戲/重玩本回合loading介面圖片與所選陣營不匹配的問題
------- [新增內容] -------
1.新增蓬萊山帝國歷史時刻插圖
我們仍在持續修復其他bug以及各種翻譯問題並一直關注各個渠道中大家的回饋。你的回饋、耐心與支持是我們最大的動力謝謝你們",5/18[版本V0.7.1k]更新說明
english,"5/18 [Version V0.7.1k] Patch Notes
[Version V0.7.1k]
Release Date: 2026.5.18
------- [Bug Fixes] -------
1. Fixed a bug where saving was still possible after surrendering.
2. Fixed a bug where killing Fujiwara no Mokou could erroneously spawn two Mokou Flames if a chain fear damage occurred at the same moment.
3. Fixed a bug where killing the Koakuma Priest could erroneously spawn two Koakuma Priests (Lion God Form) if a chain fear damage occurred at the same moment.
4. Fixed a bug where the Komeiji Empire wonder building's description text was missing.
5. Fixed a bug where a Spy unit pushed out of a city by a Giant unit could not return to stealth after moving.
6. Fixed a bug where Yuugi Hoshiguma could mistakenly enter an enemy harbor due to a push during her attack.
------- [Improvements] -------
1. Fixed UI text overflow in several places (in multi-language environments).
2. The game now defaults to BGM shuffle; this can be turned off in the Settings menu.
3. Scrolling the mouse wheel while viewing other panels in-game no longer zooms the world map.
4. Fixed an issue where in-game background images did not fully cover the screen.
5. Added shortcut buttons to unlock the second and third Heroes.
6. Polished the description text for some Skills and Techs.
7. Fixed a mismatch between the loading screen image and the selected faction when using Continue Game / Replay Turn.
------- [New Content] -------
1. Added 4 Houraisan Empire historic moment illustrations.
We're still working hard on fixing more bugs and translation issues, and we keep a close eye on everyone's feedback across all our channels. Your feedback, patience, and support are the greatest motivation for us!! Thank you so much, everyone!",5/18 [Version V0.7.1k] Patch Notes
japanese,"5/18【バージョンV0.7.1k】アップデート内容
[バージョン V0.7.1k]
リリース日 2026.5.18
------- [バグ修正] -------
1. 降伏後もセーブを継続できてしまうバグを修正
2. 藤原妹紅を撃破した際、同時に連鎖恐怖ダメージが発生すると妹紅の炎が誤って2つ生成されることがあるバグを修正
3. 小悪魔神官を撃破した際、同時に連鎖恐怖ダメージが発生すると小悪魔神官(獅神形態)が誤って2体生成されることがあるバグを修正
4. 古明地帝国の奇跡建築の説明文が欠落するバグを修正
5. 巨人ユニットに都市から押し出されたスパイユニットが、移動後にステルス状態に戻れないバグを修正
6. 星熊勇儀が攻撃時の押し出しにより誤って敵港湾に侵入してしまうバグを修正
------- [最適化] -------
1. 多言語環境下で複数箇所のUIテキストがはみ出す問題を最適化
2. 現在、ゲームの初期設定はBGMの順送り再生となっており、設定画面でオフにできるようになりました
3. ゲーム内で他の画面を表示中にホイールをスクロールしても、メインマップが同時にズームされなくなりました
4. ゲーム内の背景画像が全体を覆いきれない問題を最適化
5. 2人目3人目の英雄を解放するショートカットボタンを追加
6. 一部のスキル/テクノロジーの説明文を最適化
7. ゲームを続ける/このターンをやり直す際のローディング画面の画像と選択した陣営が一致しない問題を最適化
------- [新規追加] -------
1. 蓬莱山帝国の歴史時刻の挿絵を4枚追加
他のバグや各種翻訳の問題も引き続き修正を進めており、各チャンネルで寄せられる皆さまのご意見にも常に目を通しています。皆さまのフィードバック、ご辛抱、そしてご支援こそが私たちの最大の原動力です!!本当にありがとうございます!",5/18【バージョンV0.7.1k】アップデート内容
korean,"5/18 [버전 V0.7.1k] 업데이트 노트
[버전 V0.7.1k]
출시일 2026.5.18
------- [버그 수정] -------
1. 항복 후에도 세이브를 이어갈 수 있는 버그 수정
2. 후지와라노 모코우 처치 시 동시에 연쇄 공포 피해가 발생하면 모코우의 불꽃이 잘못 2개 생성되는 버그 수정
3. 소악마 사제 처치 시 동시에 연쇄 공포 피해가 발생하면 소악마 사제(사자신 형태)가 잘못 2개 생성되는 버그 수정
4. 코메이지 제국 불가사의 건물의 설명 문구가 누락되는 버그 수정
5. 거인 유닛에 의해 도시 밖으로 밀려난 스파이 유닛이 이동 후 다시 은신할 수 없는 버그 수정
6. 호시구마 유우기가 공격 시 밀어내기로 인해 잘못 적 항구로 들어가는 버그 수정
------- [최적화] -------
1. 다국어 환경에서 여러 곳의 UI 텍스트가 프레임을 벗어나는 문제 최적화
2. 현재 게임 기본 설정이 BGM 순차 재생이며, 설정 화면에서 BGM 순차 재생을 해제할 수 있습니다
3. 게임 내에서 다른 화면을 보는 중 휠을 스크롤해도 메인 맵이 함께 확대/축소되지 않습니다
4. 게임 내 배경 이미지가 전체를 덮지 못하는 문제 최적화
5. 두 번째/세 번째 영웅을 해금하는 단축 버튼 추가
6. 일부 스킬/과학기술의 설명 문구 최적화
7. 게임 이어하기/이번 턴 다시하기의 로딩 화면 이미지가 선택한 진영과 일치하지 않는 문제 최적화
------- [새로운 콘텐츠] -------
1. 호라이산 제국 역사적 순간 삽화 4장 추가
다른 버그와 다양한 번역 문제도 계속해서 수정하고 있으며, 여러 채널에서 보내주시는 여러분의 피드백을 늘 살펴보고 있습니다. 여러분의 피드백과 인내, 그리고 응원이 저희의 가장 큰 원동력입니다!! 정말 감사합니다!",5/18 [버전 V0.7.1k] 업데이트 노트
1 language Description Title
2 schinese 5/18[版本V0.7.1k]更新说明 [版本V0.7.1k] 发布日期 26.5.18 ------- [bug修复] ------- 1.修复了投降后可以继续存档的bug 2.修复了击杀藤原妹红时,若同时发生连环恐惧伤害,可能错误产生两个妹红火焰的bug 3.修复了击杀小恶魔祭司时,若同时发生连环恐惧伤害,可能错误产生两个小恶魔祭司(狮神形态)的bug 4.修复了古明地帝国奇观建筑说明文字丢失的bug 5.修复了被巨人单位挤出城市的间谍单位移动后无法隐身的bug 6.修复了星熊勇仪在攻击时因推人错误进入敌方港口的bug ------- [优化] ------- 1.优化了多处UI文字超框(多语言环境下)的问题 2.现在游戏默认设置为轮播BGM,可以在设置界面中关闭BGM轮播 3.在游戏内查看其他界面时拖动滚轮,将不再导致大地图一同缩放 4.优化了游戏中背景图片覆盖不全问题 5.增加了解锁第二/三个英雄的快捷点击按钮 6.优化了部分技能/科技的描述文字 7.优化了继续游戏/重玩本回合loading界面图片与所选阵营不匹配的问题 ------- [新增内容] ------- 1.新增蓬莱山帝国历史时刻插图 我们仍在持续修复其他bug以及各种翻译问题,并一直关注各个渠道中大家的反馈。你的反馈、耐心与支持是我们最大的动力!!谢谢你们! 5/18[版本V0.7.1k]更新说明
3 tchinese 5/18[版本V0.7.1k]更新說明 [版本V0.7.1k] 發佈日期 26.5.18 ------- [bug修復] ------- 1.修復了投降後可以繼續存檔的bug 2.修復了擊殺藤原妹紅時,若同時發生連環恐懼傷害,可能錯誤產生兩個妹紅火焰的bug 3.修復了擊殺小惡魔祭司時,若同時發生連環恐懼傷害,可能錯誤產生兩個小惡魔祭司(獅神形態)的bug 4.修復了古明地帝國奇觀建築說明文字遺失的bug 5.修復了被巨人單位擠出城市的間諜單位移動後無法隱身的bug 6.修復了星熊勇儀在攻擊時因推人錯誤進入敵方港口的bug ------- [優化] ------- 1.優化了多處UI文字超框(多語言環境下)的問題 2.現在遊戲預設設置為輪播BGM,可以在設置介面中關閉BGM輪播 3.在遊戲內查看其他介面時拖動滾輪,將不再導致大地圖一同縮放 4.優化了遊戲中背景圖片覆蓋不全的問題 5.增加了解鎖第二/三個英雄的快捷點擊按鈕 6.優化了部分技能/科技的描述文字 7.優化了繼續遊戲/重玩本回合loading介面圖片與所選陣營不匹配的問題 ------- [新增內容] ------- 1.新增蓬萊山帝國歷史時刻插圖 我們仍在持續修復其他bug以及各種翻譯問題,並一直關注各個渠道中大家的回饋。你的回饋、耐心與支持是我們最大的動力!!謝謝你們! 5/18[版本V0.7.1k]更新說明
4 english 5/18 [Version V0.7.1k] Patch Notes [Version V0.7.1k] Release Date: 2026.5.18 ------- [Bug Fixes] ------- 1. Fixed a bug where saving was still possible after surrendering. 2. Fixed a bug where killing Fujiwara no Mokou could erroneously spawn two Mokou Flames if a chain fear damage occurred at the same moment. 3. Fixed a bug where killing the Koakuma Priest could erroneously spawn two Koakuma Priests (Lion God Form) if a chain fear damage occurred at the same moment. 4. Fixed a bug where the Komeiji Empire wonder building's description text was missing. 5. Fixed a bug where a Spy unit pushed out of a city by a Giant unit could not return to stealth after moving. 6. Fixed a bug where Yuugi Hoshiguma could mistakenly enter an enemy harbor due to a push during her attack. ------- [Improvements] ------- 1. Fixed UI text overflow in several places (in multi-language environments). 2. The game now defaults to BGM shuffle; this can be turned off in the Settings menu. 3. Scrolling the mouse wheel while viewing other panels in-game no longer zooms the world map. 4. Fixed an issue where in-game background images did not fully cover the screen. 5. Added shortcut buttons to unlock the second and third Heroes. 6. Polished the description text for some Skills and Techs. 7. Fixed a mismatch between the loading screen image and the selected faction when using Continue Game / Replay Turn. ------- [New Content] ------- 1. Added 4 Houraisan Empire historic moment illustrations. We're still working hard on fixing more bugs and translation issues, and we keep a close eye on everyone's feedback across all our channels. Your feedback, patience, and support are the greatest motivation for us!! Thank you so much, everyone! 5/18 [Version V0.7.1k] Patch Notes
5 japanese 5/18【バージョンV0.7.1k】アップデート内容 [バージョン V0.7.1k] リリース日 2026.5.18 ------- [バグ修正] ------- 1. 降伏後もセーブを継続できてしまうバグを修正 2. 藤原妹紅を撃破した際、同時に連鎖恐怖ダメージが発生すると妹紅の炎が誤って2つ生成されることがあるバグを修正 3. 小悪魔神官を撃破した際、同時に連鎖恐怖ダメージが発生すると小悪魔神官(獅神形態)が誤って2体生成されることがあるバグを修正 4. 古明地帝国の奇跡建築の説明文が欠落するバグを修正 5. 巨人ユニットに都市から押し出されたスパイユニットが、移動後にステルス状態に戻れないバグを修正 6. 星熊勇儀が攻撃時の押し出しにより誤って敵港湾に侵入してしまうバグを修正 ------- [最適化] ------- 1. 多言語環境下で複数箇所のUIテキストがはみ出す問題を最適化 2. 現在、ゲームの初期設定はBGMの順送り再生となっており、設定画面でオフにできるようになりました 3. ゲーム内で他の画面を表示中にホイールをスクロールしても、メインマップが同時にズームされなくなりました 4. ゲーム内の背景画像が全体を覆いきれない問題を最適化 5. 2人目/3人目の英雄を解放するショートカットボタンを追加 6. 一部のスキル/テクノロジーの説明文を最適化 7. ゲームを続ける/このターンをやり直す際のローディング画面の画像と選択した陣営が一致しない問題を最適化 ------- [新規追加] ------- 1. 蓬莱山帝国の歴史時刻の挿絵を4枚追加 他のバグや各種翻訳の問題も引き続き修正を進めており、各チャンネルで寄せられる皆さまのご意見にも常に目を通しています。皆さまのフィードバック、ご辛抱、そしてご支援こそが私たちの最大の原動力です!!本当にありがとうございます! 5/18【バージョンV0.7.1k】アップデート内容
6 korean 5/18 [버전 V0.7.1k] 업데이트 노트 [버전 V0.7.1k] 출시일 2026.5.18 ------- [버그 수정] ------- 1. 항복 후에도 세이브를 이어갈 수 있는 버그 수정 2. 후지와라노 모코우 처치 시 동시에 연쇄 공포 피해가 발생하면 모코우의 불꽃이 잘못 2개 생성되는 버그 수정 3. 소악마 사제 처치 시 동시에 연쇄 공포 피해가 발생하면 소악마 사제(사자신 형태)가 잘못 2개 생성되는 버그 수정 4. 코메이지 제국 불가사의 건물의 설명 문구가 누락되는 버그 수정 5. 거인 유닛에 의해 도시 밖으로 밀려난 스파이 유닛이 이동 후 다시 은신할 수 없는 버그 수정 6. 호시구마 유우기가 공격 시 밀어내기로 인해 잘못 적 항구로 들어가는 버그 수정 ------- [최적화] ------- 1. 다국어 환경에서 여러 곳의 UI 텍스트가 프레임을 벗어나는 문제 최적화 2. 현재 게임 기본 설정이 BGM 순차 재생이며, 설정 화면에서 BGM 순차 재생을 해제할 수 있습니다 3. 게임 내에서 다른 화면을 보는 중 휠을 스크롤해도 메인 맵이 함께 확대/축소되지 않습니다 4. 게임 내 배경 이미지가 전체를 덮지 못하는 문제 최적화 5. 두 번째/세 번째 영웅을 해금하는 단축 버튼 추가 6. 일부 스킬/과학기술의 설명 문구 최적화 7. 게임 이어하기/이번 턴 다시하기의 로딩 화면 이미지가 선택한 진영과 일치하지 않는 문제 최적화 ------- [새로운 콘텐츠] ------- 1. 호라이산 제국 역사적 순간 삽화 4장 추가 다른 버그와 다양한 번역 문제도 계속해서 수정하고 있으며, 여러 채널에서 보내주시는 여러분의 피드백을 늘 살펴보고 있습니다. 여러분의 피드백과 인내, 그리고 응원이 저희의 가장 큰 원동력입니다!! 정말 감사합니다! 5/18 [버전 V0.7.1k] 업데이트 노트

View File

@ -1,5 +1,5 @@
{
"nextId": 21,
"nextId": 22,
"todos": [
{
"id": 2,
@ -117,6 +117,12 @@
"title": "发图",
"done": false,
"createdAt": 1778947602361
},
{
"id": 21,
"title": "新增数字美术包放到群里",
"done": false,
"createdAt": 1779262524577
}
]
}

View File

@ -0,0 +1,167 @@
# 01_事件背景与玩家诉求
## 事件起源
2026-05-14 TH1 EA 发售,中文圈三区定价(¥28/HK$35/NT$120)显著高于 Steam 推荐定价,且**高于美区($3.99 ≈ ¥28 但实际美区按 Steam 推荐应更低)、日区(¥500 日元 ≈ 折合实际差异大)**。
发售约 3-5 天后(5/17-5/18),小黑盒帖子开始发酵。
---
## 玩家真痛点(必须理解,任何 session 处理必看)
### ❌ 错误理解
> "玩家骂的是'价格高于 Steam 推荐定价'"
### ✅ 正确理解
> "玩家骂的是'国区比美日还贵 = 中国玩家被歧视'"
**这是两个完全不同的痛点**。
| 表达 | 玩家感受 |
|------|---------|
| "高于推荐定价" | 抽象、技术化、像在转移焦点 |
| "高于美区/日区" | 具体、情感化、直击痛点 |
**任何回应必须对齐玩家原始痛点,不能用技术化表达逃避**。
---
## 玩家高频骂点(原话存档)
### 第一波:技术指控
- "Steam 的推荐定价都不可能把国区定价比美国贵,只可能是厂商自己调的"
- "按作者说的 4 刀按汇率差不多 28 人民币,推荐定价会让国区和美区同价,真是令人信服的理由"
- "嘴硬说 3.99 刀自动定价 28 人民币,当社区没有开发者科普 steam 定价机制呢"
- "嘴硬说现在降价会背刺已经购买的用户,以为大家不知道 steam 会给最近买贵的用户自动退差价呢"
### 第二波:态度指控
- "嘴硬还说自动定价"
- "态度再好不做出行动也没用"
- "人情世故都搞不明白"
- "和十二影 Twelves:Shadow 这个游戏一样,嘴硬说推荐定价"
### 第三波:本质指控
- "国产游戏,国区最贵"
- "区别对待""不把国区当回事""收割韭菜"
- "国区高价方便收割韭菜"
- "我看美国人一半都要被斩杀了,日本人饭都吃不起了,那咱们多出两块钱支持下游戏产业也没啥大不了的吧"(讽刺)
### 第四波:行为预测
- "他不是知道错了,是知道自己要死了.jpg"
- "考虑到现在就国区专属尊贵高价嘴硬不调"
- "推测出后面更新塞屎对抗玩家概率不小"
- "败坏路人缘"
### 第五波:观望诉求
- "什么叫我昨天刚买的还没捂热就降价了差价谁补"
- "原价已经降到 18 了"(信息传播)
- "不知道其他已经买的喝油怎么补偿"
- "群公告说是正在咨询 steam 客服"
---
## 群体分类(决定回应策略)
### 🟢 友善方(约 50-60%)
**特征**:
- 理性指出问题,不带情绪
- 主动帮你在社区解释
- 看到改价后愿意撤评/改评
- 给红包关心你"会不会饿死"
**代表**:
- 烃-(浙江,多次帮你解释)
- FunJack(原价降到 18 后入手支持)
- 闽江招生办附属泉奈(理性指出"是厂商自己调的")
- 多变量转换私信玩家(同行视角,懂 Steamworks 后台)
**处理策略**:
- 点赞 + 简短感谢
- 不公开 @ 避免他们被嘴硬党挂"水军"
- 私信里可以适度展开技术真相(供他们"科普"用)
### 🟡 中立路人(约 30-40%)
**特征**:
- 观望中,看你怎么做
- 不主动骂也不主动支持
- 看到改价 + 补偿方案会做出判断
**处理策略**:
- 用"行动 + 补偿"打动,不用"语言 + 解释"
- 视频/公告主要面向这群人
- 这是你 80% 精力的目标
### 🔴 嘴硬党 / 死磕(约 5-10%)
**特征**:
- 情绪化嘲讽
- 不接受任何解释
- 哪怕你完美处理也会继续骂
**代表评论**:
- "他不是知道错了,是知道自己要死了.jpg"
- "败坏路人缘""塞屎对抗玩家"
- "行为符合头像"
**处理策略**:
- **完全不回应**
- 任何回应 = 给截图素材
- 0% 精力,接受这是"事件成本"
---
## 关键 evidence:开发者第一次回应(嘴硬贴原文)
> 诶大家好,我是这游戏的开发者 天火人雪糕。
> 被老哥提到的事情,我发现我确实有疏忽的地方,这里也澄清一下——
> 因为我看地区定价很复杂,就决定完全按照 Steam 推荐定价做的,我先是选择了美区的 $3.99 档位,国区的价格是自动定位到 ¥28,日区是 500 出头,按汇率其实是基本对齐的。但是我最大的失误在于我当时把日区调整到了 ¥500(我本来想着就抹个零吧)。然后整体的定价,在以美元为基准的汇率转换情况下,显得国区更贵了。但是这不是区别对待,这确实是我第一款游戏开发没注意到踩坑了。
> 但是我没办法给国区也补个"降价",因为游戏已经 EA 发售了 3 天了,按 ¥28 定价购买的朋友是最早支持我的人,我也没法因此就反悔调整,对他们也不公平。
> 后续 Steam 的打折周期我会去做的!!也希望大家继续多多支持 w
> 谢谢老哥提出来!也谢谢楼里帮忙解释的朋友们~
**这条贴的致命问题**:
1. "完全按照 Steam 推荐定价做的" — 玩家立刻反驳"推荐定价不可能国区比美区贵"
2. "汇率换算基本对齐" — 玩家立刻反驳"国区购买力低于美日,推荐价不可能更高"
3. "不能给国区补降价 / 对已购玩家不公平" — 这是被骂最狠的一句,逻辑反了
4. 整体姿态"我没错只是疏忽" — 被解读为嘴硬
**这条贴成为 5/18 危机扩大的导火索**。
---
## 私信类高价值反馈(同行视角)
某玩家通过私信主动指出技术真相:
> "我开始是也想帮忙解释一下的。但是我登上 steam 后发现,steam 默认的定价策略是多变量转换,这种情况下国区定价是不会太高的。而导致国区定价比美区定价都要高的原因是定价时选择了'仅按汇率转换'。这个问题确实是不好解释的。"
**这是金矿级私信**——理性同行,本来想帮你,但被技术事实卡住。
**这类私信必须回复(详见 05_已执行话术存档)**——可以适度展开技术细节(私信场景安全),建立"自来水"信任。
---
## 玩家未明说但隐含的诉求
读完所有评论,玩家真实的"想要"是:
1. **要"道歉的姿态"** — 不是 PR 道歉,是承认自己错
2. **要"行动证明"** — 改价 + 补偿,不只是话
3. **要"被尊重"** — 国区玩家不是二等公民
4. **要"不画饼"** — 不要"以后会怎样",要现在能看到
5. **要"开发者人格"** — 知道你是真人不是公司 PR
6. **要"不跑路"** — 担心你被骂跑了,游戏烂尾
7. **要"长期透明"** — 后续 DLC 不要切片收割
**所有处理策略必须对齐这 7 个诉求**。
---
## 一个关键比例
```
"渴望知道你不是有意的"(友善方) : "试图证明你是恶意的"(嘴硬党)
= 6 : 1 ~ 8 : 1
```
也就是说:**对你抱有善意的玩家是死磕党的 6-8 倍**。处理时把精力放在前者,后者注定挽回不了,接受这个成本。

View File

@ -0,0 +1,193 @@
# 02_危机公关策略与决策
## 整体策略
**核心原则**: **行动 > 语言。诚信 > 完美。透明 > 隐藏。**
## 关键决策点(每个都讨论过利弊)
### 决策 1:嘴硬贴**不删除,在底下追加认错**
**讨论过的选项**:
- ❌ 删除嘴硬贴 → 控评指控、删评二次危机
- ❌ 编辑嘴硬贴 → 改动会被发现
- ✅ **不删 + 楼中楼追加认错**
**追加贴的核心句**:"上面这条愚蠢的回复就留在这里提醒自己,不删。"
**为什么这是核武器**:
- 自嘲程度比玩家骂得还狠 → 解除 70% 敌意
- 主动声明"不删" → 预防"删评"指控
- 形成完整时间线证据,反而成为诚信资产
- 谁截图嘴硬贴,必须连带截到认错追加,传播效果减半
### 决策 2:补偿方案**走 DLC Key,不走"退差价"**
**讨论过的选项**:
- ❌ 主动给所有原价玩家退 ¥10 → Steam 不支持开发者主动退差价
- ❌ 让所有人走 Steam 自助退款 → >2 小时玩家走不了
- ❌ 在公告里承诺"退差价" → 做不到的承诺=画饼
- ✅ **<2 小时走 Steam 退款 + 所有原价玩家凭订单领 DLC Key**
**为什么 DLC Key 是神器**(单机游戏特别适用):
- Steam 后台预生成 Key,DLC 没做完也能发
- Key 是看得见摸得着的实物凭证,不是承诺
- 玩家激活后,游戏库里显示"DLC: 即将推出",**补偿心理落地**
- 把"画饼 9 个月"变成"已发放预付凭证"
### 决策 3:**不专门发"澄清贴"**,真相通过 3 个渠道分阶段释放
**渠道**:
1. **私信渠道**(理性玩家私信里展开技术细节)
2. **公告里 1 句话埋**("混用了 Steamworks 两种定价工具")
3. **1-2 周后软性复盘文**(开发者博客/B站长视频)
**为什么不专门澄清**:
- "澄清"姿态本身就输了 = 像"求理解"
- 对立方不会被澄清改变(他们已经选择立场)
- 友善方需要的是"弹药"而非"公开声明"(私信即可)
- 中立路人看行动不看解释
### 决策 4:**视频/公告里用"高于美日"话术,不用"高于推荐定价"**
**讨论过的纠结点**:
- 用"高于推荐定价" = 安全但答非所问,像嘴硬
- 用"高于美日" = 对齐玩家痛点,但风险是"邀请其他地区比对"
**最终判断**:
- 玩家骂的是"高于美日",回应"高于推荐"就是嘴硬
- 海外玩家没多付钱,不会有"我也要降"诉求
- **前提**:其他地区定价确实符合 Steam 推荐(必须先验证 Steamworks 后台)
- 推荐"双重表述":既说"高于美日"又说"违反推荐梯度"
### 决策 5:**视频用纯字幕+BGM,不用 AI 配音也不出镜**
**用户限制**:
- 不愿出镜
- 不愿录音
- 之前默认想用 AI 配音
**讨论结果**:
- AI 配音的情感段落会显得"塑料"——尤其"红包截图段"
- B 站观众对常见 AI 声线敏感,弹幕会刷"AI 配音""一眼丁真"
- **纯字幕 + BGM** 反而显得庄重、像"声明文件"
- 适合道歉调性,避免商业感
### 决策 6:**不回复评分区差评、不刷自己 5 星好评**
**讨论过的诱惑**:
- 想给自己刷 5 星留言"开发者声明"——绝对禁止
- 想私信差评者要求撤评——平台违规风险
**为什么坚决不做**:
- 评分区是战场,下场 = 引爆"控评"指控
- 任何"自评"在危机期都是自杀
- 私信差评者 = 法律风险(中国对控评敏感)
- **正确做法**:让 48 小时后补偿方案自然吸引"翻转评论",差评盖过去
### 决策 7:**17 阵营问题主动透明**
**问题**:
- 游戏内已经能遇到 17 个敌人
- 当前可玩 4 个,正式版 8 个,DLC 1 增 2 个,剩 7 个"长期愿景"
- 玩家会算"剩 7 阵营按 ¥5 单价 = ¥45,加起来 ¥63 长线收割"
**决策**:
- 主动公布完整结构:4 可玩 + 4 EA 计划 + 2 DLC1 + 7 未来
- 主动公布"全套封顶价":EA 玩家 ≤ ¥60,正式版玩家 ≤ ¥70
- 主动承诺"不切片销售""倾向打包"
### 决策 8:**视频里不展开技术细节**
**用户的诉求**:想澄清"不是刻意的"
**讨论结果**:
- 公告/视频里展开 = 嘴硬第N季种子
- "疏忽"两字已经传达了"不是刻意"
- 想表达诚意 → 留给"红包截图 + 真诚收尾"那一段
---
## 不同场景的回应策略
### 公开场合(评论区、Steam 公告、B站动态)
| 内容 | 是否展开 |
|------|---------|
| 道歉 | ✅ 直接说 |
| 改价信息 | ✅ 三区都列 |
| 补偿方案 | ✅ 详细列流程 |
| 技术原因(汇率 vs 购买力) | ❌ 最多 1 句话带过 |
| "我不是刻意的"自辩 | ❌ 用"疏忽"两字传达 |
| 涨价预告 | ❌ 留到后续单独说 |
| 全套封顶承诺 | ✅ 必须明说 |
### 私信场合(同行/理性玩家私信)
| 内容 | 是否展开 |
|------|---------|
| 技术真相 | ✅ 可以详细说 |
| "不是刻意的"内心独白 | ✅ 可以坦白 |
| 公开场合的策略困境 | ✅ 可以解释 |
| 对差评的真实感受 | ⚠️ 谨慎,任何话默认可被公开 |
**唯一铁律**: **私信里说的任何话,要"经得起被截图公开"的检验**
---
## 时间节奏(危机公关黄金 48 小时)
```
T+0(改价时刻 5/18 16:06):立刻发占位短帖
T+2 小时:嘴硬贴下追加认错
T+4 小时:小黑盒道歉帖(已发)
T+8 小时:回复闽江高赞理性指控(已做)
T+24 小时:发 B 站/微博/小黑盒视频
T+48 小时(5/20 24:00):Steam 正式公告 + 完整补偿方案
T+1 周(5/27):开始批量发 DLC Key
T+2 周:观察评分区状态,不主动干预
T+1 月:发"开发者复盘"软性内容(可选)
T+3 月:B站"独游踩坑回顾"长视频(可选)
```
---
## "诚信资产"的复利效应
**核心洞察**: 这次危机如果处理好,**诚信资产可以复利使用**。
| 动作 | 立刻收益 | 长期收益 |
|------|---------|---------|
| 嘴硬贴下追加认错 | 解除当前敌意 | 形成"勇于认错"人设 |
| 主动公布全套封顶价 | 化解"长线收割"指控 | 玩家长期信任 |
| Steam 申请 Key 时主动说"DLC 在开发" | 审核通过 | 不留诚信隐患 |
| 私信回复同行 | 获得自来水 | 长期 KOL 关系 |
| "不删嘴硬贴" | 预防二次危机 | 历史证据资产 |
**长期收益 >> 立刻收益**。这是策略选择的核心衡量标准。
---
## 数据预期(用户应有的心理建设)
| 时间点 | 差评状态 |
|--------|---------|
| 现在(5/18-5/19) | 集中爆发,数量多,情绪激烈 |
| +24 小时(5/19-5/20) | 增速放缓,部分友善方反向辩护 |
| +48 小时(5/20 补偿方案发布) | 出现"翻转评论",撤评开始 |
| +1 周(5/27 Key 发放后) | 新好评开始上升,差评数量稳定 |
| +1 月 | 差评淡出,事件被新版本/更新冲淡 |
**核心数字**:好的补偿方案能让差评在 1 周内下降 30-50%。**差评清零不可能**——这是事件成本,不是 bug。
---
## 用户精力分配建议
```
❌ 0% 给嘴硬党(任何回应都是火上浇油)
✅ 80% 给中立路人(用补偿方案 + 视频打动)
✅ 20% 给友善方(私信提供"弹药" + 点赞)
```
**当试图说服嘴硬党时,你正在浪费给中立路人的精力**。

View File

@ -0,0 +1,258 @@
# 03_补偿方案完整设计
## 方案概览(单机游戏适配版)
```
🟢 立即可领(所有 EA 期间购买玩家,不限原价):
▎数字感谢礼包(壁纸/概念图/感谢信 PDF)
- 加 QQ 群 952618884 公告区下载
- 不需要提交订单号
- 开发成本:1.5 小时(打包已有素材)
🟢 凭原价订单领取(仅原价玩家):
▎免费 DLC Key
- 预激活 Key,DLC 上线时自动可玩
- DLC 等价 ¥10
- 凭 Steam 订单号申请,人工审核
- 申请截止:2026/12/31
- 集中发放:5/27 起每周批处理
🟢 自助退款(Steam 官方流程):
<2 小时玩家可立即拿回差价
- 退款重买后,原订单失效
- 不在 Key 补偿范围(避免双重补偿)
```
---
## DLC Key 资格判定(核心规则)
### 通过条件(必须全部满足)
1. **购买时间**:在 2026/5/18 16:06 UTC+8 之前
2. **支付金额**:必须是原价
- 中国区:¥28
- 中国香港:HK$35
- 中国台湾:NT$120
3. **订单状态**:未走过 Steam 退款,仍然有效
### ⚠️ 待确认的关键事实
**首周特惠的实际生效情况**:
- 首周特惠声称从 5/14 17:14 UTC+8 开始(9 折)
- 但小黑盒上所有原价玩家都说"付了 ¥28"而非 ¥25.2
- 可能原因:首周特惠在改价前没生效,或生效时间不同
- **后续 session 处理时务必先验证实际付费金额**(让玩家提交订单截图)
---
## 12 个场景的处理流程
| # | 场景 | 给 Key? | 说明 |
|---|------|---------|------|
| 1 | 自买自玩,原价,未退款 | ✅ 标准发放 | 主流情况 |
| 2 | 送礼,已激活 | ✅ Key 给付款人 | 付款人可再转赠 |
| 3 | 送礼,未激活 | ⚠️ 优先建议自助退款 | 比走 Key 更快、拿到更多钱 |
| 4 | 已通过 Steam 退款 | ❌ 不发放 | 已拿回差价,避免双重补偿 |
| 5 | 退款流程进行中 | ⏳ 等待结果 | 让玩家退款完再判断 |
| 6 | VPN 切区低价购买 | ❌ 不发放 | 看实际支付金额 < 原价 |
| 7 | 海外华人付 HK$35/NT$120 | ✅ 发放 | 实际付了原价就给 |
| 8 | Steam 家庭共享 | ✅ Key 给购买者 | 共享对象自然共享 DLC |
| 9 | 玩家 Key 丢失要求重发 | ✅ 重发同一 Key | 不取消旧 Key 不发新 Key |
| 10 | 同一订单多次申请 | ❌ 已发不重复 | Excel 记录防重复 |
| 11 | 拿到 Key 后转赠 | ⚠️ 接受但建议自留 | Steam 政策允许转赠 |
| 12 | 不在 QQ 群的玩家 | ✅ 邮箱替代渠道 | 双通道设计 |
---
## 申请玩家需提交的 5+1 项
```
1. Steam 用户名 / 个人主页链接
2. Steam 购买订单号(客户端 → 帮助 → 购买记录)
3. 购买时支付的金额 + 货币(例:¥28 / HK$35 / NT$120)
4. 购买地区(CN / HK / TW)
5. 购买类型:
☐ 自买自玩
☐ 我送朋友(礼物未激活)
☐ 我送朋友(礼物已激活)
↑ 选"礼物"请额外注明接收人 Steam 用户名
6. 上传 Steam 购买记录截图(因 Sales Reports 是月报,人工核对需要截图凭据)
```
---
## 申请通道(双通道设计)
| 通道 | 用途 | 优先级 |
|------|------|--------|
| QQ 群 952618884 "DLC Key 申领"专区 | 中国玩家(更快沟通) | 主通道 |
| 邮箱(待定) | 港台/海外华人/正式留档 | 备通道 |
| 腾讯问卷(可选) | 结构化收集 | 进阶选项 |
| Google Form(可选) | 海外结构化收集 | 进阶选项 |
---
## 人工审核 SOP
```
1. 收到玩家提交后,记录到 Excel 跟踪表
2. 登录 Steamworks 后台核对:
- 主面板 → 财务 → Sales Reports(月度数据,5月数据要6月底才出)
- 或:玩家提交的订单截图(更快)
3. 验证 4 件事:
☐ 订单号存在
☐ 支付金额是原价
☐ 购买时间在 5/18 16:06 之前
☐ 订单未退款
4. 通过 → 标记 Excel "已通过"
→ 从 Key 列表取一个,标记"已用"
→ 通过私信/邮箱发 Key
5. 不通过 → 用对应模板回复(详见 05_已执行话术存档)
```
### Excel 跟踪表字段
```
| 提交时间 | Steam用户名 | 订单号 | 价格 | 地区 | 类型 | 审核结果 | Key已发 | Key值 | 备注 |
```
### 集中处理建议
- **固定时间**:每天晚上 8-10 点
- **预估量**:第一周高峰 50-200/天,后续 10-30/天
- **流程**:整理新申请 → Steamworks 后台/截图核对 → 发 Key + 标记 Excel
---
## Steam DLC Key 申请细节
### 申请数量公式
```
申请 Key 数 = 实际原价销量 × 1.3(30% 缓冲)
⚠️ 不要超过 30% 缓冲,否则可能被 Steam 拒批怀疑滥用
```
### 申请说明(500 字符版,英文,已提交)
```
Compensation Keys for unreleased DLC (App XXXXX, in
development, Q1 2027) of TOHOTOPIA.
A pricing oversight made CN/HK/TW prices higher than
Steam recommended; fixed May 18.
Keys go to players who paid original price
(¥28/HK$35/NT$120) before May 18 and didn't refund.
Verified via Sales Reports, sent individually. Not sold,
not public, not promotional. Players informed DLC is
in development.
[X] eligible, requesting [Y] (+30% buffer). Deadline
Dec 31, 2026.
```
**5 个必须保留的关键点**:
1. "in development"(主动说 DLC 未完成)
2. "pricing oversight"(申请理由)
3. "didn't refund"(资格门槛)
4. "Not sold, not public, not promotional"(不挪用承诺)
5. "Players informed DLC is in development"(玩家端透明承诺)
### Steam 审核时间预期
| 阶段 | 预计时间 |
|------|---------|
| 创建 DLC App | 即时(已完成) |
| Steam 审核 DLC | 1-3 个工作日 |
| 申请 DLC Key | 提交后 1-3 个工作日 |
| Key 到手 | **总计 3-7 天** |
**所以 5/20 公告里说"5/27 起批量发放 Key"是合理的**。
---
## DLC Key 工作机制(必须主动说明)
```
⚠️ Key 是预激活码,DLC 内容仍在开发中
▎DLC 当前状态:
- 内容开发中,尚未发布
- 预计 2027 Q1 上线(随正式版后续)
▎Key 的两种使用方式:
▸ 方式 A(推荐):现在激活
- 收到 Key 后立即在 Steam 激活
- DLC 会出现在游戏库,显示"即将推出"
- DLC 实际发布时,自动可玩
- 不会丢失,与账号绑定永久有效
▸ 方式 B:保留 Key 等发布
- 不激活,自己保存
- 等 DLC 发布时再激活
- 注意:请妥善保管
▎激活操作:
Steam 客户端 → 游戏 → 激活产品代码 → 输入 Key
▎送礼场景:
Key 发给付款人,付款人可自激活或再赠送给原接收人
(Key 是标准 Steam Key,支持赠送)
```
**推荐玩家"现在激活"的 4 个好处**:
1. 心理验证完成(库里看到"即将推出" = 补偿落地)
2. Key 不会丢(与账号绑定)
3. 减少你的"重发"工作量
4. 玩家可以晒"库里的 DLC 即将推出"截图,**集体可验证的真实补偿**
---
## 数字感谢礼包内容(成本 1.5 小时)
```
礼包内容(打包成 ZIP):
▎壁纸_4K_X张.jpg ← 用游戏内现有立绘导高分辨率
▎壁纸_手机版_X张.jpg ← 同上改尺寸
▎角色设计稿_X张.png ← 已有的内部设计图
▎开发者感谢信.pdf ← 你写一封 1 页诚意信
▎README.txt ← 简单说明
实际成本:
- 打包已有素材: 30 分钟
- 调整分辨率: 30 分钟
- 写感谢信: 30 分钟
= 1.5 小时
```
---
## 红线总结
```
❌ 不要承诺"主动退差价"(Steam 做不到)
❌ 不要在 Key 没到手前发任何 Key
❌ 不要把 Key 公开发布(Steam 会回收)
❌ 不要用 Key 做抽奖/促销(违反"补偿"理由)
❌ 不要给媒体当评测 Key(应另申请 Press Keys)
❌ 不要承诺"无截止日期"(留 12/31 作为闭环点)
❌ 不要"承诺退差价"但下一段说"做不到"(自相矛盾)
❌ 不要在退款 + DLC 上让玩家"同时领"(对未退款玩家不公平)
```
## 申请高频问题速查
### Q: 玩家拿到 Key 后转赠/出售?
A: Key 一旦发出,所有权归玩家。你不能技术上限制转赠。但在公告里**建议保留**——"这是给原价玩家的专属感谢,转赠不影响资格,但请勿在第三方平台出售"。
### Q: VPN 玩家用阿根廷区低价买,但被中国 IP 标识?
A: 看**实际支付金额**,不看 IP。实际付费 < 原价 不发 Key
### Q: 海外华人付 HK$35 或 NT$120?
A: 给 Key。只看支付金额,不看国籍。
### Q: 第一批 Key 不够用怎么办?
A: 可以申请第二批,Steam 审核第二批通常更快(有使用记录)。但**第一批不要申请太多**(超过 30% 缓冲容易被拒)。

View File

@ -0,0 +1,277 @@
# 04_DLC定价与17阵营问题
## 关键事实:阵营结构
游戏内**已经能遇到 17 个敌人**,但其中:
```
17 阵营总数:
├─ 4 个已可玩(EA 当前)
├─ 4 个 EA 期间会做(免费,正式版前完成)
├─ 2 个 DLC 1 规划(¥10,原价玩家免费)
└─ 7 个未来 DLC 规划(长期愿景,未正式立项)
非可玩阵营:在游戏中作为 AI 对手出现
只有领袖头像 + 基础 AI,无可玩玩法
```
---
## 玩家潜在质疑(必须预防)
### 质疑 1:"游戏内已有 17 阵营,你 DLC 卖的是啥?"
**回应核心**:17 是世界观规模,4 可玩 + 13 AI 对手。DLC = 把 AI 阵营转化为可玩。
### 质疑 2:"你 8 阵营 ¥18,剩 9 阵营按 ¥5 = ¥45,加起来 ¥63 太贵"
**回应核心**:已主动公布"全套封顶 ¥60(EA 入手)/ ¥70(正式版入手)"。
### 质疑 3:"是不是用降价收买人心,后面 DLC 切片收割?"
**回应核心**:已主动承诺"不切片销售""倾向打包""价格透明"。
### 质疑 4:"剩 7 阵营会做完吗?"
**回应核心**:不承诺必做完。但承诺"做的都遵循封顶价"。
---
## 价格档位完整设计
| 项目 | 当前 | 正式版 | 备注 |
|------|------|--------|------|
| 本体(中国区) | ¥18(EA) | ¥28(预期) | 改价后,首周特惠 ¥16.2 |
| DLC 1(2 阵营) | - | ¥10 | 原价玩家免费 |
| DLC 2+(假设) | - | 待定 | 单阵营 ≤ ¥5,倾向打包 |
### 全套封顶承诺(关键)
```
▎EA 早鸟玩家(¥18 入手):
全套阵营内容总价 ≤ ¥60
▎正式版玩家(预期 ¥28 入手):
全套阵营内容总价 ≤ ¥70
▎不包含:
非阵营 DLC(音乐包/设定集等周边)
```
**这个承诺的作用**:
- ✅ 立刻封锁"长线收割"指控
- ✅ 给 EA 玩家 ¥10 的"早鸟价值"
- ✅ 给开发者保留弹性(7 阵营做不完也不算违约)
---
## 后续 DLC 承诺(4 条核武器)
```
1. 不切片销售
不会让每个阵营单独 ¥10/¥15 卖
2. 价格透明
任何新 DLC 提前公告,价格保持合理标准
3. 全套封顶
即便所有 17 阵营全部完成 + 全部付费 DLC,
全套总价不会超过 ¥60(EA入手) / ¥70(正式版入手)
4. 优先打包
小内容倾向作为免费更新
大内容打包成扩展包,而非切片
```
---
## 重新框架"17 阵营"表述
### ❌ 不要说
> "游戏将有 17 个阵营"
### ✅ 应该说
> "游戏世界共有 17 个阵营(参考东方 Project 角色谱系),
> 当前 4 可玩,正式版 8 可玩,DLC 1 增 2 可玩,
> 剩余持续转化为可玩。"
---
## 视频/公告完整表述
```
关于本作的阵营内容结构(透明公开):
▎游戏世界观:共有 17 个阵营
(参考东方 Project 角色谱系)
▎当前 EA 阶段:
✅ 4 个阵营完整可玩
⬜ 13 个阵营作为 AI 对手出现
(有领袖头像和基础 AI,无可玩玩法)
▎正式版 1.0(2026 年底):
✅ 8 个阵营完整可玩(免费升级)
- EA 期间会逐步加入 4 个新可玩阵营
- 不需要额外付费
▎第一个 DLC(2027 Q1):
✅ 新增 2 个可玩阵营,共 10 可玩
- 定价 ¥10
- 原价购买玩家免费获得
▎剩余 7 个阵营(更长期):
- 暂无具体开发时间表
- 后续视开发进度和玩家反馈决定
- 可能形式:DLC / 免费更新 / 大型扩展包
- 价格承诺:单阵营成本不超过 ¥5
- 倾向于打包成大型扩展包(总价更优)
关于后续 DLC 的 4 条承诺:
1. 不切片销售
2. 价格透明
3. 全套封顶(EA 入手 ≤ ¥60 / 正式版 ≤ ¥70)
4. 优先打包(小内容免费更新,大内容打包)
```
---
## 视频画面建议(进度条可视化)
```
┌─────────────────────────────────────┐
│ 本作阵营内容结构 │
│ ════════════════════════ │
│ │
│ 17 阵营 = 游戏世界规模 │
│ │
│ ───────────────── │
│ │
│ 当前 EA: │
│ ▰▰▰▰▱▱▱▱▱▱▱▱▱▱▱▱▱ 4 / 17 │
│ │
│ 正式版 1.0(免费升级): │
│ ▰▰▰▰▰▰▰▰▱▱▱▱▱▱▱▱▱ 8 / 17 │
│ │
│ DLC 1(原价玩家免费): │
│ ▰▰▰▰▰▰▰▰▰▰▱▱▱▱▱▱▱ 10 / 17 │
│ │
│ ───────────────── │
│ │
│ 剩余 7 阵营:长期开发 │
│ 全套总价 ≤ ¥60 (EA 入手) │
└─────────────────────────────────────┘
```
---
## DLC 1 是否提前公布具体 2 个阵营
### 提前公布的好处
- 让玩家知道"是不是我想要的"
- 选热门角色 → 立刻收获好感
- 减少"DLC 内容不明"的焦虑
### 提前公布的风险
- 选错角色 → 玩家觉得"骗钱"
- 改主意时不灵活
### 推荐:**主役级角色 + 公开 1 个,留 1 个悬念**
**建议优先角色类型**:
- 高人气主役(灵梦/魔理沙/咲夜/妖梦/早苗等)
- 玩家在 EA 阶段呼声高的(听 QQ 群反馈)
- 玩法上特色鲜明的(避免和现有 4 个雷同)
**避免冷门角色**——会被解读为"凑数"。
---
## 防御性话术模板
### Q: "你 8 阵营 ¥18,剩 9 阵营按 ¥5 = ¥45,合计 ¥63 太贵?"
```
"理解你的担忧。
但需要澄清:
- 17 阵营是世界观规模,不是付费阵营
- 已经承诺全套封顶:EA 入手 ≤ ¥60 / 正式版 ≤ ¥70
- 剩余阵营会优先考虑打包成扩展包,不切片
- 部分小型阵营有可能作为免费更新
具体来说:
- 本体 ¥18 包含 8 可玩阵营
- DLC 1 增 2 阵营 ¥10(原价玩家免费)
- 剩余 7 阵营如果做,总价不超过 ¥32
不会让玩家陷入'每个 ¥10 切片卖'的局面。"
```
### Q: "是不是用降价收买人心,后面 DLC 切片收割?"
```
"理解这个担忧,我也思考过。
回答:
- 降价是修正错误,不是营销手段
- DLC 不会是'付费切片',会有完整的内容包装
- 原价购买玩家免费获得第一个 DLC
- 后续 DLC 计划公开透明
如果你看到任何'每个新阵营 ¥10/¥15 单独卖'的
切片定价,你可以来骂我。我承诺不做这种事。"
```
### Q: "我玩到的 13 个 AI 阵营,什么时候能玩?"
```
"理解你想玩特定角色的心情。
当前明确计划:
- 正式版 8 可玩
- DLC 1 + 2 可玩(共 10 个)
- 剩余 7 个的转化进度,会持续公告
如果你有特别想玩的角色,可以在 QQ 群告诉我,
玩家呼声是我决定后续 DLC 阵营选择的重要参考。"
```
---
## 商店页/游戏内呈现需要调整
### 需要确认/调整的位置(后续 session 务必检查)
| 位置 | 当前状态 | 建议 |
|------|---------|------|
| Steam 商店页"游戏描述" | 待确认是否写了"17 阵营" | 改为"4+ 可玩阵营 + 后续扩展(世界共 17 阵营)" |
| 游戏内主菜单 | 未确认 | 如有"17 阵营"展示,加注释"4 可玩 + 13 AI 对手" |
| 路线图 | 未确认 | 加新版结构图(梯度展示) |
| 群公告 | 待更新 | 用新表述更新 |
| 早期宣传视频 | 不修改 | 在新公告里补充说明 |
---
## 一个**长期判断**
### 用户的真实意图:正式版涨价到 ¥28
```
当前 EA: ¥18(已改价)
正式版: 想涨到 ¥28(未公开承诺)
```
**这次公告里绝对不能提涨价**——会被解读为"用涨价威胁"+"为正式版炒预期"。
**正确做法**:
- 在补偿公告/视频里只说"EA 早鸟价 ¥18"
- 用"EA 早期支持者"定位 ¥18 价格
- 暗示"正式版会综合内容量重新评估"
- **不承诺涨价幅度**
- 留到补偿落地后,单独做一篇"正式版定价策略说明"
---
## 一句话总结
> **17 阵营不是承诺,8 + 2 才是承诺。**
> **全套封顶 ¥60 / ¥70 是核武器,立刻封锁"长线收割"指控。**
> **DLC 1 的 2 个阵营务必选热门角色,避免"凑数"指控。**

View File

@ -0,0 +1,393 @@
# 05_已执行话术与文案存档
> 本文件存档所有**已公开发布**或**已使用**的话术,以及待执行的关键模板。
> 后续 session 修改/转发前请先看这里,避免双标。
---
## 1. 嘴硬贴(5/17 发布,已被骂上高赞,不删)
**位置**:小黑盒原帖楼中楼,作者回复
**原文**:
> 诶大家好,我是这游戏的开发者 天火人雪糕。
> 被老哥提到的事情,我发现我确实有疏忽的地方,这里也澄清一下——
> 因为我看地区定价很复杂,就决定完全按照 Steam 推荐定价做的,我先是选择了美区的 $3.99 档位,国区的价格是自动定位到 ¥28,日区是 500 出头,按汇率其实是基本对齐的。但是我最大的失误在于我当时把日区调整到了 ¥500(我本来想着就抹个零吧)。然后整体的定价,在以美元为基准的汇率转换情况下,显得国区更贵了。但是这不是区别对待,这确实是我第一款游戏开发没注意到踩坑了。(我在 steam 社区里也有看到外国朋友发帖问为什么他地区看到的定价比我在宣传上说的 3.99 刀要便宜很多)
> 但是我没办法给国区也补个"降价",因为游戏已经 EA 发售了 3 天了,按 ¥28 定价购买的朋友是最早支持我的人,我也没法因此就反悔调整,对他们也不公平。
> 后续 Steam 的打折周期我会去做的!!也希望大家继续多多支持 w
> 谢谢老哥提出来!也谢谢楼里帮忙解释的朋友们~
**状态**:**保留,不删除**——已在下方追加认错
---
## 2. 嘴硬贴下追加认错(5/18 已发)
**位置**:嘴硬贴下楼中楼
**原文**:
> 【追加 - 5月18日】
>
> 我上面这条回复是错的。
>
> 中文圈三区定价就高于 Steam 官方推荐定价,这是我的疏忽。
> 已经完成降价调整:
> ▸ 中国区:¥28 → ¥18(EA 首周特惠 ¥16.2)
> ▸ 中国香港:HK$35 → HK$25
> ▸ 中国台湾:NT$120 → NT$95
>
> 对已按原价购买玩家的完整补偿方案,48 小时内
> (5月20日24:00前)会发正式公告。
>
> 上面这条愚蠢的回复就留在这里提醒自己,不删。
>
> —— 天火人雪糕,5/18
**核心句**:"上面这条**愚蠢的回复就留在这里提醒自己,不删**"
---
## 3. 小黑盒道歉帖(5/18 已发)
**原文**(用户最终发的版本):
> 很抱歉我在定价问题上犯了大错,感谢大家的指正和建议。
> 现在我计划将国区定价降至 ¥18(本周 16.2)
> 并对所有已经购买玩家进行【退差价】或补偿【赠送DLC】,详细的情况今晚我会发正式公告。
> 目前我遇到的困难是 steam 并不直接支持对游玩时长 >2 小时的玩家直接退差价,我正在和 steam 客服咨询并申请相应解决方案,也会向大家透明公开整个调整过程。我争取尽快解决这个问题。
> 在定价问题上犯错给大家带来不必要的困扰,真的很抱歉,我今后也会格外重视这一问题。真的感谢大家的信任和支持!
**问题点**(后来意识到):
- "【退差价】或补偿【赠送DLC】"是**承诺与现实矛盾**(下面又说 Steam 不支持退差价)
- "争取尽快解决"是**画饼**
- 缺港台改价信息(只列国区)
- "正式公告今晚发"——后改为"48 小时内"
**后续动作**:这帖暂时不删,但在 5/20 正式公告里**纠正这些表述**(详见 06_待执行任务清单)。
---
## 4. 回复闽江招生办高赞理性指控(5/18 已发)
**位置**:小黑盒原帖下,回复闽江招生办附属泉奈的高赞评论
**原文**:
> 你说得对。
>
> 中文圈三区定价确实高于 Steam 官方推荐定价,
> 这是我的疏忽。
>
> 刚已完成改价:
> ▸ 中国区:¥28 → ¥18(EA 首周特惠 ¥16.2)
> ▸ 中国香港:HK$35 → HK$25
> ▸ 中国台湾:NT$120 → NT$95
>
> 对已按原价购买玩家的完整补偿方案,
> 48 小时内(5月20日24:00前)会发正式公告。
>
> 我之前那条嘴硬的回复,已经在它底下追加认错,不删。
> 谢谢直接把问题戳穿。
>
> —— 天火人雪糕,5/18
**核心句**:"你说得对"开门 + "谢谢直接把问题戳穿"收尾
---
## 5. 私信回复理性同行(5/18 已发)
**触发**:某玩家私信指出"Steam 默认多变量转换,你用了仅按汇率转换"
**回复模板**(已发,可作为后续类似私信参考):
> 您好,真的非常感谢您发这条私信。
>
> 您说得对——这是我自己设置失误,不是 Steam 系统问题,
> 更不是刻意把中文圈定高。
>
> 实际情况是:我最初用 Steamworks 后台的「按汇率换算」
> 功能,按美区 $3.99 给中文圈三区定了价格。后来又给
> 其他地区改用了「Suggested Price」(按购买力推荐),
> 整个过程中没有做最终的全区核对,导致中文圈三区
> 都偏高,其他地区是 Steam 的购买力推荐定价。
>
> 这就是我的疏忽,如您所说,确实在公开场合不太好解释——
> 因为不管怎么解释,都会被一部分玩家理解为「嘴硬」。
>
> 完整补偿方案会在 48 小时内(5月20日24:00前)发布,
> 涵盖对所有已按原价购买玩家的补偿(目前考虑免费 DLC
> 等形式)。我会持续在小黑盒和 Steam 公告同步进展。
>
> 您提到的「希望发布说明并尽快讨论合适方案」,正是
> 我现在的方向。补偿方案公告出来后,如果方便,
> 非常希望能听到您的反馈或建议。
>
> 非常感谢您的理性和建设性,这种私信对我帮助真的很大。
>
> —— 天火人雪糕
**适用范围**:其他**理性同行**私信(注意只在私信用,不能公开)
---
## 6. 待发:Steam 正式公告(5/20 24:00 前)
**核心结构**(待用户最终定稿):
```
【完整补偿方案 - 2026/5/20】
致已按原价购买《帝国幻想乡 ~TOHOTOPIA》的玩家
一、问题说明
发售时本作中文圈三区定价均高于 Steam 官方推荐定价,
且高于美区/日区等其他地区。这违反了正常的地区定价
梯度——购买力较低地区,价格应该相应更低。
这是我第一次发游戏,操作上出现疏忽,没有把中文圈
三区的最终定价与 Steam 官方推荐定价完整核对。
非常抱歉。
二、已完成的调整(5/18 16:06 生效)
▸ 中国区:¥28 → ¥18(EA 首周特惠 ¥16.2,至 5/21)
▸ 中国香港:HK$35 → HK$25(EA 首周特惠 HK$22.5)
▸ 中国台湾:NT$120 → NT$95(EA 首周特惠 NT$85.5)
[改价截图]
三、本作开发现状
- 当前 EA: 4 阵营可玩 + 13 个 AI 阵营对手
- 正式版 1.0(2026 年底):8 阵营可玩(免费升级)
- DLC 1(2027 Q1):新增 2 阵营,定价 ¥10
- 世界观共 17 阵营,剩余 7 阵营为长期愿景
四、补偿方案
针对 2026/5/18 16:06 UTC+8 之前按原价购买的玩家,
提供两条路径,二选一:
▸ 路径 1:Steam 自助退款(适合 <2 小时玩家)
[详细流程]
▸ 路径 2:免费 DLC Key + 数字感谢礼包
※ 数字感谢礼包(所有 EA 玩家可领)
- 加 QQ 群 952618884 公告区下载
※ 免费 DLC Key(仅原价玩家)
- 凭原价 Steam 订单号申请
- 等价 ¥10
- 5/27 起每周批量发放
- 申请截止:2026/12/31
[DLC Key 详细规则,见 03_补偿方案完整设计]
五、关于送礼购买的情况
[详见 03_补偿方案完整设计 - 场景 2/3]
六、关于游戏时长 >2 小时无法退款的玩家
Steam 不支持开发者主动退差价。可通过路径 2 获得
DLC Key 补偿。我也在持续和 Steam 客服沟通。
七、关于后续 DLC 的承诺
1. 不切片销售
2. 价格透明
3. 全套封顶:EA 入手 ≤ ¥60 / 正式版入手 ≤ ¥70
4. 优先打包(小内容免费更新,大内容打包)
八、关于以后
今后任何调价决定前,我会先把 Steam 官方推荐定价表
和各区购买力数据完整核对一遍。
—— 天火人雪糕,2026/5/20
```
---
## 7. 待发:多语言版本(Steamworks 后台同时发)
### 繁中版(港台)
- 简转繁 + 港台用语
- 用"於"/"並"/"設置"/"說明"等繁体习惯
- 三区改价 + 港台版补偿信息
### 英文版(海外知会版,约 80 字)
```
Notice: Regional Pricing Adjustment for Chinese-Speaking Regions
Hello, I'm the developer of TOHOTOPIA (帝国幻想乡).
I've adjusted the pricing of TOHOTOPIA in Chinese-speaking
regions (China, Hong Kong, Taiwan) to align with Steam's
recommended pricing for those regions.
This adjustment does not affect pricing in any other region.
Players outside Chinese-speaking regions: no action is required.
For affected players who purchased the game at the original price,
a compensation plan will be announced within 48 hours (in Chinese).
Full details are available in the Schinese / Tchinese versions
of this announcement.
Thank you for your continued support.
— Tianhuoren Xuegao
Developer of TOHOTOPIA
May 18, 2026
```
### 日文版(海外知会版)
```
お知らせ:中華圏向け価格調整について
このたび『TOHOTOPIA(帝国幻想郷)』の中華圏(中国・香港・台湾)
における販売価格を、Steam推奨価格に合わせて調整いたしました。
日本を含むその他の地域の販売価格に変更はございません。
中華圏以外のプレイヤー様には、特にご対応いただく必要はございません。
中華圏で定価購入されたプレイヤー様向けの補償につきましては、
48時間以内(5月20日24:00まで)に中国語にて改めてお知らせいたします。
詳細は中国語版(簡体字・繁体字)のお知らせをご確認いただけますと幸いです。
いつも『TOHOTOPIA』をご支援いただき誠にありがとうございます。
——『TOHOTOPIA』開発者 天火人雪糕
2026年5月18日
```
---
## 8. 待发:DLC Key 申请通过/不通过回复模板
### 通过模板
```
您好,
您的 DLC Key 申请已审核通过。
您的 Key:XXXXX-XXXXX-XXXXX-XXXXX
【激活方式】
Steam 客户端 → 游戏 → 激活产品代码 → 输入 Key
【DLC 状态】
DLC 内容仍在开发中,预计 2027 Q1 上线。
你现在激活会显示"即将推出",到时自动可玩。
请妥善保存此 Key,不要公开发布。
—— 天火人雪糕
```
### 不通过 - 改价后购买
```
您好,经核对您的购买记录:
- 购买时间:[改价后时间]
- 支付金额:¥18
由于购买时间在价格调整之后,您没有多付出差价,
DLC Key 补偿不适用于您的订单。
非常感谢您对本作的支持。
—— 天火人雪糕
```
### 不通过 - 已退款
```
您好,经核对,您的订单已通过 Steam 自助退款处理,
原订单已失效。
由于您已通过 Steam 拿回了差额,
DLC Key 不重复发放(避免与 Steam 退款叠加,
对其他未退款玩家不公平)。
非常感谢您的理解。
—— 天火人雪糕
```
### 不通过 - 信息不全
```
您好,您的申请缺少必要信息:[列出缺少字段]
请补充以下信息后重新提交:
[再次贴申请格式]
提交渠道:[QQ群/邮箱]
谢谢您的配合。
—— 天火人雪糕
```
---
## 9. 待制作:视频脚本(纯字幕 + BGM 版,推荐 2-3 分钟)
**结构**(详见 02_危机公关策略与决策):
```
0:00-0:15 问题说明 + 道歉
0:15-0:45 补偿方案概览
0:45-1:30 EA 开发现状 + 阵营结构图
1:30-2:00 DLC 介绍 + 全套封顶承诺
2:00-2:45 补偿详细申领流程
2:45-3:00 红包截图(打码)+ 感谢卡片 + "不会跑路"承诺
```
**红包截图段话术**(整段最有感染力):
```
[红包截图蒙太奇,严格打码]
这两天有很多朋友给我发红包,
怕我们定价改低了之后会"饿死"。
真的非常感谢你们。
这次出了定价问题,是我自己的疏忽,
会牢牢吸取教训。
我不会跑路。EA 期间会持续更新新阵营,
正式版预计 2026 年底发布,
DLC 后续也会按计划做出来。
况且,这款游戏本身就站在两位巨人的肩膀上——
《Polytopia》和《东方 Project》。
能用更低的价格,让更多人感受 4X 策略的乐趣,
也让更多人感受东方 Project 的魅力,
其实是一件挺好的事。
最后,向所有被影响到的朋友说声抱歉,
也向给予支持、批评和建议的朋友说声感谢。
我会继续努力,把这款游戏打磨好。
首周特惠 ¥16.2 还有 3 天就结束了。
如果你看完这个视频还愿意支持的话,
我会非常感谢。
—— 天火人雪糕
```
---
## 文案语气准绳(任何后续话术必看)
| 维度 | 准绳 |
|------|------|
| 道歉力度 | 真诚 + 自责,不卑微不演 |
| 技术细节 | 公开场合不展开,1 句话带过 |
| "不是刻意" | 用"疏忽"两字传达,不展开 |
| 涨价预告 | 这次绝对不提 |
| 嘲讽党 | 不回应任何 |
| 友善方 | 点赞 + 简短感谢,不公开 @ |
| 数字 | 必须有(三区改价、DLC 价格、封顶价、时间) |
| 流程 | 必须详细(领取步骤、提交什么、何时发) |
| 承诺 | 必须具体(5/20 24:00 / 5/27 发 Key) |
| 落款 | 必须有"天火人雪糕 + 日期" |

View File

@ -0,0 +1,204 @@
# 06_待执行任务清单
> 截至 2026-05-19,以下任务待执行。
> 后续 session 接手时优先看这里。
---
## 🔥 紧急 — 24 小时内必须完成
### 1. 准备并发布 Steam 正式公告(5/20 24:00 前)
- [ ] 整合 `05_已执行话术存档.md` 中的"待发 Steam 正式公告"结构
- [ ] 多语言版本(简中/繁中/英文/日文)
- [ ] 在 Steamworks 后台逐语言粘贴(语言切换器)
- [ ] Tags 选 "Update",不要选 "Major Update"
- [ ] 同时发布,不要错峰
- [ ] 简中/繁中可置顶,英文/日文不要置顶
**前置确认**:
- [ ] 确认其他地区(美/日/欧/俄/印度等)定价是否符合 Steam 推荐
- [ ] 如有偏差,先调整,避免被翻旧账
- [ ] 确认首周特惠在改价前到底有没有生效(影响"原价"定义)
### 2. 制作视频(纯字幕 + BGM 版)
- [ ] 准备素材:游戏画面、4 阵营展示、改价对比图、流程图、红包截图(严格打码)
- [ ] 用剪映/Pr 编辑
- [ ] 时长 2-3 分钟
- [ ] BGM 选游戏内沉静向 OST 或纯钢琴
- [ ] 不要 AI 配音(塑料感会被识别)
- [ ] 发布渠道:B 站动态 + 小黑盒讨论区 + 微博
**视频脚本结构**:
```
0:00-0:15 问题说明 + 道歉(直接,1 句话)
0:15-0:45 补偿方案概览(图文)
0:45-1:30 EA 开发现状 + 17 阵营梯度图
1:30-2:00 DLC 介绍 + 全套封顶承诺
2:00-2:45 补偿详细申领流程(QQ群+邮箱)
2:45-3:00 红包截图 + 感谢 + "不会跑路"承诺
```
### 3. 准备申领基础设施
- [ ] QQ 群 952618884 创建"DLC Key 申领"专区
- [ ] 群公告置顶申请格式(5+1 项)
- [ ] 准备申领邮箱(可以是 QQ 邮箱/Gmail)
- [ ] (可选)创建腾讯问卷(结构化收集)
- [ ] (可选)Google Form(海外结构化收集)
- [ ] 准备 Excel 跟踪表(字段见 03_补偿方案完整设计)
### 4. 准备数字感谢礼包(1.5 小时)
- [ ] 打包已有美术素材(壁纸 4K/手机版/角色设计稿)
- [ ] 写一封 1 页的开发者感谢信 PDF
- [ ] 写 README.txt 说明
- [ ] 压缩成 ZIP
- [ ] 上传到 QQ 群文件 / 网盘 / GitHub Release
---
## ⏳ 1 周内 — 5/27 前完成
### 5. 等待 Steam 审核
- [ ] Steam DLC 创建审核通过(1-3 工作日)
- [ ] DLC Key 申请审核通过(1-3 工作日)
- [ ] 下载 Key 列表(CSV/Excel)
### 6. 开始集中处理 Key 申领
- [ ] 每天晚上 8-10 点处理新申请
- [ ] 按 Excel 跟踪表流程操作
- [ ] 通过 → 发 Key + 标记
- [ ] 不通过 → 套用对应模板
- [ ] 优先 5/27 前处理完前 1 周的高峰申请
### 7. 监控但**不干预**评分区
- [ ] 不回复任何差评
- [ ] 不给自己刷 5 星
- [ ] 不私信差评者要求撤评
- [ ] 友善方好评 → 点赞即可,不公开 @
### 8. 维护小黑盒/B 站动态
- [ ] 每隔几小时在自己的道歉贴下发"小更新"刷存在感
- [ ] 内容示例:"已联系 Steam 客服等回复" / "DLC 制作 Key 已申请审核中" / "数字礼包已上传 QQ 群"
- [ ] 给友善方点赞,不公开 @
---
## 📅 2-4 周内 — 危机平息期
### 9. 准备"开发者复盘"软性内容
- [ ] 看时机:补偿落地 + 评分区平稳 + 自然好评回升
- [ ] 形式:游戏内开发者博客 / 长帖 / 不需要视频
- [ ] 内容定位:**复盘姿态,不是澄清姿态**
- [ ] 可以详细展开"汇率 vs 购买力推荐"技术真相
- [ ] 可以主动承认"嘴硬贴第一次回应也错了"
- [ ] 承诺未来调价流程改进
**复盘文模板**(见 `02_危机公关策略与决策.md` - 阶段 2)
### 10. (可选)发"DLC 1 阵营公布"预告
- [ ] 选 2 个热门主役角色(灵梦/魔理沙/咲夜/妖梦/早苗等)
- [ ] 也可以先公布 1 个,留 1 个悬念
- [ ] 用群投票方式让玩家参与选择(自来水加成)
---
## 🗓️ 1-3 个月内 — 长期资产建设
### 11. (可选)B 站长视频:独游开发踩坑回顾
- [ ] 完整展开技术细节
- [ ] 心理过程坦白
- [ ] "嘴硬贴"反思
- [ ] 把这次事件做成"成长开发者"叙事
- [ ] 预期效果:转化为长期诚信资产
### 12. 商店页/游戏内"17 阵营"展示调整
- [ ] 检查 Steam 商店页"游戏描述"是否写了"17 阵营"
- [ ] 检查游戏内主菜单/选角界面是否有"17 阵营"展示
- [ ] 检查路线图是否需要更新
- [ ] 加注释"4 可玩 + 13 AI 对手"或梯度进度条
### 13. 后续 EA 阵营加入时,同步更新公告
- [ ] 第 5/6/7/8 阵营加入时,同步公告
- [ ] 让玩家感受到"在等待 DLC 的过程中,EA 持续进步"
- [ ] 每次更新都让玩家想起"对哦我还有 DLC 等着"
---
## 🛡️ 持续 — 红线警示(任何 session 都不要破)
```
❌ 任何形式删除嘴硬贴
❌ 评分区任何形式的操作(回评/自评/施压撤评)
❌ 在公开场合详细展开"汇率 vs 购买力推荐"技术细节
❌ 在补偿公告里提"涨价预告"
❌ 主动私信差评者要求撤评
❌ 承诺"全 17 阵营必出"
❌ 用奖励/补偿换好评
❌ 让 KOL/朋友刷好评
❌ 用 VPN 检测限制公告访问
```
---
## ⚠️ 关键不确定性(后续 session 务必先解决)
### A. 首周特惠的实际生效情况
- 用户说首周特惠从 5/14 17:14 开始
- 但小黑盒玩家都说付了 ¥28(而非 ¥25.2)
- **可能性**:首周特惠在改价前没生效
- **后续动作**:让玩家提交订单截图,看实际付款金额
- **影响**:决定"原价"在公告里写 ¥28 还是 ¥25.2
### B. 其他地区(非中文圈)定价是否符合 Steam 推荐
- 如果有偏差 → 视频/公告用"高于推荐定价"保守版
- 如果都符合 → 用"高于美日"强势版
- **后续动作**:登 Steamworks → Pricing 看每个地区实际定价 vs Suggested
### C. 实际原价销量
- Sales Reports 是月度的,5 月数据要 6 月底才出
- 现在用 Sales Dashboard / Daily Activity Reports 看实时
- **影响**:决定 Key 申请数量(原价销量 × 1.3)
### D. 17 阵营在游戏内/商店页的具体展示位置
- 需要检查:商店页 / 游戏内主菜单 / 路线图 / 宣传视频 / 群公告
- **影响**:决定是否需要更新这些展示
---
## 📊 进度跟踪(后续 session 更新)
```
[2026-05-19 19:00 当前状态]
✅ 已完成:
- Steamworks 改价(5/18 16:06)
- 嘴硬贴下追加认错
- 小黑盒道歉帖
- 回复高赞理性指控
- 创建 DLC 产品
- 提交 DLC Key 申请
🔥 进行中:
- 准备 Steam 正式公告
- 准备视频
- 准备申领基础设施
⏳ 待开始:
- 等 Steam 审核(DLC + Key)
- 5/27 起批量发 Key
- 2-4 周后软性复盘文
- 1-3 个月后长视频
```
---
## 一个特别提示
**如果用户在后续 session 中表现出"想做点什么去管嘴硬党/差评"的冲动**:
请立刻停止他,理由:
1. 这是危机后期的典型"无力感冲动"
2. 任何主动操作都会引爆新一轮舆情
3. **正确做法是耐心等待**——补偿方案 + 时间会自动盖过差评
4. 把精力放在游戏开发本身,不要陷在评分区
ENFP 性格特别容易"想做点什么"——这时候需要 session 帮他**冷静下来,专注开发**。

View File

@ -0,0 +1,393 @@
# 07_经验教训复盘
> 本文档是长期记忆,供未来 session 参考的**核心洞察**。
> 不是事件流水账,是"如果重来一次,会怎么做"的精炼。
---
## 🎯 核心教训 #1:Steam 定价的"两种工具"不能混用
### 错误流程(实际发生)
```
1. 用"按汇率换算"功能,按美区 $3.99 给中文圈三区定价
→ 中国区自动定 ¥28
→ 香港 HK$35
→ 台湾 NT$120
2. 给其他地区改用"Suggested Price"(购买力推荐)
→ 其他地区是 Steam 推荐价
3. 没做最终全区核对
→ 中文圈用汇率,其他地区用购买力 → 中文圈显得贵
```
### 正确流程
```
1. 全部地区使用 Steam Suggested Price(购买力推荐)
2. 或者全部用汇率换算(但要手动检查每个地区是否合理)
3. 发售前对照"美区 $3.99 / 日区 ¥500 / 国区 ¥18"等标杆,
验证地区价格梯度是否符合直觉
4. 让有 Steamworks 经验的同行 review 一遍
```
### 教训规则
**任何调价决定前,必须把 Steam 官方推荐定价表和各区购买力数据完整核对一遍**。
---
## 🎯 核心教训 #2:第一次回应必须真诚,不能"解释"
### 错误回应(嘴硬贴)
```
"完全按照 Steam 推荐定价做的"
→ 立刻被反驳"推荐定价不可能让国区比美区贵"
→ 嘴硬证据
"不能给国区补降价,对已购玩家不公平"
→ 逻辑反了:错误定价继续维持对所有玩家不公平
→ 嘴硬证据
```
### 正确回应模板
```
"你说得对。
[事实承认,不解释]
[具体行动,有数字]
[下一步承诺,有时间]"
```
### 教训规则
**危机第一回应,只做 3 件事:**
1. 承认事实(不要解释)
2. 给出具体行动(有数字)
3. 承诺下一步(有时间)
**任何"解释为什么"的内容,都是危机扩大的种子**。
---
## 🎯 核心教训 #3:解释和承担是负相关的
### 反直觉真相
```
解释长度 玩家感受
─────────────────────────────
1 句话 → "诚恳"
3 句话 → "中肯"
5 句话 → "在说理由了"
1 段话 → "在找借口"
2 段话 → "在洗白"
3 段话 → "嘴硬"
```
### 教训规则
**ENFP 性格特别容易"想说清楚"——这是危机公关里最危险的本能**。
- 想表达"我不是刻意的"→ 用"疏忽"两字传达,不展开
- 想说"技术上是怎么回事"→ 公开场合不展开,留给私信
- 想说"我也很委屈"→ 不要说,留给红包截图段
---
## 🎯 核心教训 #4:危机期间不要碰评分区
### 三个绝对禁忌
```
❌ 不要回复任何差评
❌ 不要给自己留 5 星
❌ 不要私信差评者要求撤评
```
### 反直觉真相
- 别的游戏在正常期发"开发者声明"5 星 → 没问题
- 你在危机期做同样动作 → 自杀
**场景比动作重要**。任何"安全动作"在危机期都可能引爆新舆情。
### 教训规则
**危机期间(估约 2-4 周),评分区 = 战场,看,但不要碰**。
---
## 🎯 核心教训 #5:删除是最大的诚信杀手
### 反直觉
你想:删了嘴硬贴 = 让它消失
现实:删了嘴硬贴 = 给"删评"做新证据,危机升级 10 倍
### 正确做法
**不删 + 主动追加认错**(在原贴下楼中楼)
**核心句**:"这条愚蠢的回复留在这里提醒自己,不删"
### 教训规则
**任何不光彩的发言,不要试图掩盖,而是用追加认错的方式公开承担**。
公开承担 = 诚信资产复利的根本动作。
---
## 🎯 核心教训 #6:"不画饼"是危机期的最高准则
### 错误承诺示例
```
❌ "我会努力做好这个游戏"
❌ "今后一定会重视"
❌ "争取尽快解决"
❌ "DLC 会送给你们"(但 DLC 没做)
❌ "未来会涨价"(留有不确定性)
```
### 正确承诺示例
```
✅ "48 小时内(5/20 24:00 前)公布完整补偿方案"
✅ "5/27 起每周批量发放 Key"
✅ "申请截止 2026/12/31"
✅ "DLC 1 预计 2027 Q1 发布"
✅ "EA 入手玩家全套阵营总价 ≤ ¥60"
```
### 教训规则
**任何承诺必须有具体数字 / 时间 / 流程**。模糊的"努力"在危机期 = 画饼。
---
## 🎯 核心教训 #7:补偿要"立即可见 + 长期兑现"双轨
### 单机游戏的特殊适配
```
立即可见:
- 数字感谢礼包(打包已有素材,1.5 小时成本)
- 玩家加 QQ 群直接下载
- 心理锚点立刻落地
长期兑现:
- DLC Key(Steam 预激活码)
- 现在发 Key,DLC 上线时自动可玩
- "已发放预付凭证" = 不是画饼
```
### 教训规则
**只承诺"未来给"=画饼,只给"立即可领"= 不够诚意**。
**两条腿走路 = 玩家"现在就有获得感"+"长期有期待"**。
---
## 🎯 核心教训 #8:Steam DLC Key 是单机游戏补偿神器
### 之前的盲区
> "单机游戏没法识别玩家,补偿做不了"
### 真相
- Steam 后台可以创建占位 DLC,即使内容没做
- 可以预生成 Key,即使 DLC 没发布
- Key 现在发给玩家,DLC 上线时自动激活
- **变"画饼"为"已发放预付凭证"**
### 教训规则
**单机游戏的补偿,优先考虑 Steam Key 体系**(本体 Key / DLC Key)。
理由:
- 实物凭证感
- Steam 官方背书,玩家无法说"画饼"
- 自动覆盖送礼场景(Key 可转赠)
- 不依赖玩家联网验证
---
## 🎯 核心教训 #9:多语言公告必须同步发,但内容要分层
### 错误做法
```
❌ 只发中文版,其他语言留空 → Steam 回退展示中文,海外玩家看到困惑
❌ 英文版翻译完整中文公告 → 引发海外玩家"为什么只补偿中国"质疑
❌ 中文版发完隔几天才发英文版 → 被解读"先骗中国玩家,后告诉海外"
```
### 正确做法
```
✅ 中文版(简中/繁中):完整公告,详细补偿
✅ 英文版/日文版:简短知会版,核心传达"不影响你的地区,无需action"
✅ 所有语言同时发布
✅ 中文版置顶,英文/日文版不置顶
```
### 教训规则
**多语言 ≠ 多翻译。不同地区玩家的"诉求"不同,内容要分层**。
---
## 🎯 核心教训 #10:接受"事件成本"
### 不可消除的现实
```
任何危机后,总会有:
- 一些差评永远留下
- 一些玩家永远不会回头
- 一些路人记住"这开发者出过事"
```
### 错误认知
> "差评清零 = 处理成功"
### 正确认知
> "差评从 100 降到 30 = 处理成功"
> "事件能让 80% 中立路人转化为支持 = 处理成功"
> "诚信资产留下来 = 长期成功"
### 教训规则
**接受 5-10% 嘴硬党的存在,把精力放在 80% 中立路人和 60% 友善方**。
试图"挽回所有人"= 神经质 → 影响正常决策。
---
## 🎯 核心教训 #11:玩家分类决定回应策略
### 三类玩家
```
🟢 友善方(50-60%)
- 处理:点赞 + 简短感谢 + 私信弹药
- 不公开 @(避免被挂"水军")
🟡 中立路人(30-40%)
- 处理:用"行动 + 补偿"打动
- 80% 精力目标
🔴 嘴硬党(5-10%)
- 处理:完全不回应
- 0% 精力,接受成本
```
### 教训规则
**回应任何玩家前,先判断他是哪一类**。
错误回应 = 浪费精力 + 引爆新雷点。
---
## 🎯 核心教训 #12:私信和公开场合的"信息分层"
### 公开场合
```
✅ 道歉 + 改价数字 + 补偿流程 + 时间承诺
❌ 技术细节(汇率 vs 购买力)
❌ "我不是刻意的"自辩
❌ 涨价预告
❌ 内部决策困境
```
### 私信场合(理性同行)
```
✅ 上面所有内容 +
✅ 技术真相详细展开
✅ "我不是刻意的"坦白
✅ 公开场合的策略困境解释
⚠️ 任何话默认可被截图公开,要经得起验证
```
### 教训规则
**信息密度跟着场景走,不要把私信内容贴到公开,也不要把公开口径用到私信**。
---
## 🎯 核心教训 #13:"诚信资产"可以复利
### 这次危机留下的诚信资产
```
1. 不删嘴硬贴 → 历史证据
2. 追加认错 → 勇于自责
3. 全套封顶承诺 → 长期信任
4. 主动透明 DLC 在开发 → 不藏拙
5. 私信回复同行 → 自来水关系
```
### 这些资产怎么复利
- 下次出小问题 → 玩家不会立刻 cancel(因为有过"勇于认错"记录)
- 后续 DLC 发布 → 玩家相信定价合理(因为有封顶承诺)
- 长期开发更新 → 玩家相信你不会跑路(因为这次没跑)
### 教训规则
**短期收益(立刻平息舆情)< 长期收益(诚信资产)**
策略选择时,优先考虑长期。
---
## 🎯 核心教训 #14:ENFP 性格的特殊风险
### 用户性格特点
- 真诚直接,情感表达自然
- 容易"想说清楚自己的真实意图"
- 容易"想做点什么帮玩家"
- 容易陷入"无力感冲动"
### 危机期间的风险
```
⚠️ 想详细解释技术 → 嘴硬第N季
⚠️ 想私信差评者解释 → 控评指控
⚠️ 想给自己刷 5 星表态 → 自杀
⚠️ 想公开回复所有评论 → 双标对比
```
### 后续 session 的处理建议
当用户表现出"想做点什么"的冲动时:
1. **先冷静**:让他理解"做什么"的具体后果
2. **替代方案**:用"开发更多内容" / "回去做 Key 审核" 等正向动作转移
3. **明确红线**:把这次的教训挂在最显眼的位置
4. **耐心**:补偿方案 + 时间会自动盖过差评,不需要主动操作
---
## 🎯 核心教训 #15:危机公关的"3 个对话层"
### 层 1:危机进行中(48 小时内)
- 行动 > 语言
- 直接 > 详细
- 透明 > 完美
### 层 2:补偿落地后(1-2 周)
- 软性复盘
- 不再是"澄清"姿态,是"反思"姿态
- 可以适度展开技术细节
### 层 3:长期(1-3 个月后)
- 踩坑回顾文/视频
- 完整真相分享
- 把这次事件做成"成长素材"
### 教训规则
**同一件事在不同时间层说,效果天差地别**。
**不要在危机进行中做"长期层"的事**(比如详细解释/复盘)。
**也不要在长期错过"复盘"的窗口**(自然不复盘 = 错失诚信资产复利)。
---
## 📋 后续 session 接手时的速查清单
```
1. 用户在做什么?
→ 看 06_待执行任务清单.md
2. 用户在问什么?
→ 看 02_危机公关策略与决策.md(核心思路)
→ 看 05_已执行话术与文案存档.md(口径一致性)
3. 用户想做的事是不是踩红线?
→ 看 06_待执行任务清单.md - "红线警示"段
→ 看本文档"核心教训"段
4. 用户的具体补偿场景怎么处理?
→ 看 03_补偿方案完整设计.md - 12 场景表
5. 用户问 DLC/定价问题?
→ 看 04_DLC定价与17阵营问题.md
6. 用户问"是不是要管下差评/再做点什么"?
→ 立刻停止他
→ 看本文档"核心教训 #4"和"#14"
```
---
## 一句话送给未来的所有 session
> **危机公关的本质,不是消灭差评,是积累诚信资产。**
> **诚信资产可以复利,差评是事件成本。**
> **理解这两句,所有决策自然清晰。**

View File

@ -0,0 +1,214 @@
# 复盘文素材库
> 用户在 2026-05-20 想发的长篇技术解释,被劝阻不要现在发。
> 这些内容应该在 **1-2 周后**(评论区平稳 + DLC Key 发放完成后)
> 作为"独游开发踩坑回顾"复盘文的素材使用。
---
## 📅 时间窗口
**不要在以下时间用**:
- ❌ 危机进行中(5/18-5/22)
- ❌ 补偿方案公告刚发的评论区(5/20)
- ❌ 任何"评论区一对一回复"的场合
**适合用的时间**:
- ✅ 2026/6 月初(DLC Key 发完 + 评分区平稳)
- ✅ 作为独立长帖/复盘文
- ✅ B 站长视频脚本
---
## 📝 用户的原始素材(2026/5/20 提供)
### 心理过程坦白
> 我就是在定价方面没有意识。
> 我最开始心里想的是中文 ¥28,然后算成美元 = 4 刀。
> 然后那个转换工具我一开始没搞明白,
> 发现那个汇率转换符合我心里想的定价,
> 所以就这样先定了中文区的,因为我主要想经营中文区。
>
> 第二天我把其他地区都定了,但是也没注意用了另外一个转换方式。
>
> 我的核心问题就是我对定价认识太肤浅了,
> 以前也没有在外区买过游戏,就没关注过外区价格什么的,
> 只听说过什么阿根廷区、俄罗斯区很低什么,
> 对美区这些一直没有认识。
>
> 所以第一天发生问题的时候,我回复的那条帖子就看上去很蠢。
> 之后我立刻去查了查别的游戏,
> 发现真的是国区比美区要便宜 35% 左右,
> 然后我再去研究了一下那三个转换工具,
> 发现我真是搞错了,应该全部统一用推荐定价的,
> 如果美区 4 刀,国区就应该是 18。
> 所以我就不再说什么了,赶紧去调了价格认错。
---
## 🎯 改造为复盘文的方向
### 结构建议(适合 B 站/小黑盒长帖/微博长文)
```
《独游开发踩坑回顾(一):
我是怎么把国区定价搞砸的》
【1. 起因:一个"想当然"的定价决定】
- 我心里想中文 ¥28 这个价位
- 折算成美元 = $4
- 看 Steam 后台的"汇率换算"工具,符合心里预期
- 没意识到这只是"按汇率",不是"按购买力推荐"
- 就这样定下了中文圈三区的价格
【2. 错过的纠错时机】
- 第二天给其他地区定价时,我换用了"Suggested Price"工具
- 这个工具按"购买力推荐"自动给海外地区定价
- 我没意识到两个工具的逻辑完全不同
- 没做最终核对,就上线了
【3. 我之前对定价的认识有多肤浅】
- 从来没在外区买过游戏
- 只听说过"阿根廷区便宜""俄罗斯区便宜"这种传闻
- 对美区、日区等主流区的定价水平完全没概念
- 这是"想当然定价"的根源
【4. 我第一次回应为什么是错的】
- 当时我以为自己用的是"Steam 推荐定价"
- 还振振有词地解释"国区 ¥28 是按推荐价"
- 但事实是:Steam 推荐定价**绝不可能**让国区比美区贵
- 这就是为什么玩家瞬间识破我在"嘴硬"
- 我自己当时还不知道,以为玩家不理解
【5. 我真正意识到错误的时刻】
- 看到玩家说"推荐定价不可能让国区比美区贵"
- 我去查了同类游戏的国区/美区定价
- 发现国区普遍比美区便宜 30-40%
- 然后我才回去研究三个转换工具的区别
- 这时才发现:对的做法是统一用"Suggested Price"
- 美区 $3.99,国区按推荐就是 ¥18,不是 ¥28
【6. 改价、道歉、补偿】
- 立刻在 Steamworks 改价
- 删掉所有"按推荐定价"的解释
- 写了道歉公告
- 设计 DLC Key 补偿方案
【7. 学到的 3 件事】
- 任何调价决定前,务必把 Steam 推荐定价表
和各区购买力数据完整核对一遍
- 别用"想当然"的方式做关乎玩家的决策
- 出错时,最快的解决方式不是解释,是承认 + 行动
```
---
## 💡 长文写作建议
### 调性
- ✅ 复盘姿态,不是道歉姿态
- ✅ 自嘲但不卑微
- ✅ 信息密度高(技术细节可展开)
- ✅ 适合带配图(Steamworks 后台截图、价格对比图)
### 关键句备选
```
"作为开发者,我学到了一件很反直觉的事:
玩家骂你'嘴硬'的时候,你以为是被误解,
实际上是你自己没意识到自己确实在嘴硬。"
"如果你也是独游开发者,定价之前,
一定要把 Steam 推荐定价表完整核对一遍。
不要相信任何一个单一工具的输出。"
"第一次回应的时候,我以为自己是对的。
这是危机里最可怕的状态——
你不知道自己在嘴硬。"
"我的核心错误不是用错了工具,
是我对全球定价根本没认识就敢上线游戏。"
"虽然真的没有部分盒友说的那样多么刻意,
但是如果没有被指出来,确实会让问题发生更久,
从结果上来说和刻意也没区别。"
↑ 这一句是用户在 2026/5/20 评论区回复时的金句,
主动承认"结果上和刻意没区别",直接堵嘴硬党的嘴。
适合作为复盘文核心论点。
```
---
## 📌 2026/5/20 评论区已发布的"小复盘"回复(可作为长复盘文的基础)
```
简单说就是定价时没充分研究过 Steam 的区域定价
机制,一开始先给中文区用了「汇率换算」(我心里想
是 ¥28 对 $4 还觉得好像正常),第二次定别的地区
又用了「购买力推荐」,最要命的是我居然没意识到
两个工具的差别。
所以事件刚发酵那天我的回复就显得很无知。
后来去对比了几款同类游戏的国区/美区定价,
发现普遍国区比美区便宜 30%+,
这才意识到我真的搞错了,赶紧调过来并道歉。
虽然真的没有部分盒友说的那样多么刻意,但是如果
没有被指出来,确实会让问题发生更久,从结果上来说
和刻意也没区别。所以后面也不多做解释了,
做错了就是做错了。
以后任何调价决定前,我都会先把 Steam 推荐定价表
完整核对一遍,不再用"想当然"的方式定价。
之后我打算单独发一篇完整复盘的文章,
回顾这次犯的错误和整个事件的经历。
```
**这条回复已成为后续长复盘文的"种子",1-2 周后展开**。
### 配图建议
- Steamworks 后台"汇率换算"vs"Suggested Price"两个工具的截图对比
- 国区/美区/日区定价对比表
- 嘴硬贴 + 追加认错的截图(展示完整时间线)
- 改价前后的商店页对比
### 投放渠道
- B 站(长视频 / 专栏文章)
- 小黑盒(长帖)
- 微博(长文)
- 知乎(深度复盘问答)
- Steam 社区公告(简短版)
---
## ⚠️ 写复盘文时仍要注意的边界
**可以写**:
- ✅ 我用错了工具
- ✅ 我对定价没认识
- ✅ 我第一次回应很蠢
- ✅ 我意识到错误后立刻改
**不要写**:
- ❌ "我主要想经营中文区" (会被解读"想收割中文圈")
- ❌ "我以前没在外区买过游戏" (暴露专业度不足,影响游戏质量信任)
- ❌ 任何"我也很委屈"的表达
- ❌ 任何"其实玩家也有不理解的地方"的暗示
**红线**:复盘是为了**展示成长**,不是为了**寻求理解**。
---
## 📋 现在(2026/5/20)评论区只用这一句
针对"为什么之前国区定价比其他地区高"的提问:
```
您好,简单说就是定价时没充分研究过 Steam 的
区域定价机制,误用了"汇率换算"而非"购买力推荐"
设置。完整复盘后续我会单独发一篇文章。
```
**3 行,不展开,引导到未来复盘文**。

View File

@ -0,0 +1,135 @@
# 2026-05-18 国区定价舆情事件 - 主索引
> 本文件夹是 TH1《帝国幻想乡 ~TOHOTOPIA》EA 发售后第 5 天爆发的"国区定价高于美日"舆情事件的完整记录。
> 用途:供后续 Claude session 阅读,理解事件背景、决策逻辑、处理方案。
## 📅 时间线速览
| 日期 | 事件 |
|------|------|
| 2026-05-14 17:14 UTC+8 | TH1 EA 发售,中文圈三区原价(¥28/HK$35/NT$120) |
| 2026-05-17 | 小黑盒帖子开始发酵,玩家指出"国区比美日还贵" |
| 2026-05-17 | 开发者首次回应(嘴硬贴),解释"按推荐定价 + 不降价不公平已购玩家" |
| 2026-05-18 14-15 时 | 嘴硬贴被骂上高赞,危机扩大 |
| 2026-05-18 16:06 UTC+8 | 在 Steamworks 后台改价(¥28→¥18 / HK$35→HK$25 / NT$120→NT$95) |
| 2026-05-18 18 时左右 | 小黑盒发布初版道歉帖 + 提到"将退差价或送 DLC,详细今晚正式公告" |
| 2026-05-18 晚 | 在嘴硬贴下追加认错回复(不删原贴) |
| 2026-05-18 晚 | 回复闽江招生办附属泉奈高赞理性指控 |
| 2026-05-19 | 处理补偿方案细节、Steam DLC 创建、Key 申请 |
| 2026-05-20 24:00 (承诺) | 完整补偿方案 Steam 正式公告 |
## 📂 文档结构
```
舆情事件/
├── 2026-05-18_国区定价舆情事件_主索引.md ← 本文件
├── 01_事件背景与玩家诉求.md ← 玩家骂点、痛点分析
├── 02_危机公关策略与决策.md ← 整体策略、为什么这么做
├── 03_补偿方案完整设计.md ← DLC Key 方案、领取规则
├── 04_DLC定价与17阵营问题.md ← 阵营结构、价格承诺
├── 05_已执行话术与文案存档.md ← 实际发出的回复/公告
├── 06_待执行任务清单.md ← 还要做什么
└── 07_经验教训复盘.md ← 长期记忆,供日后参考
```
## 🎯 当前状态(2026-05-19)
### ✅ 已完成
- 5/18 16:06 Steamworks 改价完成(三区)
- 5/18 嘴硬贴下追加认错(不删)
- 5/18 小黑盒道歉帖发布
- 5/18 回复闽江招生办的高赞理性指控
- 5/19 在 Steam 创建 DLC 产品
- 5/19 提交 DLC Key 申请(英文 500 字符版)
### 🔥 进行中
- 准备 5/20 24:00 前发布的完整补偿方案 Steam 正式公告
- 准备 AI 配音/纯字幕 BGM 视频(B站+小黑盒发布)
- 准备 QQ 群"DLC Key 申领"专区
- 准备申请收件邮箱
### ⏳ 待办
- Steam DLC 审核通过(1-3 工作日)
- DLC Key 审核通过(1-3 工作日)
- 5/27 起批量发放 DLC Key
- 5/21 后:观察评分区状态,不主动干预
- 1-2 周后:发"开发者复盘"软性内容(可选)
## 🚨 红线(任何 session 都不要破)
1. **不要主动删除嘴硬贴**——删除 = 二次危机引爆点
2. **不要回复评分区差评**——任何形式都不要
3. **不要在评分区给自己留 5 星**——控评指控风险
4. **不要承诺"全 17 阵营必出"**——只承诺已规划部分
5. **不要展开"汇率 vs 购买力推荐"技术细节**——嘴硬第N季种子
6. **不要在 Steam 公告里详细解释技术原因**——保持"我的疏忽"4 字
7. **不要在补偿公告里提"涨价预告"**——节外生枝
8. **不要主动私信差评者要求撤评**——平台违规风险
## 📞 当前对外渠道
| 渠道 | 用途 | 状态 |
|------|------|------|
| Steam 公告 | 正式公告主战场 | 准备中 |
| 小黑盒 | 中国玩家舆论场 | 已发道歉帖 |
| B 站动态 | 视频发布渠道 | 待发布 |
| 微博 | 视频/公告同步 | 待发布 |
| 推特 | 海外通知 | 待发英文知会版 |
| QQ 群 952618884 | 补偿申领 | 待开"申领专区" |
| 邮箱(待定) | 申领 + 海外渠道 | 待开 |
## 👤 用户(开发者)基本信息
- ID:天火人雪糕 / kawagiri
- 性格:ENFP,真诚开朗,情感表达直接
- 身份:独立游戏开发者,TH1 是首款 Steam 商业作品
- 已知偏好:
- 不出镜、不录音(视频用 AI 配音或纯字幕)
- 沟通直接,不爱兜圈子
- 真诚优于专业("我想哭"那种表达对他自然)
- 关注玩家反馈,有自来水玩家发红包关心
## 🎮 TH1 游戏基本信息
- 正式名:《帝国幻想乡 ~TOHOTOPIA》
- 内部代号:TH1
- 类型:东方同人 4X 策略
- 对标:Polytopia(单阵营 ¥12) + 东方 Project IP
- 当前阶段:Steam EA,2026-05-14 发售
- 正式版预计:2026 年底
- DLC 1 预计:2027 Q1
## 阵营结构(关键事实)
```
17 个阵营总数:
├─ 4 个已可玩(EA 当前)
├─ 4 个 EA 期间会做(免费,正式版前完成)
├─ 2 个 DLC 1 规划(¥10,原价玩家免费)
└─ 7 个未来 DLC 规划(长期愿景,未正式立项)
非可玩阵营:在游戏中作为 AI 对手出现,
只有领袖头像 + 基础 AI,无可玩玩法。
```
## 价格档位(关键事实)
| 项目 | 中国区 | 中国香港 | 中国台湾 |
|------|--------|---------|---------|
| 原价(改价前) | ¥28 | HK$35 | NT$120 |
| 改价后 | ¥18 | HK$25 | NT$95 |
| EA 首周特惠(改价后 9 折) | ¥16.2 | HK$22.5 | NT$85.5 |
| 首周特惠截止 | 2026-05-21 | 同左 | 同左 |
| 正式版预期 | ¥28(未公开承诺) | 待定 | 待定 |
| DLC 1 预计 | ¥10 | 待定 | 待定 |
| 全套封顶承诺 | EA 入手 ≤ ¥60 / 正式版入手 ≤ ¥70 | 待最终确认 | 待最终确认 |
## 🔗 相关文件
- `01_事件背景与玩家诉求.md` - 详细骂点 + 玩家心理分析
- `02_危机公关策略与决策.md` - 整体处理思路 + 关键决策点
- `03_补偿方案完整设计.md` - DLC Key + 12 场景 + 申领流程
- `04_DLC定价与17阵营问题.md` - 阵营结构 + 价格承诺设计
- `05_已执行话术与文案存档.md` - 已发出的所有公开内容
- `06_待执行任务清单.md` - 详细 TODO + 时间表
- `07_经验教训复盘.md` - 长期记忆,后续 session 参考

Binary file not shown.

View File

@ -0,0 +1,23 @@
fileFormatVersion: 2
guid: 391c2624fd642094cb8a4d7ba267ff4e
AudioImporter:
externalObjects: {}
serializedVersion: 7
defaultSettings:
serializedVersion: 2
loadType: 0
sampleRateSetting: 0
sampleRateOverride: 44100
compressionFormat: 1
quality: 1
conversionMode: 0
preloadAudioData: 0
platformSettingOverrides: {}
forceToMono: 0
normalize: 1
loadInBackground: 0
ambisonic: 0
3D: 1
userData:
assetBundleName:
assetBundleVariant:

View File

@ -538,7 +538,7 @@ MonoBehaviour:
- SkillType: 40
SkillViewType: 2
SkillName:
SkillDesc: "**<\u592A\u6781>**:\u88AB\u52A8\u6280\u80FD\u3002\u53D7\u5230\u4F24\u5BB3\u65F6\uFF0C\u5C06\u4F24\u5BB3\u989D\u5916\u8FD4\u56DE\u7ED9\u5BF9\u65B9\u3002"
SkillDesc:
NotShow: 0
ShowOnUnitMono: 0
SkillIcon: {fileID: 0}
@ -2882,7 +2882,7 @@ MonoBehaviour:
- SkillType: 230
SkillViewType: 4
SkillName: "\u6838\u878D\u5408\u9884\u70ED"
SkillDesc: "\u5F53\u524D\u56DE\u5408\u65E0\u6CD5\u79FB\u52A8\uFF0C\u4E0B\u4E00\u56DE\u5408\u5F00\u59CB\u65F6\u5C06\u81EA\u52A8\u6309\u7167\u6307\u4EE4\u8DEF\u5F84\u79FB\u52A8\u5E76\u653B\u51FB\u8DEF\u5F84\u4E0A\u7B2C\u4E00\u4E2A\u9047\u5230\u7684\u654C\u4EBA\u3002"
SkillDesc: "\u5F53\u524D\u56DE\u5408\u65E0\u6CD5\u79FB\u52A8\uFF0C\u4E0B\u4E00\u56DE\u5408\u5F00\u59CB\u65F6\u5C06\u81EA\u52A8\u6309\u7167\u6307\u4EE4\u8DEF\u5F84\u79FB\u52A8\u5E76\u653B\u51FB\u8DEF\u5F84\u4E0A\u7B2C\u4E00\u4E2A\u9047\u5230\u7684\u654C\u4EBA\u3002\u82E5\u8DEF\u5F84\u4E0A\u7B2C\u4E00\u4E2A\u78B0\u5230\u7684\u662F\u5DF1\u65B9\u5355\u4F4D\u5219\u4F1A\u505C\u6B62\u79FB\u52A8\u3002"
NotShow: 0
ShowOnUnitMono: 0
SkillIcon: {fileID: 21300000, guid: de3bb8de90b277e4d83c00930a9e7933, type: 3}

View File

@ -1085,6 +1085,7 @@ RectTransform:
m_ConstrainProportionsScale: 0
m_Children:
- {fileID: 2621553783464108823}
- {fileID: 4528966887792056795}
- {fileID: 1205708729765306845}
- {fileID: 2184881051338692039}
- {fileID: 8882186284409583335}
@ -1201,6 +1202,7 @@ MonoBehaviour:
RankingButton: {fileID: 4649407183905496781}
WikiButton: {fileID: 5879810144992425802}
QuitPanel: {fileID: 7159509067703284630}
NextTurnConfirmPanel: {fileID: 3395910451510361722}
_tabUnitCount: 0
--- !u!1 &2643776139574445125
GameObject:
@ -4310,7 +4312,7 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 7849747489070299319, guid: 19402153ee79dbc4e80a78f3222e6b47, type: 3}
propertyPath: m_SizeDelta.x
value: 830.08167
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7849747489070299319, guid: 19402153ee79dbc4e80a78f3222e6b47, type: 3}
propertyPath: m_AnchoredPosition.x
@ -4357,3 +4359,172 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 23a2c17451c60ba4596a82bec9da1626, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!1001 &4511593649456151611
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
serializedVersion: 3
m_TransformParent: {fileID: 7448979660496629192}
m_Modifications:
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_Pivot.x
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_Pivot.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMax.x
value: 1
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMin.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_SizeDelta.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalPosition.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalRotation.w
value: 1
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalRotation.x
value: -0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalRotation.y
value: -0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalRotation.z
value: -0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalEulerAnglesHint.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalEulerAnglesHint.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_LocalEulerAnglesHint.z
value: 0
objectReference: {fileID: 0}
- target: {fileID: 2929065332464497643, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3276818161146238211, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3276818161146238211, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3276818161146238211, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3276818161146238211, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 4562217579296961775, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_Name
value: UIBottomNextTurnConfirmPanel
objectReference: {fileID: 0}
- target: {fileID: 7534345392331640139, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMax.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7534345392331640139, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMin.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7534345392331640139, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7534345392331640139, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.y
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7849747489070299319, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMax.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7849747489070299319, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchorMin.y
value: 1
objectReference: {fileID: 0}
- target: {fileID: 7849747489070299319, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_SizeDelta.x
value: 0
objectReference: {fileID: 0}
- target: {fileID: 7849747489070299319, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.x
value: 338.1344
objectReference: {fileID: 0}
- target: {fileID: 7849747489070299319, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
propertyPath: m_AnchoredPosition.y
value: -253.69449
objectReference: {fileID: 0}
m_RemovedComponents: []
m_RemovedGameObjects: []
m_AddedGameObjects: []
m_AddedComponents: []
m_SourcePrefab: {fileID: 100100000, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
--- !u!114 &3395910451510361722 stripped
MonoBehaviour:
m_CorrespondingSourceObject: {fileID: 1278129582971699777, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
m_PrefabInstance: {fileID: 4511593649456151611}
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 0}
m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 21a4ab62951dbc4438313f299d40741b, type: 3}
m_Name:
m_EditorClassIdentifier:
--- !u!224 &4528966887792056795 stripped
RectTransform:
m_CorrespondingSourceObject: {fileID: 19837280825370080, guid: ed55b8a014ca41543a2d95f370c5750d, type: 3}
m_PrefabInstance: {fileID: 4511593649456151611}
m_PrefabAsset: {fileID: 0}

View File

@ -1977,7 +1977,7 @@ RectTransform:
m_AnchorMin: {x: 0, y: 1}
m_AnchorMax: {x: 0, y: 1}
m_AnchoredPosition: {x: 475.04083, y: -253.69449}
m_SizeDelta: {x: 830.08167, y: 137.3574}
m_SizeDelta: {x: 0, y: 137.3574}
m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1640998311177812195
MonoBehaviour:

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: ed55b8a014ca41543a2d95f370c5750d
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -5822,11 +5822,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 2623095339141718462, guid: fb0641be7df17f1489b938bde7529f8b, type: 3}
propertyPath: m_AnchoredPosition.x
value: 92.005
value: 182.005
objectReference: {fileID: 0}
- target: {fileID: 2623095339141718462, guid: fb0641be7df17f1489b938bde7529f8b, type: 3}
propertyPath: m_AnchoredPosition.y
value: -39.324
value: -39.32425
objectReference: {fileID: 0}
- target: {fileID: 3401993140071222086, guid: fb0641be7df17f1489b938bde7529f8b, type: 3}
propertyPath: m_AnchorMax.y
@ -5958,11 +5958,11 @@ PrefabInstance:
objectReference: {fileID: 0}
- target: {fileID: 4927754070562819153, guid: fb0641be7df17f1489b938bde7529f8b, type: 3}
propertyPath: m_AnchoredPosition.x
value: 228.01498
value: 318.015
objectReference: {fileID: 0}
- target: {fileID: 4927754070562819153, guid: fb0641be7df17f1489b938bde7529f8b, type: 3}
propertyPath: m_AnchoredPosition.y
value: -39.324
value: -39.32425
objectReference: {fileID: 0}
- target: {fileID: 4944937303067552312, guid: fb0641be7df17f1489b938bde7529f8b, type: 3}
propertyPath: m_Name

File diff suppressed because it is too large Load Diff

View File

@ -103,6 +103,7 @@ namespace Logic.Audio
path["SFX/MATCH_win"] = "Audio/SFX/MATCH_win";
path["SFX/MATCH_lose"] = "Audio/SFX/MATCH_lose";
path["SFX/UNIT_born"] = "Audio/SFX/UNIT_born";
path["SFX/start"] = "Audio/SFX/start";
@ -129,7 +130,7 @@ namespace Logic.Audio
{
foreach (var player in _allPlayer)
{
if (player == _musicPlayer) player.Update(ConfigManager.Instance.Config.MusicVolume);
if (player.IsMusic) player.Update(ConfigManager.Instance.Config.MusicVolume);
else player.Update(ConfigManager.Instance.Config.AudioVolume);
if (player.State != PlayerState.Finished) continue;
if (!player.Clip) continue;
@ -161,14 +162,18 @@ namespace Logic.Audio
return;
}
}
// 异曲切换: 让旧 player 自然走完 FadeOut, 新曲用独立的新 player crossfade,
// 避免复用同一个 _musicPlayer 导致 Source.clip 被立刻覆盖而戛然而止。
StopMusic();
_musicPlayer = null;
}
else _musicPlayer = GetPlayer();
_musicPlayer = GetPlayer();
_musicPlayer.IsMusic = true;
// 清除待播放和间隔状态,因为正在显式切换到新音乐
_pendingMusicName = null;
_gapTimer = 0;
_musicPlayer.Clip = _clips[musicName][0];
if (!_musicPlayer.Clip)
if (!_musicPlayer.Clip)
{
LogSystem.LogError($"音乐资源 {musicName} 未找到或加载失败!");
return;
@ -269,7 +274,9 @@ namespace Logic.Audio
_activePlayerMusics.Contains(_musicPlayer.MusicName))
{
_lastPlayedMusicName = _musicPlayer.MusicName;
// 如果是循环音乐,取消循环,让 UpdateBgmRotation 处理后续切换
// 取消状态机的循环, 让 UpdateBgmRotation 在到达 FadeOut 触发点时进 FadeOut。
// 不动 Source.loop: BGM 的 Source.loop 始终为 true (在 Play() 中强制),
// 防止 AudioSource 自然终止, FadeOut 完全由状态机控制。
if (_musicPlayer.IsLoop)
{
_musicPlayer.IsLoop = false;
@ -320,7 +327,9 @@ namespace Logic.Audio
return;
}
// 如果是循环音乐,取消循环,让 UpdateBgmRotation 处理后续切换
// 取消状态机的循环, 让 UpdateBgmRotation 在到达 FadeOut 触发点时进 FadeOut。
// 不动 Source.loop: BGM 的 Source.loop 始终为 true (在 Play() 中强制),
// 防止 AudioSource 自然终止, FadeOut 完全由状态机控制。
if (_musicPlayer.IsLoop)
{
_musicPlayer.IsLoop = false;
@ -400,9 +409,9 @@ namespace Logic.Audio
return;
}
// 如果当前音乐是循环播放的,取消循环让它自然播完
// 只修改状态机的 IsLoop不修改 Source.loop
// 这样 AudioSource 不会在到达结尾时自行停止FadeOut 完全由状态机控制
// 取消状态机的循环, 让 UpdateSourceVolume 在到达 Length-FadeOutDuration 时进 FadeOut。
// 不动 Source.loop: BGM 的 Source.loop 在 Play() 里被强制为 true,
// 防止 AudioSource 到达 Clip 末尾自然终止导致 FadeOut 还没跑完就丢声音。
if (_musicPlayer.State == PlayerState.Playing && _musicPlayer.IsLoop)
{
_musicPlayer.IsLoop = false;
@ -466,6 +475,7 @@ namespace Logic.Audio
{
if (!_clips.ContainsKey(musicName)) return;
var player = GetPlayer();
player.IsMusic = false;
player.Clip = _clips[musicName][0];
if (!player.Clip)
{
@ -587,6 +597,9 @@ namespace Logic.Audio
public PlayerState State;
// 播放当帧不能停, 能停标记
public bool FirstFrame;
// 是否是BGM(true=用MusicVolume控制, false=用AudioVolume控制)
// 切歌crossfade期间, 旧BGM player已不是_musicPlayer但仍应受MusicVolume控制
public bool IsMusic;
public AudioPlayer(AudioSource source)
@ -608,8 +621,12 @@ namespace Logic.Audio
Source.time = 0;
Source.clip = Clip;
Source.volume = 0;
Source.loop = IsLoop;
// BGM 强制 Source.loop = true: 防止 AudioSource 在 Source.time 到达 Clip.length
// 时自动停止, 导致状态机的 FadeOut 还没机会跑就丢声音(听感=戛然而止)。
// 状态机的 IsLoop 字段独立控制 FadeOut 触发时机, FadeOut 完成后状态机会调 Source.Stop()。
// 短音效 (IsMusic=false) 走原逻辑, 由 IsLoop 决定是否循环。
Source.loop = IsMusic || IsLoop;
Source.Play();
// 设置播放位置(在 Play 之后)
if (recordTime > 0 && Clip.length > 0)

View File

@ -1943,6 +1943,7 @@ namespace RuntimeData
gameRecord.MapWidth = MapConfig.Width;
gameRecord.MapHeight = MapConfig.Height;
gameRecord.PlayerCount = MapConfig.PlayerCount;
gameRecord.MatchSettlement = MapConfig.MatchSettlement;
return gameRecord;
}

View File

@ -473,6 +473,8 @@ namespace Logic.Action
{
if (actionParams.UnitData.GetSkill(SkillType.KomeijiFear, out _))
return true;
if (actionParams.UnitData.GetSkill(SkillType.SAKUYATIRED, out _))
return true;
if (actionParams.UnitData.Health < actionParams.UnitData.GetMaxHealth())
return true;
return false;
@ -582,6 +584,8 @@ namespace Logic.Action
{
if (actionParams.UnitData.GetSkill(SkillType.KomeijiFear, out _))
return true;
if (actionParams.UnitData.GetSkill(SkillType.SAKUYATIRED, out _))
return true;
if (actionParams.UnitData.Health < actionParams.UnitData.GetMaxHealth())
return true;
return false;

View File

@ -227,6 +227,12 @@ namespace TH1_Logic.Config
// 老存档反序列化时此字段不存在 → 默认 false → 自动触发一次迁移
[SerializeField]
private bool _modConfigMigrated;
// 始终显示选中地块所属城市的边界。老存档反序列化默认 false → 与旧版本行为一致(只在点城市中心格时显示边界)
[SerializeField]
private bool _alwaysShowCityBorder;
// 点击"下一回合"前是否弹出二次确认。老存档反序列化默认 false → 与旧版本行为一致(直接结束回合)
[SerializeField]
private bool _confirmBeforeNextTurn;
private bool _isChanged;
public bool IsChanged => _isChanged;
@ -324,6 +330,28 @@ namespace TH1_Logic.Config
}
}
public bool AlwaysShowCityBorder
{
get => _alwaysShowCityBorder;
set
{
if (_alwaysShowCityBorder == value) return;
_isChanged = true;
_alwaysShowCityBorder = value;
}
}
public bool ConfirmBeforeNextTurn
{
get => _confirmBeforeNextTurn;
set
{
if (_confirmBeforeNextTurn == value) return;
_isChanged = true;
_confirmBeforeNextTurn = value;
}
}
public GameConfig()
{
@ -337,6 +365,8 @@ namespace TH1_Logic.Config
_modLanguageConfigs = new List<ModLanguageConfig>();
// 全新存档不需要迁移(迁移仅针对老版本"全自动 apply"过的玩家)
_modConfigMigrated = true;
_alwaysShowCityBorder = false;
_confirmBeforeNextTurn = false;
}
// ── Mod 优先级配置接口 ──

View File

@ -495,8 +495,13 @@ namespace Logic
}
// 保存游戏记录
var record = Main.MapData.ExportGameRecord();
GameRecordManager.Instance.AddRecord(record);
// 教程关卡不进历史存档UIOutsideHistory 只按 GameMode 过滤GameMode 没有 Tutor 这一项),
// 教程的 record.Mode 实际是 DOMINATION会污染 DOMINATION 列表。Story 仍保留。
if (Main.MapData.MapConfig.MatchSettlement != MatchSettlementType.Tutor)
{
var record = Main.MapData.ExportGameRecord();
GameRecordManager.Instance.AddRecord(record);
}
// 保存存档
if (Main.MapData.MapConfig.MatchSettlement != MatchSettlementType.Story)

View File

@ -0,0 +1,105 @@
// 临时调试工具dump MatchLevelData 里某个关卡的 PlayerSettlements 详情
// 用完可以删
using System.Text;
using TH1_Logic.MatchConfig;
using UnityEditor;
using UnityEngine;
namespace Logic.Editor
{
public static class DumpMapConfigEditor
{
[MenuItem("Tools/Debug/Dump 关卡2配置(Domination)")]
private static void DumpId2()
{
DumpId(2);
}
[MenuItem("Tools/Debug/Dump 关卡6配置(Perfect)")]
private static void DumpId6()
{
DumpId(6);
}
[MenuItem("Tools/Debug/Dump 关卡7配置(Creative)")]
private static void DumpId7()
{
DumpId(7);
}
[MenuItem("Tools/Debug/Dump 全部关卡列表")]
private static void DumpAllIds()
{
MatchConfigManager.Instance.Init();
var data = MatchConfigManager.Instance.LevelData;
if (data == null || data.LevelConfigs == null)
{
Debug.LogError("[DumpMapConfig] LevelData 为空");
return;
}
var sb = new StringBuilder();
sb.Append("[DumpMapConfig] 全部关卡 id => MatchSettlement / PlayerSettlements.Count:\n");
foreach (var kv in data.LevelConfigs)
{
var cfg = kv.Value;
sb.Append($" id={kv.Key} MatchSettlement={cfg?.MatchSettlement} ");
sb.Append($"PlayerSettlements.Count={cfg?.PlayerSettlements?.Count ?? -1}");
sb.Append($" GameMode={cfg?.GameMode}");
sb.Append($" MapName={cfg?.MapName}");
sb.Append('\n');
}
Debug.Log(sb.ToString());
}
private static void DumpId(uint id)
{
MatchConfigManager.Instance.Init();
var cfg = MatchConfigManager.Instance.GetMatchConfig(id);
if (cfg == null)
{
Debug.LogError($"[DumpMapConfig] 找不到 id={id} 的关卡");
return;
}
var sb = new StringBuilder();
sb.Append($"[DumpMapConfig] id={id}\n");
sb.Append($" GameMode={cfg.GameMode}\n");
sb.Append($" MatchSettlement={cfg.MatchSettlement}\n");
sb.Append($" IsCustomMap={cfg.IsCustomMap} MapName={cfg.MapName}\n");
sb.Append($" PlayerCount={cfg.PlayerCount} AIDiff={cfg.AIDiff}\n");
if (cfg.PlayerSettlements == null)
{
sb.Append(" PlayerSettlements = null ← 这种情况会 fallback 到 OtherDie+Param1=-1\n");
}
else
{
sb.Append($" PlayerSettlements.Count = {cfg.PlayerSettlements.Count}\n");
for (int i = 0; i < cfg.PlayerSettlements.Count; i++)
{
var s = cfg.PlayerSettlements[i];
if (s == null)
{
sb.Append($" [{i}] null\n");
continue;
}
sb.Append($" [{i}] SettlementType={s.SettlementType} Tasks.Count={s.Tasks?.Count ?? -1}\n");
if (s.Tasks != null)
{
for (int j = 0; j < s.Tasks.Count; j++)
{
var t = s.Tasks[j];
if (t == null) { sb.Append($" Task[{j}] null\n"); continue; }
sb.Append($" Task[{j}] Type={t.TaskType} ");
sb.Append($"P1={t.Param1} P2={t.Param2} P3={t.Param3} P4={t.Param4} ");
sb.Append($"Order={t.Order}\n");
}
}
}
}
Debug.Log(sb.ToString());
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8f7ef651def5fbb49bc6296edcb54b64
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -13,6 +13,7 @@ using Logic.AI;
using Logic.CrashSight;
using MemoryPack;
using TH1_Logic.Config;
using TH1_Logic.MatchConfig;
using TH1_Logic.Tools;
using UnityEngine;
@ -181,5 +182,8 @@ namespace RuntimeData
public uint MapWidth;
public uint MapHeight;
public uint PlayerCount;
// 新增字段必须追加在末尾,否则会破坏老玩家存档。
// 用于区分教程/剧情等特殊关卡UI 历史记录会过滤 Tutor。
public MatchSettlementType MatchSettlement;
}
}

View File

@ -255,6 +255,30 @@ namespace Logic
#endif
}
if (Input.GetKeyDown(KeyCode.Alpha1))
{
#if UNITY_EDITOR
if ((Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
&& (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)))
{
//Ctrl+Shift+1调试用让当前选中的我方城市立即升1级仅编辑器下可用
var map = Main.MapData;
var selfPlayer = map?.PlayerMap?.SelfPlayerData;
var grid = MapRecordManager.Instance?.RecordGridData;
if (map != null && selfPlayer != null && grid != null
&& map.GetCityDataByGid(grid.Id, out var city)
&& map.GetPlayerDataByCityId(city.Id, out var owner)
&& owner == selfPlayer)
{
//恰好升1级所需的exp每级升级消耗等于当前 Level
int need = city.Level - city.LevelExp;
if (need < 1) need = 1;
Main.CityLogic.GridGiveCityExp_LogicView(map, owner, grid, city, need);
}
}
#endif
}
OnTechTreeAction();
OnHeroAction();
@ -402,6 +426,8 @@ namespace Logic
// 检测数字键1-9的按下执行对应的操作
if (UIManager.Instance.UIInfoManager.GetCurTaskType() != typeof(UIInfoGridInfoController)) return;
//带 Ctrl 修饰的数字键留给作弊快捷键(如 Ctrl+Shift+1不在此处吃掉
if (Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl)) return;
for (int i = 1; i <= 9; i++)
{
if (Input.GetKeyDown(KeyCode.Alpha1 + i - 1))

View File

@ -38,8 +38,50 @@ namespace Logic
_mapData = mapData;
}
// 当前被半透的城市格 Id(0 = 无),用来保底恢复
private uint _fadeCityGridId = 0;
// 保底:把上一次半透处理过的城市恢复正常透明度。任何状态切换前都应调用
private void ClearCityFadeIfAny()
{
if (_fadeCityGridId == 0) return;
if (MapRenderer.Instance != null
&& MapRenderer.Instance.ROGridMap.TryGetValue(_fadeCityGridId, out var roGrid))
{
roGrid.ClearCityBuildingFade();
}
_fadeCityGridId = 0;
}
// 检测 clickedGrid 是否正好在某城市的"正上方 1/2 格"(城市在 clickedGrid 的 -1-1 / -2-2 位置),
// 命中则对该城市应用 fade。z >= h 的房子半透
private void TryApplyCityFadeForClickedGrid(GridData clickedGrid)
{
if (clickedGrid == null) return;
int cx = clickedGrid.Pos.X;
int cy = clickedGrid.Pos.Y;
//距离 1 上方:城市在 (cx-1, cy-1) → z>=2 半透
if (TryFadeCityAt(cx - 1, cy - 1, 2)) return;
//距离 2 上方:城市在 (cx-2, cy-2) → z>=5 半透
TryFadeCityAt(cx - 2, cy - 2, 5);
}
private bool TryFadeCityAt(int x, int y, int fadeHeight)
{
if (!_mapData.GridMap.GetGridDataByPos(x, y, out var targetGrid)) return false;
if (!targetGrid.CityOnGrid(_mapData, out _)) return false;
if (!MapRenderer.Instance.ROGridMap.TryGetValue(targetGrid.Id, out var roGrid)) return false;
roGrid.SetCityBuildingFadeAboveHeight(fadeHeight);
_fadeCityGridId = targetGrid.Id;
return true;
}
public void CancelAllHighlight() //专门用来应对BottomInfoUI的CloseButton的函数点击close的时候先调用这个函数通知interaction处理好信息再关闭bottominfo
{
//保底:恢复所有被半透的城市
ClearCityFadeIfAny();
foreach (var gridData in Main.MapData.GridMap.GridList)
{
gridData.CityBorderRenderMark = false;
@ -130,6 +172,18 @@ namespace Logic
MapRenderer.Instance.CameraController.CameraFocusOnGrid(gridData);
CancelAllHighlight();
MapRenderer.Instance.ROGridMap[gridData.Id].SetSelectHighlight(true);
//检测点击格"下方 1/2 格"是否有城市,有则对其建筑应用 fade
TryApplyCityFadeForClickedGrid(gridData);
//如果点击格属于某城市领土,对应城市中心播放弹跳动画
if (_mapData.GetCityDataByTerritoryGid(gridData.Id, out var city))
{
if(_mapData.GetGridDataByCityId(city.Id,out var gridTmp)
&& Main.MapData.PlayerMap.SelfPlayerData.Sight.CheckIsInSight(gridTmp.Id))
MapRenderer.Instance.ROGridMap[gridTmp.Id].SetBounceAnim();
}
//UIManager.Instance.BottomInfoUI.SetBottomInfoShowGrid(gridData.Id);
EventManager.Publish(new ShowUIInfoGridInfo() {type = UIGridInfoType.grid,id = gridData.Id });
}
@ -272,6 +326,9 @@ namespace Logic
CancelAllHighlight();
MapRenderer.Instance.ROGridMap[gridData.Id].SetSelectHighlight(true);
//检测点击格"下方 1/2 格"是否有城市,有则对其建筑应用 fade
TryApplyCityFadeForClickedGrid(gridData);
if (_mapData.GetCityDataByTerritoryGid(gridData.Id, out var city))
{
if(_mapData.GetGridDataByCityId(city.Id,out var gridTmp)

View File

@ -71,6 +71,8 @@ namespace Logic.Skill
public override void OnDamaged(MapData mapData, SettlementInfo info)
{
if (info.DamageTarget == null) return;
// 承伤者重定向场景(如 SakuyaGuard):target 实际没掉血,CorpseBuff 不消耗层数
if (info.DamageBearer != null) return;
if (info.DamageType == DamageType.ActiveAttack || info.DamageType == DamageType.CounterAttack ||
info.DamageType == DamageType.Splash)
{

View File

@ -33,7 +33,7 @@ namespace Logic.Skill
public override void BeforeDamagedTransformStage(MapData mapData, SettlementInfo info)
{
if (info.DamageOrigin == null || info.DamageTarget == null || info.DamageType == DamageType.KillSelf) return;
if (!mapData.GetGridDataByUnitId(info.DamageTarget.Id, out var targetGrid)) return;
var aroundBuf = RentAroundBuf();
mapData.GridMap.GetAroundGridData(1, 1, targetGrid, aroundBuf);
@ -47,12 +47,14 @@ namespace Logic.Skill
// 必须和受击目标是同一阵营(友军)才能代为守护
if (!mapData.IsLeagueUnitByUnit(info.DamageTarget.Id, unit.Id)) continue;
info.IsFinished = true;
// 改为承伤者重定向:伤害减半由 unit(Sakuya) 承受,target 仍正常触发 OnDamaged,
// origin 的 OnDamageOther/Moment/HeroTask 链照常跑(Escape 等触发器能正常生效)。
info.DamageBearer = unit;
info.DamageValue = info.DamageValue / 2;
//提前记录unitRednerer(可能会死亡)
var unitRenderer = unit.Renderer(Main.MapData);
var guardGridRenderer = unit.Grid(Main.MapData)?.Renderer(Main.MapData);
var targetGridRenderer = info.DamageTarget.Grid(Main.MapData)?.Renderer(Main.MapData);
Main.UnitLogic.DamageSettlement(mapData, info.DamageOrigin, unit,info.DamageValue / 2, DamageType.Splash);
//脱离presentation体系 播放sakuya动画 TODO 这里有一点动画隐患之后要纳入presentation体系
if(info.DamageTarget.Grid(mapData)?.InMainSight() ?? true )
Timer.Instance.TimerRegister(this, () =>

View File

@ -84,6 +84,10 @@ namespace Logic
public CityData DamageTargetCity;
//伤害值
public int DamageValue;
// 承伤者:非空时,扣血和死亡判定改针对此单位,但 OnDamaged/HeroTask/Moment 等被动回调仍走 DamageTarget。
// 用于 SakuyaGuard 这类"代为承受伤害"语义:原目标算被打过(被动正常触发)但不掉血,血由 Bearer 来扣。
// Bearer 死亡不计入攻击者的 TotalKill / killHero 等 moment。
public UnitData DamageBearer;
//是否击杀
public bool IsKill;
//是否已有死亡替换技能触发(防止多个死亡替换技能同时生成单位)
@ -455,26 +459,42 @@ namespace Logic
mapData.BeforeUnitDamaged(settlement);
if (settlement.IsFinished) return null;
settlement.HealthReduceValue = Mathf.Min(target.Health, settlement.DamageValue);
target.Health -= settlement.DamageValue;
if (type == DamageType.KillSelf && !target.IsAlive())
// 承伤者重定向:Bearer 非空时,扣血/击杀针对 Bearer,但 OnDamaged/Moment/HeroTask 仍走 target。
// Bearer 死亡走完整 UnitDie 流程,但不计为攻击者的击杀(IsKill 保持 false,不加 TotalKill)。
var bearer = settlement.DamageBearer;
if (bearer != null)
{
UnitDie(mapData, target, settlement.DamageValue);
settlement.IsKill = true;
}
else if (target.CanBeKilled(mapData) && !target.IsAlive())
{
if (Main.MapData == mapData) AchievementDataManager.Instance.OnKillUnit(mapData, origin, target);
UnitDie(mapData, target, settlement.DamageValue);
settlement.IsKill = true;
//if (!origin.IsExpLock(mapData)) origin.Exp++;
mapData.GetPlayerDataByUnitId(origin.Id, out var player);
if (player != null) player.TotalKill++;
settlement.HealthReduceValue = Mathf.Min(bearer.Health, settlement.DamageValue);
bearer.Health -= settlement.DamageValue;
if (bearer.CanBeKilled(mapData) && !bearer.IsAlive())
{
UnitDie(mapData, bearer, settlement.DamageValue);
}
settlement.IsKill = false;
}
else
{
settlement.IsKill = false;
settlement.HealthReduceValue = Mathf.Min(target.Health, settlement.DamageValue);
target.Health -= settlement.DamageValue;
if (type == DamageType.KillSelf && !target.IsAlive())
{
UnitDie(mapData, target, settlement.DamageValue);
settlement.IsKill = true;
}
else if (target.CanBeKilled(mapData) && !target.IsAlive())
{
if (Main.MapData == mapData) AchievementDataManager.Instance.OnKillUnit(mapData, origin, target);
UnitDie(mapData, target, settlement.DamageValue);
settlement.IsKill = true;
//if (!origin.IsExpLock(mapData)) origin.Exp++;
mapData.GetPlayerDataByUnitId(origin.Id, out var player);
if (player != null) player.TotalKill++;
}
else
{
settlement.IsKill = false;
}
}
// unit 受伤和伤害他人时回调

View File

@ -388,9 +388,47 @@ namespace TH1Renderer
house.transform.position = tpos;
house.transform.localScale = 3.9f * Vector3.one;
}
}
// 让 cityBuilding 下 house{x}_{y}_{z} 中 z >= h 的 sprite 半透(alpha=0.2),其余恢复 1.0
public void SetCityBuildingFadeAboveHeight(int h)
{
if (_cityBuilding == null) return;
foreach (Transform child in _cityBuilding.transform)
{
if (!TryParseHouseZ(child.name, out int z)) continue;
var sr = child.GetComponent<SpriteRenderer>();
if (sr == null) continue;
var c = sr.color;
c.a = z >= h ? 0.2f : 1.0f;
sr.color = c;
}
}
// 取消半透,cityBuilding 下所有 house 的 alpha 恢复 1.0
public void ClearCityBuildingFade()
{
if (_cityBuilding == null) return;
foreach (Transform child in _cityBuilding.transform)
{
var sr = child.GetComponent<SpriteRenderer>();
if (sr == null) continue;
var c = sr.color;
c.a = 1.0f;
sr.color = c;
}
}
// 从 "house{x}_{y}_{z}" 形式的名字解析出 z(最后一段)
private static bool TryParseHouseZ(string name, out int z)
{
z = 0;
if (string.IsNullOrEmpty(name)) return false;
int idx = name.LastIndexOf('_');
if (idx < 0 || idx == name.Length - 1) return false;
return int.TryParse(name.Substring(idx + 1), out z);
}
public void RenderUpdataHighlight()
{
_moveHighlight.SetActive(IsMoveHighlight);

View File

@ -0,0 +1,49 @@
using Animancer;
using TH1Resource;
using UnityEngine;
using UnityEngine.UI;
namespace TH1_UI.View.Bottom
{
// 点"下一回合"前的二次确认浮窗。挂在 UIBottomBottomBar prefab 里,由 UIBottomBottomBarView 持有并驱动。
// 行为对齐 UIBottomBottomBarQuitPanelMonoAnimancer 淡入淡出 + Cancel/Check 两按钮 + 委托回调。
public class UIBottomBottomBarNextTurnConfirmPanelMono : MonoBehaviour
{
public AnimancerComponent Animancer;
public Button CancelButton;
public Button CheckButton;
// 用户点 Check 后执行的委托
public ViDelegateAssisstant.Dele OnNextTurnConfirm;
public void OnInit()
{
CancelButton.onClick.RemoveAllListeners();
CancelButton.onClick.AddListener(OnClose);
CheckButton.onClick.RemoveAllListeners();
CheckButton.onClick.AddListener(OnConfirm);
gameObject.SetActive(false);
}
public void Open()
{
gameObject.SetActive(true);
Animancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeIn);
}
public void OnClose()
{
AnimancerState state = Animancer.Play(ResourceCache.Instance.AnimCache.UICommonPanelFadeOut);
state.Events.OnEnd += () =>
{
gameObject.SetActive(false);
};
}
private void OnConfirm()
{
OnClose();
OnNextTurnConfirm?.Invoke();
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 21a4ab62951dbc4438313f299d40741b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -10,6 +10,7 @@ using RuntimeData;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Core;
using TH1_Logic.Config;
using TH1_Logic.Net;
using TH1_Logic.Steam;
using TH1_UI.Components;
@ -45,6 +46,7 @@ namespace TH1_UI.View.Bottom
public Button WikiButton;
public UIBottomBottomBarQuitPanelMono QuitPanel;
public UIBottomBottomBarNextTurnConfirmPanelMono NextTurnConfirmPanel;
public int _tabUnitCount = 0;
@ -60,6 +62,12 @@ namespace TH1_UI.View.Bottom
QuitPanel.OnInit();
QuitPanel.OnQuitConfirm += OnQuitConfirmed;
}
if (NextTurnConfirmPanel != null)
{
NextTurnConfirmPanel.OnInit();
NextTurnConfirmPanel.OnNextTurnConfirm += ExecuteNextTurn;
}
}
public bool CheckHasTabUnit(out GridData grid)
@ -118,6 +126,8 @@ namespace TH1_UI.View.Bottom
{
if (QuitPanel != null)
QuitPanel.gameObject.SetActive(false);
if (NextTurnConfirmPanel != null)
NextTurnConfirmPanel.gameObject.SetActive(false);
QuitButton.onClick.RemoveAllListeners();
QuitButton.onClick.AddListener(OnQuitButtonClicked);
@ -194,15 +204,29 @@ namespace TH1_UI.View.Bottom
private void OnNextButtonClicked()
{
if (Main.MapData.CurPlayer != Main.MapData.PlayerMap.SelfPlayerData) return;
// 二次确认开关打开 → 弹窗,等用户按 CheckOnNextTurnConfirm → ExecuteNextTurn
if (ConfigManager.Instance.Config.ConfirmBeforeNextTurn && NextTurnConfirmPanel != null)
{
NextTurnConfirmPanel.Open();
return;
}
ExecuteNextTurn();
}
// 真正结束本回合的逻辑。CancelAllHighlight / HideUIInfoGridInfo 放在这里,
// 是为了让"弹窗确认"分支也走同一份清场代码;如果在弹窗里 Cancel则现场完全保持。
private void ExecuteNextTurn()
{
Main.Instance.MapInteractionLogic.CancelAllHighlight();
EventManager.Publish(new HideUIInfoGridInfo(){});
if (Main.MapData.Net.Mode == NetMode.Multi && !LobbyManager.Instance.Lobby.IsLobbyOwner())
{
{
GameNetSender.Instance.TurnEndConfirm();
}
// 单机或者是房主直接切
else Main.PlayerLogic.EndPlayerTurn(Main.MapData, Main.MapData.PlayerMap.SelfPlayerId);
}
private void OnSLButtonClicked()

View File

@ -10,6 +10,7 @@ using Logic.Skill;
using RuntimeData;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Config;
using TH1_Logic.Core;
using TH1_Logic.MatchConfig;
using TH1_Presentation.Sequencer.Task;
@ -169,6 +170,7 @@ namespace TH1_UI.View.Info
public void SetContent(ShowUIInfoGridInfo evt)
{
TryMarkCityBorderForSelection(evt);
SetContentAvatar(evt);
SetContentGrid(evt);
SetContentUnit(evt);
@ -179,6 +181,33 @@ namespace TH1_UI.View.Info
SetContentTask(evt);
LayoutRebuilder.ForceRebuildLayoutImmediate(VerticalGroup);
}
// "始终显示选中地块所属城市边界"设置打开时,把宿主格所属城市的整片领土 mark 起来。
// 关闭时不做事,仍由 SetContentCity 处理"点城市中心格才亮"的旧行为。
// CancelAllHighlight 已经在每次点击前清零全图 mark所以这里只管置 true。
private void TryMarkCityBorderForSelection(ShowUIInfoGridInfo evt)
{
if (!ConfigManager.Instance.Config.AlwaysShowCityBorder) return;
uint hostGid;
switch (evt.type)
{
case UIGridInfoType.grid:
hostGid = evt.id;
break;
case UIGridInfoType.unit:
if (!Main.MapData.GetGridIdByUnitId(evt.id, out hostGid)) return;
break;
default:
return;
}
if (!Main.MapData.GetCityDataByTerritoryGid(hostGid, out var city)) return;
foreach (var gid in city.Territory.TerritoryArea)
if (Main.MapData.GridMap.GetGridDataByGid(gid, out var gridData))
gridData.CityBorderRenderMark = true;
}
private void SetContentAvatar(ShowUIInfoGridInfo evt)
{

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using Logic.Audio;
using Logic.CrashSight;
using Logic.Multilingual;
using RuntimeData;
@ -50,6 +51,7 @@ namespace TH1_UI.View.Notify
break;
case UINotifyCommonType.TurnHint:
MultilingualManager.Instance.SetUIText(content,Table.Instance.TextDataAssets.NotifyUITurnHint,new List<string>(){(Main.MapData.CurPlayer.Turn + 1).ToString()});
AudioManager.Instance.PlayAudio("SFX/start");
break;
case UINotifyCommonType.InfiltrateStealCoin:
MultilingualManager.Instance.SetUIText(content,Table.Instance.TextDataAssets.NotifyUIInfiltrateStealCoin,new List<string>(){eventType.IntParam.ToString()});

View File

@ -21,6 +21,8 @@ namespace TH1_UI.View.Top
public UIOutsideSelectOptionGroupMono LanguageOptionGroup;
public Toggle KeyMomentToggle;
public Toggle BgmContinuousToggle;
public Toggle CityBorderAlwaysToggle;
public Toggle ConfirmNextTurnToggle;
// MoreLanguage 模块:仅在 LanguageOptionGroup 选中索引 5 (moreLanguage) 时显示
public GameObject MoreLanguageModule;
@ -55,6 +57,18 @@ namespace TH1_UI.View.Top
BgmContinuousToggle.onValueChanged.AddListener(OnBgmContinuousToggleChanged);
}
if (CityBorderAlwaysToggle != null)
{
CityBorderAlwaysToggle.onValueChanged.RemoveAllListeners();
CityBorderAlwaysToggle.onValueChanged.AddListener(OnCityBorderAlwaysToggleChanged);
}
if (ConfirmNextTurnToggle != null)
{
ConfirmNextTurnToggle.onValueChanged.RemoveAllListeners();
ConfirmNextTurnToggle.onValueChanged.AddListener(OnConfirmNextTurnToggleChanged);
}
if (ManageButton != null)
{
ManageButton.onClick.RemoveAllListeners();
@ -72,6 +86,16 @@ namespace TH1_UI.View.Top
ConfigManager.Instance.Config.BgmContinuousPlay = isOn;
}
private void OnCityBorderAlwaysToggleChanged(bool isOn)
{
ConfigManager.Instance.Config.AlwaysShowCityBorder = isOn;
}
private void OnConfirmNextTurnToggleChanged(bool isOn)
{
ConfigManager.Instance.Config.ConfirmBeforeNextTurn = isOn;
}
public void RefreshLanguageOption()
{
var lan = MultilingualManager.Instance.GetCurLanguage();
@ -240,6 +264,8 @@ namespace TH1_UI.View.Top
RefreshLanguageOption();
RefreshKeyMomentToggle();
RefreshBgmContinuousToggle();
RefreshCityBorderAlwaysToggle();
RefreshConfirmNextTurnToggle();
}
public void RefreshKeyMomentToggle()
@ -257,6 +283,22 @@ namespace TH1_UI.View.Top
BgmContinuousToggle.isOn = ConfigManager.Instance.Config.BgmContinuousPlay;
}
}
public void RefreshCityBorderAlwaysToggle()
{
if (CityBorderAlwaysToggle != null)
{
CityBorderAlwaysToggle.isOn = ConfigManager.Instance.Config.AlwaysShowCityBorder;
}
}
public void RefreshConfirmNextTurnToggle()
{
if (ConfirmNextTurnToggle != null)
{
ConfirmNextTurnToggle.isOn = ConfigManager.Instance.Config.ConfirmBeforeNextTurn;
}
}
public void CloseView()
{

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 47f0483d122c95d49aa9e90b4d51deb5
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -13,7 +13,7 @@ PlayerSettings:
useOnDemandResources: 0
accelerometerFrequency: 60
companyName: Remilia Command
productName: TOHOTOPIA v0.7.1k
productName: TOHOTOPIA
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}

File diff suppressed because it is too large Load Diff