数据流

本章详细说明数据在系统各层之间的流动。

单人模式数据流

┌─────────────────────────────────────────────┐
│             Godot (GDScript)                │
│  1. 用户点击 → get_global_mouse_position()  │
│  2. 调用 rusty_core.send_command()          │
└──────────────────┬──────────────────────────┘
                   │ Dictionary
                   ↓
┌─────────────────────────────────────────────┐
│            gdextension (Rust)               │
│  3. Dictionary → PlayerInput                │
│  4. runtime.send_input()                    │
└──────────────────┬──────────────────────────┘
                   │ PlayerInput
                   ↓
┌─────────────────────────────────────────────┐
│          runtime_core (Rust)                │
│  5. 分发到 client                            │
└──────────────────┬──────────────────────────┘
                   │ PlayerInput
                   ↓
┌─────────────────────────────────────────────┐
│             client (Rust)                   │
│  6. 本地预测 → 立即更新显示状态               │
│  7. 发送到 server (内存通道)                 │
└──────────────────┬──────────────────────────┘
                   │ PlayerInput
                   ↓
┌─────────────────────────────────────────────┐
│             server (Rust)                   │
│  8. 处理输入命令                             │
│  9. 执行权威逻辑 (Bevy ECS)                  │
│  10. 更新 ECS World                         │
│  11. 复制组件 → client                       │
└──────────────────┬──────────────────────────┘
                   │ Replicated Components
                   ↓
┌─────────────────────────────────────────────┐
│             client (Rust)                   │
│  12. 接收权威状态                            │
│  13. Reconciliation (校正预测)              │
│  14. 生成 FrontendSnapshot                  │
└──────────────────┬──────────────────────────┘
                   │ FrontendSnapshot
                   ↓
┌─────────────────────────────────────────────┐
│          runtime_core (Rust)                │
│  15. 转发 snapshot                          │
└──────────────────┬──────────────────────────┘
                   │ FrontendSnapshot
                   ↓
┌─────────────────────────────────────────────┐
│            gdextension (Rust)               │
│  16. FrontendSnapshot → Dictionary          │
└──────────────────┬──────────────────────────┘
                   │ Dictionary
                   ↓
┌─────────────────────────────────────────────┐
│             Godot (GDScript)                │
│  17. 读取 snapshot["units"]                 │
│  18. 更新 Node2D 位置                        │
│  19. 渲染到屏幕                              │
└─────────────────────────────────────────────┘

远程模式数据流

客户端 → 服务器

Godot → gdextension → runtime_core → client
                                      ↓
                              ┌──────────────┐
                              │ 本地预测     │ (立即反馈)
                              └──────────────┘
                                      ↓
                              ┌──────────────┐
                              │ UDP Socket   │
                              └──────┬───────┘
                                     │ 网络延迟 (50-100ms)
                                     ↓
                              ┌──────────────┐
                              │远程 Server   │
                              └──────────────┘

服务器 → 客户端

                              ┌──────────────┐
                              │远程 Server   │
                              │执行权威逻辑  │
                              └──────┬───────┘
                                     │ 网络延迟 (50-100ms)
                                     ↓
                              ┌──────────────┐
                              │ UDP Socket   │
                              └──────┬───────┘
                                     ↓
client ← runtime_core ← gdextension ← Godot
   ↓
┌──────────────┐
│ Reconcile    │ (对比预测和权威)
└──────┬───────┘
       ↓
┌──────────────┐
│ Interpolate  │ (平滑过渡)
└──────┬───────┘
       ↓
FrontendSnapshot → 显示

启动时数据流

1. Godot 启动
   └─> 加载 gdextension.dll

2. gdextension 初始化
   └─> 注册 RustyCore 类

3. GDScript 调用 RustyCore.initialize(config)
   └─> Dictionary → RuntimeConfig
       └─> runtime_core 初始化

4. runtime_core.initialize()
   └─> 加载内容包
       └─> content::ContentLoader.load_package()
           └─> 读取 manifest.toml
           └─> 解析 units/*.toml
           └─> 验证 schema
           └─> 构建 ContentDatabase

5. GDScript 调用 RustyCore.start_singleplayer()
   └─> runtime_core.start_singleplayer()
       ├─> 创建 Server (使用 ContentDatabase)
       │   └─> 初始化 Bevy App
       │   └─> 加载地图
       │   └─> 生成初始单位
       └─> 创建 Client
           └─> 建立与 server 的内存通道

6. 进入游戏循环

游戏循环数据流

每帧流程 (60 FPS)

Godot _process(delta):
  ├─> rusty_core.update(delta)
  │   └─> runtime_core.update()
  │       ├─> server.update()
  │       │   └─> bevy_app.update()
  │       │       ├─> movement_system
  │       │       ├─> combat_system
  │       │       ├─> resource_system
  │       │       └─> replication_system
  │       └─> client.update()
  │           ├─> 接收复制组件
  │           ├─> reconcile
  │           └─> interpolate
  │
  ├─> var snapshot = rusty_core.get_frontend_snapshot()
  │   └─> client.get_frontend_snapshot()
  │       └─> 遍历 ECS → 构建 FrontendSnapshot
  │           └─> Dictionary
  │
  └─> render_snapshot(snapshot)
      └─> 更新 Godot 节点

关键数据结构转换

Rust → Godot

FrontendSnapshot (Rust)
  ├─> units: Vec<FrontendUnit>
  │   └─> [
  │         FrontendUnit { id, position, health, ... },
  │         FrontendUnit { ... },
  │       ]
  └─> resources: HashMap<u64, PlayerResources>

         ↓ (gdextension 转换)

Dictionary (Godot)
  ├─> "units": Array[Dictionary]
  │   └─> [
  │         { "id": 1, "position": Vector2(100, 200), ... },
  │         { "id": 2, ... },
  │       ]
  └─> "resources": Dictionary
      └─> { 0: 5000, 1: 4500 }

Godot → Rust

Dictionary (Godot)
  ├─> "type": "move"
  └─> "target": Vector2(300, 400)

         ↓ (gdextension 转换)

PlayerInput (Rust)
  └─> PlayerInput::Move {
        target: Position { x: 300.0, y: 400.0 }
      }

状态同步机制

Lightyear 复制流程

Server:
  Entity(123)
    ├─> Position { x: 100.0, y: 200.0 }  [Replicated]
    ├─> Health { current: 80, max: 100 } [Replicated]
    └─> Velocity { ... }                  [Replicated]

         ↓ (Lightyear 自动序列化和发送)

Client:
  Entity(123)  (镜像实体)
    ├─> Position { x: 100.0, y: 200.0 }  [从 server 接收]
    ├─> Health { current: 80, max: 100 } [从 server 接收]
    └─> Velocity { ... }                  [从 server 接收]

下一步

了解核心概念详解: