This commit is contained in:
2026-04-26 14:27:48 +08:00
parent f68f4914ec
commit ea33413187
155 changed files with 8130 additions and 1740 deletions

View File

@@ -4,13 +4,6 @@
*/
export type {
RpgCreationAnchorText as AnchorTextValue,
RpgCreationAnchorContent as EightAnchorContent,
RpgCreationCoreConflictValue as CoreConflictValue,
RpgCreationHiddenLineValue as HiddenLineValue,
RpgCreationIconicElementValue as IconicElementValue,
RpgCreationKeyRelationshipValue as KeyRelationshipValue,
RpgCreationPlayerEntryPointValue as PlayerEntryPointValue,
RpgCreationPlayerFantasyValue as PlayerFantasyValue,
RpgCreationThemeBoundaryValue as ThemeBoundaryValue,
RpgCreationWorldPromiseValue as WorldPromiseValue,
} from './rpgAgentAnchors';

View File

@@ -1,63 +1,17 @@
/**
* RPG 创作八锚点契约。
* 这一层只描述“创作意图采集态”的结构,不混入 session 或结果页字段
* 每个锚点只保留一段凝练文本;细分关注点由 Agent prompt 负责,不再进入存储结构
*/
export interface RpgCreationWorldPromiseValue {
hook: string;
differentiator: string;
desiredExperience: string;
}
export interface RpgCreationPlayerFantasyValue {
playerRole: string;
corePursuit: string;
fearOfLoss: string;
}
export interface RpgCreationThemeBoundaryValue {
toneKeywords: string[];
aestheticDirectives: string[];
forbiddenDirectives: string[];
}
export interface RpgCreationPlayerEntryPointValue {
openingIdentity: string;
openingProblem: string;
entryMotivation: string;
}
export interface RpgCreationCoreConflictValue {
surfaceConflicts: string[];
hiddenCrisis: string;
firstTouchedConflict: string;
}
export interface RpgCreationKeyRelationshipValue {
pairs: string;
relationshipType: string;
secretOrCost: string;
}
export interface RpgCreationHiddenLineValue {
hiddenTruths: string[];
misdirectionHints: string[];
revealPacing: string;
}
export interface RpgCreationIconicElementValue {
iconicMotifs: string[];
institutionsOrArtifacts: string[];
hardRules: string[];
}
export type RpgCreationAnchorText = string | null;
export interface RpgCreationAnchorContent {
worldPromise: RpgCreationWorldPromiseValue | null;
playerFantasy: RpgCreationPlayerFantasyValue | null;
themeBoundary: RpgCreationThemeBoundaryValue | null;
playerEntryPoint: RpgCreationPlayerEntryPointValue | null;
coreConflict: RpgCreationCoreConflictValue | null;
keyRelationships: RpgCreationKeyRelationshipValue[];
hiddenLines: RpgCreationHiddenLineValue | null;
iconicElements: RpgCreationIconicElementValue | null;
worldPromise: RpgCreationAnchorText;
playerFantasy: RpgCreationAnchorText;
themeBoundary: RpgCreationAnchorText;
playerEntryPoint: RpgCreationAnchorText;
coreConflict: RpgCreationAnchorText;
keyRelationships: RpgCreationAnchorText;
hiddenLines: RpgCreationAnchorText;
iconicElements: RpgCreationAnchorText;
}

View File

