feat(val-blog): add 2026-04-30 dream journey post

This commit is contained in:
Chen Gu
2026-08-13 17:00:22 +08:00
committed by Chen Gu
parent 691f96e8a6
commit 81978704fc
941 changed files with 195468 additions and 755 deletions
+204
View File
@@ -0,0 +1,204 @@
# AgentLiving - 技术规格文档
## 1. Godot 项目结构
```
ai-agent-living/
├── assets/
│ ├── sprites/
│ │ ├── val/
│ │ │ ├── idle.png
│ │ │ ├── walk.png
│ │ │ └── interact.png
│ │ └── furniture/
│ │ ├── sofa.png
│ │ ├── fridge.png
│ │ └── bed.png
│ ├── tilesets/
│ │ └── apartment_floor.tres
│ └── audio/
│ └── ambient.mp3
├── scenes/
│ ├── main.tscn
│ ├── apartment.tscn
│ ├── val.tscn
│ └── furniture/
│ ├── sofa.tscn
│ └── fridge.tscn
├── scripts/
│ ├── val.gd
│ ├── apartment.gd
│ ├── bridge_client.gd
│ └── state_manager.gd
└── project.godot
```
## 2. 关键类设计
### 2.1 Val (CharacterBody2D)
```gdscript
class_name Val
extends CharacterBody2D
@export var speed: float = 100.0
@onready var sprite: AnimatedSprite2D = $AnimatedSprite2D
@onready var thought_bubble: Label = $ThoughtBubble
var current_state: String = "idle"
var target_position: Vector2 = Vector2.ZERO
var agent_id: String = "val"
func _ready():
BridgeClient.connect("action_received", _on_action)
_connect_to_openclaw()
func _physics_process(delta):
match current_state:
"walk": _handle_walk(delta)
"interact": _handle_interact(delta)
"think": _handle_think(delta)
_: _handle_idle(delta)
func move_to(pos: Vector2):
target_position = pos
current_state = "walk"
sprite.play("walk")
func _on_action(action: Dictionary):
match action.cmd:
"walk_to": move_to(Vector2(action.pos[0], action.pos[1]))
"play_anim": sprite.play(action.anim)
"show_thought": _show_thought(action.text)
"update_state": _update_internal_state(action.key, action.value)
```
### 2.2 BridgeClient (WebSocket)
```gdscript
extends Node
signal action_received(action: Dictionary)
signal state_synced(state: Dictionary)
var socket: WebSocketPeer
var openclaw_url: String = "ws://127.0.0.1:18789"
func _ready():
_connect()
func _connect():
socket = WebSocketPeer.new()
socket.connect_to_url(openclaw_url)
func _process(delta):
socket.poll()
var state = socket.get_ready_state()
if state == WebSocketPeer.STATE_OPEN:
while socket.get_available_packets() > 0:
var packet = socket.get_packet()
var message = JSON.parse_string(packet.get_string_from_utf8())
_handle_message(message)
func send_command(command: Dictionary):
if socket.get_ready_state() == WebSocketPeer.STATE_OPEN:
socket.send_text(JSON.stringify(command))
func _handle_message(msg: Dictionary):
match msg.type:
"action_sequence":
for action in msg.actions:
action_received.emit(action)
"state_sync":
state_synced.emit(msg.state)
```
## 3. OpenClaw端集成
### 3.1 AgentLiving Skill
创建 `~/.openclaw/skills/agent-living/`
```
agent-living/
├── SKILL.md
├── scripts/
│ └── bridge_server.py
└── config.json
```
### 3.2 Bridge Server (Python)
```python
# bridge_server.py
import asyncio
import websockets
import json
from openclaw import session_manager
class AgentLivingBridge:
def __init__(self):
self.agents = {}
self.godot_clients = {}
async def handle_godot(self, websocket, path):
"""处理Godot客户端连接"""
async for message in websocket:
data = json.loads(message)
response = await self._process_command(data)
await websocket.send(json.dumps(response))
async def _process_command(self, cmd: dict) -> dict:
"""将Godot指令转换为Agent动作"""
if cmd["type"] == "user_command":
# 调用OpenClaw Agent处理
agent_session = session_manager.get("val")
result = await agent_session.send_message(
f"用户在Godot中发出指令:{cmd}"
)
return self._parse_agent_response(result)
def _parse_agent_response(self, response: str) -> dict:
"""解析Agent回复为Godot动作序列"""
# 提取动作序列,格式化为Godot可执行的JSON
actions = []
# ... 解析逻辑
return {"type": "action_sequence", "actions": actions}
# 启动服务器
async def main():
bridge = AgentLivingBridge()
async with websockets.serve(
bridge.handle_godot,
"localhost",
8765
):
await asyncio.Future() # 永久运行
if __name__ == "__main__":
asyncio.run(main())
```
## 4. 状态同步策略
### 4.1 心跳机制
- Godot每5秒发送状态查询
- OpenClaw立即返回完整状态
- 差异超过阈值时触发同步
### 4.2 事件驱动
- Agent状态变化 → 立即推送到Godot
- 用户交互 → 立即发送到Agent
- 避免轮询开销
## 5. 性能优化
### 5.1 Agent端
- 简单行为(走动、idle)用本地规则
- 复杂决策(任务分解)才调用LLM
- 缓存常用响应
### 5.2 Godot端
- 对象池复用粒子效果
- 远处角色降低动画帧率
- 按需加载房间(视野外不渲染)
---
**下一步:** Week 1 开始Godot场景搭建