时间: 2026年4月上旬 - 4月中旬

在完成初步框架搭建后,我们FateWeaver团队进入了功能细化与验证阶段。这段时间的工作主要围绕两个方向展开:一是完善前端界面的核心交互功能,为后续分工开发打好基础;二是验证大模型API接入的可行性,确保技术路线的正确性。


目录

一、角色创建功能的完善与优化

1.1 多题材差异化设计

1.2 属性上限系统设计

1.3 属性预览进度条优化

1.4 界面遮挡问题的解决

1.5 故事筛选功能的添加

二、团队协作与代码整合

三、API接入验证与首次AI对话成功

3.1 LLMClient类的实现

3.2 后端初始化调整

3.3 首次AI对话成功

四、当前成果与后续规划

4.1 当前成果总结

4.2 后续工作规划


一、角色创建功能的完善与优化

在初步框架中,角色创建界面只有一个简单的弹窗结构。为了让用户体验更加完整,我负责对角色创建模块进行了详细的功能实现和界面优化。以下是目前的角色创建界面:

1.1 多题材差异化设计

考虑到我们的平台需要支持不同题材的故事(奇幻、科幻等),我设计了差异化的天赋和出身系统。不同故事类型拥有各自独立的选项池:

奇幻题材(如“迷雾森林的传说”)的天赋设计:

// 奇幻故事天赋数据
const fantasyTalents = ref([
    { id: 'talent_001', name: '战斗天才', description: '你在战斗方面有着非凡的天赋', 
      effects: { strength: 5, agility: 3 }, rarity: 'rare', unlocked: true, storyId: 'fantasy_001' },
    { id: 'talent_002', name: '博学者', description: '你拥有广博的知识储备', 
      effects: { intelligence: 8, mp: 20 }, rarity: 'rare', unlocked: true, storyId: 'fantasy_001' },
    { id: 'talent_003', name: '幸运儿', description: '命运似乎总是眷顾着你', 
      effects: { luck: 10 }, rarity: 'epic', unlocked: true, storyId: 'fantasy_001' },
    { id: 'talent_005', name: '龙裔血脉', description: '你的血脉中流淌着龙的力量', 
      effects: { hp: 50, strength: 10 }, rarity: 'legendary', unlocked: false, storyId: 'fantasy_001' },
    // ...更多天赋
]);

科幻题材(如“赛博2077:觉醒”)的天赋设计:

// 科幻故事天赋数据
const scifiTalents = ref([
    { id: 'sci_talent_001', name: '黑客大师', description: '你精通各种黑客技术', 
      effects: { intelligence: 8, tech_skill: 10 }, rarity: 'rare', unlocked: true, storyId: 'scifi_001' },
    { id: 'sci_talent_002', name: '义体适应', description: '你的身体能更好地适应义体', 
      effects: { hp: 20, strength: 5 }, rarity: 'rare', unlocked: true, storyId: 'scifi_001' },
    { id: 'sci_talent_004', name: '战斗义体', description: '你装备了军用级战斗义体', 
      effects: { strength: 15, hp: 10 }, rarity: 'legendary', unlocked: false, storyId: 'scifi_001' },
    // ...更多天赋
]);

通过计算属性 availableTalents 和 backgrounds,系统会根据用户选择的故事ID自动筛选出对应的天赋和出身选项:

// 当前故事可用的天赋
const availableTalents = computed(() => {
    const allTalents = [...fantasyTalents.value, ...scifiTalents.value];
    if (!selectedStory.value) return fantasyTalents.value;
    return allTalents.filter(t => t.storyId === selectedStory.value.story_id);
});

1.2 属性上限系统设计

不同题材的故事拥有不同的属性体系。例如,奇幻题材关注HP、MP、力量、敏捷等,而科幻题材则引入了能量值、科技技能等新属性。为此,我设计了故事属性配置对象:

const storyConfigs = {
    fantasy_001: {
        baseAttributes: { hp: 100, mp: 50, strength: 15, agility: 12, intelligence: 10, luck: 8 },
        maxValues: { hp: 150, mp: 100, strength: 50, agility: 50, intelligence: 50, luck: 50 }
    },
    scifi_001: {
        baseAttributes: { hp: 80, energy: 100, strength: 18, intelligence: 20, tech_skill: 15, money: 500 },
        maxValues: { hp: 120, energy: 150, strength: 60, intelligence: 60, tech_skill: 50, money: 9999 }
    }
};

属性预览会动态计算基础值加上天赋和出身的加成,并确保不超过上限:

const previewAttributes = computed(() => {
    const config = currentStoryConfig.value;
    const base = { ...config.baseAttributes };
    const maxValues = config.maxValues;
    
    if (selectedTalent.value) {
        Object.entries(selectedTalent.value.effects).forEach(([attr, value]) => {
            if (base[attr] !== undefined) {
                base[attr] = Math.min(base[attr] + value, maxValues[attr] || 100);
            }
        });
    }
    if (selectedBackground.value) {
        Object.entries(selectedBackground.value.attribute_modifiers).forEach(([attr, value]) => {
            if (base[attr] !== undefined) {
                base[attr] = Math.min(base[attr] + value, maxValues[attr] || 100);
            }
        });
    }
    return base;
});

当属性接近或达到上限时,界面会显示提示信息:

const hasExceededLimit = computed(() => {
    const config = currentStoryConfig.value;
    const maxValues = config.maxValues;
    return Object.entries(previewAttributes.value).some(([attr, value]) => {
        return value >= (maxValues[attr] || 100);
    });
});

1.3 属性预览进度条优化

在属性预览区域,我实现了带有最大值显示的进度条,让用户直观了解当前属性在其上限中的占比:

<div class="attr-item">
    <span class="attr-name">{{ getAttrName(attr) }}</span>
    <div class="attr-bar">
        <div class="attr-fill" :style="{width: (value / getAttrMaxValue(attr) * 100) + '%'}"></div>
        <span class="attr-value">{{ value }}/{{ getAttrMaxValue(attr) }}</span>
    </div>
</div>

对应的CSS样式确保进度条正确显示:

.attr-bar {
    flex: 1;
    height: 20px;
    background: rgba(255, 255, 255, 0.1);
    border-radius: 10px;
    position: relative;
    overflow: hidden;
}