@@ -32,7 +32,7 @@ describe('RPG 创作共享契约 fixture', () => {
const anchors = createRpgCreationAnchorContentFixture();
const draftProfile = createRpgAgentFoundationDraftProfileFixture();
expect(anchors.worldPromise?.hook).toContain('旧航路群岛');
expect(anchors.worldPromise).toContain('旧航路群岛');
expect(draftProfile.worldHook).toContain('旧航路群岛');
expect(draftProfile.playableNpcs).toHaveLength(1);
expect(draftProfile.storyNpcs).toHaveLength(1);

View File

@@ -32,48 +32,22 @@ function cloneFixture<T>(value: T): T {
*/
export function createRpgCreationAnchorContentFixture(): RpgCreationAnchorContent {
return cloneFixture({
worldPromise: {
hook: '被海雾吞没的旧航路群岛',
differentiator: '灯塔与禁航令共同决定谁能活着穿过去。',
desiredExperience: '压抑、悬疑、潮湿',
},
playerFantasy: {
playerRole: '玩家回到群岛调查沉船真相。',
corePursuit: '找出失控航路背后的真相。',
fearOfLoss: '失去最后一个还能对上旧案的人。',
},
themeBoundary: {
toneKeywords: ['压抑', '潮湿', '悬疑'],
aestheticDirectives: ['旧灯塔', '潮雾', '断裂航路'],
forbiddenDirectives: ['不要出现现代枪械'],
},
playerEntryPoint: {
openingIdentity: '被迫返乡的失职守灯人',
openingProblem: '首夜就有陌生船只闯入禁航区。',
entryMotivation: '查清沉船夜里被谁改动了灯册。',
},
coreConflict: {
surfaceConflicts: ['守灯会与航运公会争夺旧航路控制权'],
hiddenCrisis: '沉船夜的航灯与灯册被人动过手脚。',
firstTouchedConflict: '玩家开局就会撞上新的封航命令。',
},
keyRelationships: [
{
pairs: '玩家 / 沈砺',
relationshipType: '旧友兼潜在背叛者',
secretOrCost: '沈砺暗地里在替沉船商盟引路。',
},
],
hiddenLines: {
hiddenTruths: ['沉船夜的真实失误并不是单纯天灾。'],
misdirectionHints: ['所有人都会先把问题推给潮雾本身。'],
revealPacing: '第一章露出痕迹,第二章才让玩家摸到灯册线。',
},
iconicElements: {
iconicMotifs: ['会移动的海雾'],
institutionsOrArtifacts: ['回潮旧灯塔', '封灯令', '旧潮图'],
hardRules: ['禁航信号一旦点亮,任何船都必须退航。'],
},
worldPromise:
'被海雾吞没的旧航路群岛,灯塔与禁航令共同决定谁能活着穿过去,体验压抑、悬疑、潮湿。',
playerFantasy:
'玩家回到群岛调查沉船真相,核心追求是找出失控航路背后的真相,风险是失去最后一个还能对上旧案的人。',
themeBoundary:
'压抑、潮湿、悬疑;旧灯塔、潮雾、断裂航路;不要出现现代枪械。',
playerEntryPoint:
'玩家是被迫返乡的失职守灯人,首夜就有陌生船只闯入禁航区,动机是查清沉船夜里被谁改动了灯册。',
coreConflict:
'守灯会与航运公会争夺旧航路控制权,沉船夜的航灯与灯册被人动过手脚,玩家开局会撞上新的封航命令。',
keyRelationships:
'玩家与沈砺是旧友兼潜在背叛者,沈砺暗地里在替沉船商盟引路。',
hiddenLines:
'沉船夜的真实失误并不是单纯天灾;所有人都会先把问题推给潮雾本身;第一章露出痕迹,第二章才让玩家摸到灯册线。',
iconicElements:
'会移动的海雾、回潮旧灯塔、封灯令、旧潮图;禁航信号一旦点亮,任何船都必须退航。',
} satisfies RpgCreationAnchorContent);
}

View File

@@ -8,6 +8,17 @@ export type NpcChatTurnLimitReason = 'negative_affinity';
export type NpcChatTurnClosingMode = 'free' | 'foreshadow_close';
export type NpcChatTurnTerminationMode = 'none' | 'hostile_model';
export type NpcChatTurnTerminationReason = 'hostile_breakoff' | 'player_exit';
export type NpcChatFunctionOption = {
functionId: string;
actionText: string;
detailText?: string | null;
action?: string | null;
};
export type NpcChatTurnDirective = {
sceneActId?: string | null;
turnLimit?: number | null;
@@ -15,6 +26,10 @@ export type NpcChatTurnDirective = {
limitReason?: NpcChatTurnLimitReason | null;
closingMode?: NpcChatTurnClosingMode | null;
forceExitAfterTurn?: boolean;
terminationMode?: NpcChatTurnTerminationMode | null;
terminationReason?: NpcChatTurnTerminationReason | null;
isHostileChat?: boolean;
functionOptions?: NpcChatFunctionOption[];
};
export type NpcChatTurnCompletionDirective = {
@@ -22,6 +37,7 @@ export type NpcChatTurnCompletionDirective = {
remainingTurns?: number | null;
forceExit?: boolean;
closingMode?: NpcChatTurnClosingMode;
terminationReason?: NpcChatTurnTerminationReason | null;
};
export type CharacterChatReplyRequest<
@@ -133,11 +149,17 @@ export type NpcChatPendingQuestOffer<TQuest = unknown> = {
introText?: string;
};
export type NpcChatFunctionSuggestion = {
functionId: string;
actionText: string;
};
export type NpcChatTurnResult<TQuest = unknown> = {
npcReply: string;
affinityDelta: number;
affinityText: string;
suggestions: string[];
functionSuggestions?: NpcChatFunctionSuggestion[];
pendingQuestOffer?: NpcChatPendingQuestOffer<TQuest> | null;
chatDirective?: NpcChatTurnCompletionDirective | null;
};

View File

@@ -131,6 +131,32 @@ export type CreateProfileRechargeOrderResponse = {
center: ProfileRechargeCenterResponse;
};
export type ProfileReferralInviteCenterResponse = {
inviteCode: string;
inviteLinkPath: string;
invitedCount: number;
rewardedInviteCount: number;
todayInviterRewardCount: number;
todayInviterRewardRemaining: number;
rewardPoints: number;
hasRedeemedCode: boolean;
boundInviterUserId: string | null;
boundAt: string | null;
updatedAt: string;
};
export type RedeemProfileReferralInviteCodeRequest = {
inviteCode: string;
};
export type RedeemProfileReferralInviteCodeResponse = {
center: ProfileReferralInviteCenterResponse;
inviteeRewardGranted: boolean;
inviterRewardGranted: boolean;
inviteeBalanceAfter: number;
inviterBalanceAfter: number;
};
export type ProfilePlayedWorkSummary = {
worldKey: string;
ownerUserId: string | null;