feat(遊戲化): 新增大廳、附身、時間流、後日談進度等遊戲化系統功能
新增角色大廳(lobby)邀約與通話、附身(possession)、時鐘(clock)抽象、 時間流與睡眠負債、後日談進度、行為選擇與旁觀反應等模組,並補齊對應冒煙 測試(R~V)與單元測試;同步調整 web/mobile 對應頁面與元件。 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+16
-11
@@ -99,9 +99,10 @@ export default async function smokeK() {
|
||||
}
|
||||
|
||||
// K-2 群聊行為變化:同角色、同輸入,在一對一與群聊應輸出不同(群聊更矜持,命中不同親密度分層的模板)。
|
||||
const oneOnOneReply = await post(`/chat/${GENKI_ID}`, {
|
||||
// T38:一對一改走 SOLO 房(DialogueService 管線),群聊仍走 GROUP 房(RoomGenerationService 管線)。
|
||||
const soloRoom = await post("/room/solo", { userId: USER_ID, characterId: GENKI_ID });
|
||||
const oneOnOneReply = await post(`/room/${soloRoom.id}/message`, {
|
||||
userId: USER_ID,
|
||||
sessionId: "smoke-k-11-session",
|
||||
text: "今天過得如何呀",
|
||||
});
|
||||
const groupIntimacyRoom = await post("/room", { userId: USER_ID, characterIds: [GENKI_ID], mode: "GROUP" });
|
||||
@@ -162,7 +163,9 @@ export default async function smokeK() {
|
||||
throw new Error("被虧的那位(小元)記憶權重應該高於旁觀者(小冷)");
|
||||
}
|
||||
|
||||
// K-6 角色自聊:話題種子驅動、發言權機制沿用、空轉偵測與輪數上限確保一定會收斂(不會無限跑下去)。
|
||||
// K-6/T6 角色自聊:話題種子驅動、發言權機制沿用;行為種類(TALK/ACTION/DELEGATE/LEAVE)由
|
||||
// BehaviorSelectionService 依人格參數+情緒/行程/話題狀態算權重抽樣決定,不再受舊版 12 輪硬上限
|
||||
// 節制——測試角色沒有設定行程/極端情緒,三項離開動因皆不成立,驗證的是「可以持續推進超過舊上限」。
|
||||
const selfChatRoom = await post("/room", {
|
||||
userId: USER_ID,
|
||||
characterIds: [GENKI_ID, TSUNDERE_ID, COOL_ID],
|
||||
@@ -171,8 +174,9 @@ export default async function smokeK() {
|
||||
});
|
||||
let ended = false;
|
||||
let turns = 0;
|
||||
const SAFETY_CAP = 30; // 遠大於 SELF_CHAT_MAX_TURNS,純粹防止測試本身無限迴圈
|
||||
for (let i = 0; i < SAFETY_CAP && !ended; i++) {
|
||||
const PAST_OLD_CAP = 20; // 大於舊版 SELF_CHAT_MAX_TURNS(12),驗證不再被舊上限強制結束
|
||||
const OLD_CAP = 12;
|
||||
for (let i = 0; i < PAST_OLD_CAP && !ended; i++) {
|
||||
const result = await post(`/room/${selfChatRoom.id}/self-chat/advance`, {});
|
||||
if (result.ended) {
|
||||
ended = true;
|
||||
@@ -180,11 +184,11 @@ export default async function smokeK() {
|
||||
turns += 1;
|
||||
}
|
||||
}
|
||||
if (!ended) {
|
||||
throw new Error("角色自聊必須在有限輪數內收斂結束,不應該無限進行下去");
|
||||
}
|
||||
if (turns === 0) {
|
||||
throw new Error("角色自聊應該至少產生過一輪對話");
|
||||
// 測試角色沒有設定行程/極端情緒,LEAVE 只可能因話題耗盡觸發;三人須「各自都」耗盡話題才會整室結束,
|
||||
// 這在短短 20 輪內發生的機率極低,因此正常情況下不應該提前結束——若真的提前結束也至少要確認曾經推進
|
||||
// 超過舊版 12 輪上限,而不是被舊上限機制卡住(該機制已整個移除,理論上不會再發生)。
|
||||
if (turns <= OLD_CAP) {
|
||||
throw new Error(`角色自聊應可連續推進超過舊版 ${OLD_CAP} 輪上限,實際只推進了 ${turns} 輪就停止`);
|
||||
}
|
||||
|
||||
// 使用者插話即切換為群聊模式。
|
||||
@@ -205,6 +209,7 @@ export default async function smokeK() {
|
||||
throw new Error("使用者插話後應該切換為群聊模式");
|
||||
}
|
||||
|
||||
// 清理本次測試建立的角色(cascade 會一併清掉關係、記憶等)。
|
||||
// 清理本次測試建立的角色(cascade 會一併清掉關係、記憶等)與本次建立的 SOLO 房。
|
||||
await prisma.room.deleteMany({ where: { id: soloRoom.id } });
|
||||
await prisma.character.deleteMany({ where: { id: { in: [GENKI_ID, TSUNDERE_ID, COOL_ID] } } });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user