.attr-fill {
    height: 100%;
    background: linear-gradient(90deg, #667eea, #764ba2);
    border-radius: 10px;
    transition: width 0.3s;
}

.attr-value {
    position: absolute;
    right: 8px;
    top: 50%;
    transform: translateY(-50%);
    font-size: 11px;
    color: white;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    z-index: 1;
}

1.4 界面遮挡问题的解决

在开发过程中,我遇到了一个样式问题:当角色创建界面的内容过多时,属性值显示框会与下方的性格倾向滑动条发生重叠遮挡。这导致用户无法正常操作滑动条,影响体验。

经过在DeepSeek等大模型的协助下进行调试,我发现问题出在 .creation-content 和 .creation-form 的高度设置上。原来的CSS没有对内容区域进行滚动限制,导致内容溢出。

修复前的代码:

.creation-content {
    display: grid;
    grid-template-columns: 1fr 1.5fr;
    gap: 30px;
}

修复后的代码:

.creation-content {
    display: grid;
    grid-template-columns: 1fr 1.5fr;
    gap: 30px;
    max-height: 500px;
}

.creation-form {
    overflow-y: auto;
    padding-right: 10px;
    max-height: 500px;
}

.step-content {
    max-height: 350px;
    overflow-y: auto;
    padding-right: 10px;
}

通过为各个容器设置 max-height 和 overflow-y: auto,当内容超出时会出现滚动条,避免了元素之间的遮挡问题。同时,性格倾向滑动条的样式也进行了优化:

.personality-slider {
    padding: 15px 0;
}

.personality-slider input {
    width: 100%;
    height: 6px;
    -webkit-appearance: none;
    appearance: none;
    background: linear-gradient(90deg, #10b981, #f59e0b, #ef4444);
    border-radius: 3px;
    outline: none;
}

.personality-slider input::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 20px;
    height: 20px;
    background: white;
    border-radius: 50%;
    cursor: pointer;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
}

1.5 故事筛选功能的添加

为了让故事大厅更加友好,我还添加了按题材筛选故事的功能。在首页增加了标签切换组件:

<div class="story-tabs-container">
    <div class="story-tab-item" :class="{active: activeStoryFilter === 'all'}" @click="activeStoryFilter = 'all'">
        <span>📚 全部</span>
    </div>
    <div class="story-tab-item" :class="{active: activeStoryFilter === 'fantasy'}" @click="activeStoryFilter = 'fantasy'">
        <span>🌲 奇幻</span>
    </div>
    <div class="story-tab-item" :class="{active: activeStoryFilter === 'scifi'}" @click="activeStoryFilter = 'scifi'">
        <span>🤖 科幻</span>
    </div>
</div>

对应的筛选逻辑:

const filteredStories = computed(() => {
    if (activeStoryFilter.value === 'all') return stories.value;
    if (activeStoryFilter.value === 'fantasy') {
        return stories.value.filter(s => s.genre === '奇幻');
    }
    if (activeStoryFilter.value === 'scifi') {
        return stories.value.filter(s => s.genre === '科幻');
    }
    return stories.value;
});

同时为故事卡片添加了图标展示,增强视觉效果:

<div class="story-card-header">
    <span class="story-icon">{{ story.icon || '📖' }}</span>
    <h3>{{ story.title }}</h3>
</div>

二、团队协作与代码整合

在各自完成负责的功能模块后,我们进行了一次集中的代码整合。其他成员在同期完成的工作包括:

  1. 故事大厅界面的优化:美化了故事卡片的样式,添加了难度标签和更详细的背景描述展示。

  2. 主游戏界面的工具栏完善:在叙事窗口顶部添加了任务日志、命运之网、结局画廊、多周目传承的快捷入口按钮。

  3. 侧边栏状态面板的优化:优化了属性条的显示效果,添加了NPC好感度面板的折叠展开功能。

  4. 结局界面和画廊界面的基础框架:搭建了结局展示和收集系统的UI框架。

进行代码合并后,我们得到了一个功能相对完整的前端框架。虽然大部分数据仍是Mock数据,但界面交互流程已经基本打通:用户可以选择故事、创建角色、进入游戏、进行对话交互。


三、API接入验证与首次AI对话成功

在完善前端的同时,团队中的一名成员负责尝试接入DeepSeek API,验证大模型驱动的互动叙事是否能够真正跑通。

3.1 LLMClient类的实现

在 story_engine.py 中,我们实现了 LLMClient 类来封装对大模型API的调用:

class LLMClient:
    def __init__(self, api_key: str = None, base_url: str = None, model: str = None):
        self.api_key = api_key or os.getenv("DEEPSEEK_API_KEY", "sk-2666c4c1dcfc4b0990dedc7b021cf29c")
        self.base_url = base_url or os.getenv("LLM_BASE_URL", "https://api.deepseek.com/v1")
        self.model = model or os.getenv("LLM_MODEL", "deepseek-chat")
        self.headers = {"Authorization": f"Bearer {self.api_key}", "Content-Type": "application/json"}

    def generate(self, messages: List[Dict[str, str]], temperature: float = 0.8) -> str:
        url = f"{self.base_url}/chat/completions"
        payload = {"model": self.model, "messages": messages, "temperature": temperature, "max_tokens": 800}
        try:
            resp = requests.post(url, headers=self.headers, json=payload, timeout=30)
            resp.raise_for_status()
            return resp.json()["choices"][0]["message"]["content"]
        except Exception as e:
            print(f"LLM 调用失败: {e}")
            return "(大模型暂时无法响应,请稍后再试。)"

3.2 后端初始化调整

在 app.py 中,我们修改了引擎初始化方式,注入真实的LLM客户端:

# 初始化故事引擎(使用大模型)
DEEPSEEK_API_KEY = os.getenv("DEEPSEEK_API_KEY", "sk-2666c4c1dcfc4b0990dedc7b021cf29c")
llm_client = LLMClient(api_key=DEEPSEEK_API_KEY)
engine = StoryEngine(llm_client=llm_client)

3.3 首次AI对话成功

经过调试,我们成功实现了与AI的完整对话流程!

这次成功的验证给了团队极大的信心。它证明了我们的技术架构是可行的——前端通过API发送用户输入,后端调用大模型进行意图识别和叙事生成,再将结果返回前端展示。整个流程顺畅运行!


四、当前成果与后续规划

4.1 当前成果总结

经过这一阶段的工作,我们取得了以下进展:

  1. 完善的角色创建系统:支持多题材差异化设计,包含属性上限管理、实时预览、三步向导流程。

  2. 故事筛选功能:用户可按题材快速筛选感兴趣的故事。

  3. AI对话验证成功:成功接入DeepSeek API,实现了从用户输入到AI剧情生成的完整闭环。

  4. 统一的前端框架:整合了团队成员各自完成的界面模块,形成了功能相对完整的交互原型。

4.2 后续工作规划

后端方面,我们将逐步实现:

  1. 数据库持久化:使用数据库存储用户存档、结局收集记录、天赋解锁状态等。

  2. 状态追踪完善:扩展逻辑裁判节点,支持更丰富的行动类型判定。

  3. 多结局收敛算法:基于用户决策倾向和属性累积,自动匹配最合适的结局。

  4. 上下文管理优化:实现对话历史的智能摘要,保证长程交互的连贯性。


这一阶段的工作让我们对项目有了更清晰的认识。前端框架的确立和AI对话的成功验证,为后续的并行开发扫清了障碍。接下来,我们将按照分工各自推进,定期进行代码合并和集成测试,向着一个功能完整的沉浸式互动叙事平台稳步前进。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