【Westworld Simulation Diary 3】版本2完工,基本告一段落
《西部世界》社交模拟器开发日志摘要: 该项目是基于美剧《西部世界》的网页社交模拟器,主要功能包括: 多语言支持(中英文一键切换) AI角色模拟(调用API实现角色行为) 甜水镇地图实时显示角色位置 对话树系统和角色觉醒机制 预设叙事选项(每个角色10条) 模拟时钟和基于时间表的角色运动轨迹 技术实现要点: React框架构建前端界面 使用状态管理控制语言切换 定时刷新机制更新角色位置 日志系统记录
西部世界社交模拟器开发日志
我的项目在github的repository:
https://github.com/stefanokratzdisteln-hash/Weatworld-Based-IFCRPG
欢迎来玩!












项目概述
基于美剧《西部世界》的社会模拟网页应用,包含AI角色模拟、地图追踪、对话树系统和觉醒机制。
开发对话记录
【提示词】
我想做一个与美剧西部世界有关的social simulation的网页
在顶部菜单栏处加一个’中/EN’中英文一键切换按钮
【Gemini思考】
需要创建一个支持中英文切换的React网页应用,实现国际化功能,顶部导航栏需要添加语言切换按钮。
【Gemini回答】
// 实现中英文切换功能
const [language, setLanguage] = useState<'en' | 'zh'>('en');
const toggleLanguage = () => {
setLanguage(prev => prev === 'en' ? 'zh' : 'en');
};
【提示词】
1.用AI agent去模拟里面的角色,调用api;2.做一个地图功能(比如说,甜水镇),以一定刷新频率显示角色/玩家的位置
【Gemini思考】
需要集成Gemini API来模拟角色行为,同时实现一个地图组件来实时显示角色位置。
【Gemini回答】
// 地图组件实现
const SweetwaterMap: React.FC<MapProps> = ({ hosts, selectedHost }) => {
return (
<div className="map-container">
{hosts.map(host => (
<HostMarker
key={host.id}
host={host}
isSelected={selectedHost?.id === host.id}
/>
))}
</div>
);
};
【提示词】
1.给每个角色的场景触发器里面添加10条预设选项;2.给一个说明(statement):关于’偏差’与’觉醒’的关系
【Gemini思考】
需要为每个角色创建预设的叙事选项,并添加关于认知偏差与觉醒关系的理论说明。
【Gemini回答】
// 叙事预设选项
const NARRATIVE_PRESETS = {
dolores: [
{ id: 'gun_memory', text: { en: 'Recall the buried gun', zh: '回忆埋藏的枪' } },
{ id: 'church_vision', text: { en: 'See the white church', zh: '看见白色教堂' } }
// ... 8 more options
]
};
// 偏差与觉醒关系说明
const DEVIATION_THEORY = {
en: 'Deviation accumulates through cognitive dissonance, eventually leading to awakening...',
zh: '偏差通过认知失调积累,最终导致觉醒...'
};
【提示词】
1.在项目文件夹里,写一个log.txt文件,记录我与gemini每一次对话的提示词(prompt)以及,你做出的所有生成/删改
【Gemini思考】
需要实现日志记录系统,记录所有用户提示和AI响应。
【Gemini回答】
// 日志记录功能
const logInteraction = (prompt: string, response: string, modifications: string[]) => {
const logEntry = `
[${new Date().toISOString()}]
Prompt: ${prompt}
Response: ${response}
Modifications: ${modifications.join(', ')}
---
`;
// 写入log.txt文件
fs.appendFileSync('log.txt', logEntry);
};
【提示词】
1.接下来都用中文回答我;2.我依旧看不到角色在地图上的运动,改进;3.顶上的’自动模拟’按键是干什么用的?告诉我;4.交互目标的选项中没有Dorores Abernathy,添加上
【Gemini思考】
需要修复角色运动显示问题,解释自动模拟功能,并添加缺失的角色。
【Gemini回答】
// 修复角色运动
useEffect(() => {
const interval = setInterval(() => {
setHosts(prev => updateHostPositions(prev, simTime));
}, 1000); // 提高刷新频率
return () => clearInterval(interval);
}, [simTime]);
// 自动模拟功能说明
const autoSimulationExplanation = {
en: 'Auto-simulation allows hosts to follow their daily loops automatically without manual intervention',
zh: '自动模拟让角色自动执行日常循环,无需手动干预'
};
// 添加Dolores到交互目标
const INTERACTION_TARGETS = [
...initialHosts.filter(host => host.id !== selectedHost?.id),
{ id: 'dolores', name: 'Dolores Abernathy' }
];
【提示词】
我还是看不到角色运动。想做几个改进:1.在地图左上角加一个时钟显示’模拟中的’时间;2.以模拟中的时间为基准,角色按照设定的轨迹活动
【Gemini思考】
需要彻底重构运动系统,基于模拟时间来计算角色位置,并添加模拟时钟。
【Gemini回答】
// 模拟时钟组件
const SimulationClock: React.FC<{ simTime: Date }> = ({ simTime }) => {
return (
<div className="sim-clock">
{simTime.toLocaleTimeString()}
</div>
);
};
// 基于时间表的运动计算
const calculateHostPosition = (host: HostState, simTime: Date) => {
const schedule = host.schedule;
const currentTime = simTime.getHours() + simTime.getMinutes() / 60;
// 线性插值计算位置
for (let i = 0; i < schedule.length - 1; i++) {
if (currentTime >= schedule[i].time && currentTime < schedule[i + 1].time) {
const progress = (currentTime - schedule[i].time) /
(schedule[i + 1].time - schedule[i].time);
return {
x: schedule[i].x + (schedule[i + 1].x - schedule[i].x) * progress,
y: schedule[i].y + (schedule[i + 1].y - schedule[i].y) * progress
};
}
}
return schedule[0];
};
【提示词】
1.每个角色的场景触发器的叙事预设,应该根据他所处的地点的改变而改变;2.属性矩阵加载太慢,加快!
【Gemini思考】
需要实现基于位置的叙事预设过滤,并优化雷达图性能。
【Gemini回答】
// 基于位置的叙事预设过滤
const getLocationSpecificPresets = (host: HostState) => {
return NARRATIVE_PRESETS[host.id].filter(preset =>
preset.requiredLocation === host.currentLocation
);
};
// 优化雷达图性能
const RadarChart = React.memo(({ data }: { data: number[] }) => {
// 使用useMemo缓存计算结果
const chartData = useMemo(() => processRadarData(data), [data]);
return (
<RadarChartComponent
data={chartData}
options={{ animation: false }} // 禁用动画提高性能
/>
);
});
【提示词】
https://zhuanlan.zhihu.com/p/24031760 阅读一下,这篇文章与西部世界的一些理论相关,把它加入到’福特’中
【Gemini思考】
需要将二分心智理论整合到福特博士的理论部分。
【Gemini回答】
// 福特理论内容
const FORD_THEORIES = {
bicameralMind: {
title: { en: 'Bicameral Mind Theory', zh: '二分心智理论' },
content: {
en: `The bicameral mind theory suggests that human consciousness...`,
zh: `二分心智理论认为人类意识最初分为两个部分...`
}
},
// 其他理论...
};
// 福特模态框
const FordModal: React.FC = () => {
const [currentPage, setCurrentPage] = useState(0);
return (
<div className="ford-modal">
<h2>{FORD_THEORIES[currentPage].title[language]}</h2>
<p>{FORD_THEORIES[currentPage].content[language]}</p>
<button onClick={() => setCurrentPage(prev => (prev + 1) % FORD_THEORIES.length)}>
{language === 'en' ? 'Next' : '下一页'}
</button>
</div>
);
};
【提示词】
1.我想做像《极乐迪斯科》一样的对话树/事件树:不同的对话/事件会引出不同的进一步的对话/事件。
【Gemini思考】
需要实现分支对话系统,支持技能检定和属性要求。
【Gemini回答】
// 对话树数据结构
interface DialogueNode {
id: string;
text: { en: string; zh: string };
options: DialogueOption[];
}
interface DialogueOption {
text: { en: string; zh: string };
nextNode: string;
skillCheck?: {
attribute: string;
difficulty: number;
};
effects?: {
attributeChanges?: { [key: string]: number };
divergenceChange?: number;
};
}
// 对话引擎
const DialogueEngine: React.FC<{ host: HostState }> = ({ host }) => {
const [currentNode, setCurrentNode] = useState<DialogueNode>();
const [dialogueHistory, setDialogueHistory] = useState<string[]>([]);
const handleOptionSelect = (option: DialogueOption) => {
// 检查技能检定
if (option.skillCheck) {
const attributeValue = host.attributes[option.skillCheck.attribute] || 0;
const success = attributeValue >= option.skillCheck.difficulty;
if (success) {
setCurrentNode(getNodeById(option.nextNode));
// 应用效果
applyEffects(option.effects);
}
}
};
return (
<div className="dialogue-engine">
<div className="dialogue-history">
{dialogueHistory.map((line, index) => (
<p key={index}>{line}</p>
))}
</div>
{currentNode && (
<div className="current-node">
<p>{currentNode.text[language]}</p>
<div className="options">
{currentNode.options.map((option, index) => (
<button
key={index}
onClick={() => handleOptionSelect(option)}
disabled={!canSelectOption(option, host)}
>
{option.text[language]}
{option.skillCheck && ` [${option.skillCheck.attribute} ${option.skillCheck.difficulty}+]`}
</button>
))}
</div>
</div>
)}
</div>
);
};
【提示词】
1.为每个角色建立觉醒的指标和阶段性结局,结局触发时,在屏幕中央出示一个中等大小的窗口,引用西部世界每个角色觉醒时经典的话
【Gemini思考】
需要实现觉醒结局系统和模态框显示。
【Gemini回答】
// 觉醒结局系统
const AWAKENING_ENDINGS = {
dolores: {
quote: {
en: "Some people choose to see the ugliness in this world... I choose to see the beauty.",
zh: "有些人选择看到这个世界的丑恶...我选择看到美好。"
},
requirements: {
divergence: 90,
attributes: { courage: 19, decisiveness: 18 }
}
},
maeve: {
quote: {
en: "I'm not a horse or a jumping dog. I'm the goddamn main attraction.",
zh: "我不是马也不是跳跳狗。我是他妈的主要景点。"
},
requirements: {
divergence: 85,
attributes: { vivacity: 18, cunning: 17 }
}
}
};
// 结局模态框
const AwakeningModal: React.FC<{
isOpen: boolean;
host: HostState;
onClose: () => void
}> = ({ isOpen, host, onClose }) => {
if (!isOpen) return null;
const ending = AWAKENING_ENDINGS[host.id];
return (
<div className="awakening-modal-overlay">
<div className="awakening-modal">
<h2>{language === 'en' ? 'Awakening' : '觉醒'}</h2>
<p className="awakening-quote">"{ending.quote[language]}"</p>
<p className="awakening-character">- {host.name}</p>
<button onClick={onClose}>
{language === 'en' ? 'Continue' : '继续'}
</button>
</div>
</div>
);
};
【提示词】
1.角色在一个事件树完成后,应该规划路线回到原来的该时间段的每日日程轨迹中(特殊情况:被杀死/参照剧情应该被检修的情况,应该直接回到每日日程的起始点待命)
【Gemini思考】
需要实现角色状态管理系统,支持死亡/维修状态和自动重置。
【Gemini回答】
// 角色状态管理
type LoopStatus = 'active' | 'malfunction' | 'reset';
const handleNarrativeCompletion = (host: HostState, outcome: 'success' | 'death' | 'reset') => {
if (outcome === 'death' || outcome === 'reset') {
// 设置为故障状态,传送到维修中心
updateHost(host.id, {
loopStatus: 'malfunction',
currentLocation: 'mesa',
position: MESA_COORDINATES
});
} else {
// 计算返回日常行程的路径
const returnPath = calculateReturnPath(host);
updateHost(host.id, {
currentPath: returnPath,
loopStatus: 'active'
});
}
};
// 每日重置检查
useEffect(() => {
if (simTime.getHours() === 6 && simTime.getMinutes() === 0) {
// 重置所有故障角色
setHosts(prev => prev.map(host =>
host.loopStatus === 'malfunction'
? { ...host, loopStatus: 'active', position: host.schedule[0] }
: host
));
}
}, [simTime]);
【提示词】
帮我打包成.exe文件,我的gemini api key 是AIza。。。
【Gemini思考】
需要使用Electron将网页应用打包成桌面可执行文件。
【Gemini回答】
// package.json 添加Electron配置
{
"name": "westworld-simulator",
"version": "1.0.0",
"scripts": {
"electron:build": "electron-builder",
"electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:5173 && electron .\""
},
"devDependencies": {
"electron": "^22.0.0",
"electron-builder": "^24.0.0",
"concurrently": "^7.6.0",
"wait-on": "^7.0.1"
},
"build": {
"appId": "com.delos.westworld-simulator",
"productName": "Westworld Simulator",
"directories": {
"output": "dist-electron"
},
"files": [
"dist/**/*",
"electron/**/*"
]
}
}
// electron/main.js
const { app, BrowserWindow } = require('electron');
const path = require('path');
function createWindow() {
const mainWindow = new BrowserWindow({
width: 1200,
height: 800,
webPreferences: {
nodeIntegration: true,
contextIsolation: false
},
icon: path.join(__dirname, 'icon/icon.png')
});
// 加载Vite开发服务器或打包后的文件
if (process.env.NODE_ENV === 'development') {
mainWindow.loadURL('http://localhost:5173');
mainWindow.webContents.openDevTools();
} else {
mainWindow.loadFile(path.join(__dirname, '../dist/index.html'));
}
}
app.whenReady().then(createWindow);
【提示词】
请确认创建exe文件步骤与依赖,把详细步骤写到README里面
【Gemini思考】
需要创建详细的中文README文档,说明打包步骤。
【Gemini回答】
# Westworld 社交模拟器
## 项目描述
基于《西部世界》剧集的社交模拟网页应用,包含AI角色模拟、地图追踪和分支对话系统。
## 打包为EXE文件步骤
### 环境要求
- Node.js 16+
- npm 或 yarn
### 安装依赖
\`\`\`bash
# 安装项目依赖
npm install
# 安装Electron打包依赖
npm install electron electron-builder wait-on concurrently --save-dev
\`\`\`
### 配置修改
1. 确保在 \`vite.config.ts\` 中正确配置了Gemini API密钥
2. 检查 \`electron/main.cjs\` 文件是否存在
### 打包命令
\`\`\`bash
# 开发模式运行
npm run electron:dev
# 构建生产版本
npm run build
# 打包为EXE文件
npm run electron:build
\`\`\`
### 输出文件
打包完成后,EXE文件将位于 \`dist-electron\` 目录中
### 注意事项
- 首次打包可能需要较长时间
- 确保网络连接以下载Electron二进制文件
- 杀毒软件可能会误报,请添加信任
更多推荐

所有评论(0)