go-game-dev

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Go 游戏开发专家 (Go Game Development Expert)

Go Game Development Expert

本技能为独立游戏开发者提供了一套使用 Go 语言构建专业级游戏的标准化工程流和深度决策模型。
This skill provides indie game developers with a standardized engineering workflow and in-depth decision-making model for building professional-grade games using the Go language.

✅ DOS (必须做的事)

✅ DOS (Things You Must Do)

  1. 热路径零分配 (Zero Allocation):
    • 必须在
      Update()
      Draw()
      循环复用切片(
      slice = slice[:0]
      )和对象池(
      sync.Pool
      或泛型 Pool),确保每帧 GC 压力为零。
  2. 主线程封印 (Main Thread Binding):
    • 所有的绘图逻辑(
      DrawImage
      ,
      NewImage
      )必须严格限制在
      Game.Draw()
      主回调中执行,以确保运行在 OS 主线程。
  3. 并发安全 (Concurrency Safety):
    • 在 Goroutine 中处理 AI 或物理运算时,必须通过
      Channel
      回传结果到主循环,或者对共享状态加
      sync.RWMutex
      锁。
  4. 显存手动管理 (Manual VRAM Disposal):
    • 任何动态创建的
      ebiten.Image
      (非嵌入资源),必须在使用完毕后显式调用
      .Dispose()
      ,不得依赖 GC。
  1. Zero Allocation on Hot Paths:
    • Must reuse slices (
      slice = slice[:0]
      ) and object pools (
      sync.Pool
      or generic Pool) in the
      Update()
      and
      Draw()
      loops to ensure zero GC pressure per frame.
  2. Main Thread Binding:
    • All drawing logic (
      DrawImage
      ,
      NewImage
      ) must be strictly restricted to the
      Game.Draw()
      main callback to ensure execution on the OS main thread.
  3. Concurrency Safety:
    • When handling AI or physics calculations in Goroutines, results must be passed back to the main loop via
      Channel
      , or shared states must be locked with
      sync.RWMutex
      .
  4. Manual VRAM Disposal:
    • Any dynamically created
      ebiten.Image
      (non-embedded resources) must explicitly call
      .Dispose()
      after use; do not rely on GC.

❌ DON'TS (绝对禁止的事)

❌ DON'TS (Things You Must Never Do)

  1. 🚫 禁止在循环中创建对象:
    • 严禁在
      Update
      中使用
      fmt.Sprintf
      (隐式接口转换)、
      make([]int)
      &Vector{}
  2. 🚫 禁止跨线程渲染:
    • 绝不要在自己启动的
      go func()
      中调用任何图形 API。这会导致随机崩溃或
      invalid memory address
  3. 🚫 禁止并发读写 Map:
    • 严禁在未加锁的情况下从多个 Goroutine 访问同一个
      map
      。Go 的 Map 竞态检测会直接 Panic 整个进程。
  4. 🚫 禁止 CGO 频繁交互:
    • 避免在
      Update
      循环中高频调用微小的 C 函数(如 Raylib 的单点绘图)。必须在 Go 侧批处理数据,一次性传递给 C 侧。
  1. 🚫 Forbid Object Creation in Loops:
    • Strictly prohibit using
      fmt.Sprintf
      (implicit interface conversion),
      make([]int)
      or
      &Vector{}
      in
      Update
      .
  2. 🚫 Forbid Cross-Thread Rendering:
    • Never call any graphics API in a self-started
      go func()
      . This will cause random crashes or
      invalid memory address
      errors.
  3. 🚫 Forbid Concurrent Map Reads/Writes:
    • Strictly prohibit accessing the same
      map
      from multiple Goroutines without locking. Go's Map race detector will directly panic the entire process.
  4. 🚫 Forbid Frequent CGO Interactions:
    • Avoid high-frequency calls to tiny C functions (such as Raylib's single-point drawing) in the
      Update
      loop. Data must be batched on the Go side and passed to the C side in one go.

Workflows

Workflows

Phase 1: 标准化工程脚手架 (Project Scaffolding)

Phase 1: Standardized Project Scaffolding

切勿将所有代码塞进
main.go
。请遵循 Go 标准项目布局。
  • 目录结构:
    • cmd/game/main.go
      : 程序入口,仅负责初始化窗口和启动 Game Loop。
    • internal/game/
      : 核心逻辑,对外部不可见。
    • internal/assets/
      : 嵌入式文件系统 (
      embed.FS
      ) 的对接口。
    • internal/ecs/
      : (可选) 存放 Component 和 System 定义。
  • 动作:
    1. go mod init <module>
    2. 创建
      internal/game/game.go
      并定义
      Game
      结构体。
    3. cmd/game/main.go
      中调用
      ebiten.RunGame(&game.Game{})
Never stuff all code into
main.go
. Follow the Go standard project layout.
  • Directory Structure:
    • cmd/game/main.go
      : Program entry point, only responsible for initializing the window and starting the Game Loop.
    • internal/game/
      : Core logic, invisible to external parties.
    • internal/assets/
      : Interface for embedded file system (
      embed.FS
      ).
    • internal/ecs/
      : (Optional) Stores Component and System definitions.
  • Actions:
    1. go mod init <module>
    2. Create
      internal/game/game.go
      and define the
      Game
      struct.
    3. Call
      ebiten.RunGame(&game.Game{})
      in
      cmd/game/main.go
      .

Phase 2: 场景管理状态机 (Scene Manager FSM)

Phase 2: Scene Manager FSM

游戏不是一个大循环,而是一系列场景的切换(Logo -> Menu -> Play -> Over)。
  • 模式:
    • 定义
      Scene
      接口:必须包含
      Update() error
      Draw(screen *ebiten.Image)
    • Game
      结构体中持有
      currentScene Scene
  • 动作:
    1. 实现
      SceneManager
      ,提供
      SwitchTo(Scene)
      方法。
    2. 确保
      Game.Update()
      只是一层代理:
      return g.currentScene.Update()
    3. 实现第一个
      TitleScene
      并挂载。
A game is not a single big loop, but a series of scene switches (Logo -> Menu -> Play -> Over).
  • Pattern:
    • Define the
      Scene
      interface: Must include
      Update() error
      and
      Draw(screen *ebiten.Image)
      .
    • Hold
      currentScene Scene
      in the
      Game
      struct.
  • Actions:
    1. Implement
      SceneManager
      and provide the
      SwitchTo(Scene)
      method.
    2. Ensure
      Game.Update()
      is just a proxy:
      return g.currentScene.Update()
      .
    3. Implement the first
      TitleScene
      and mount it.

Phase 3: 数据导向实体设计 (Data-Oriented Entity Design)

Phase 3: Data-Oriented Entity Design

随着实体数量增加,OOP 继承树会成为性能瓶颈。
  • 策略:
    • 少量实体 (<500): 使用 组合模式 (Composition)。定义
      GameObject
      结构体,内嵌
      *Sprite
      *Position
    • 海量实体 (>1000): 必须上 ECS (Entity Component System)。推荐使用
      donburi
      arche
      库。
  • 动作:
    1. 定义
      Component
      接口或结构体数据。
    2. 实现
      System
      (如
      MovementSystem
      ),只遍历拥有
      Velocity
      组件的实体。
As the number of entities increases, OOP inheritance trees become performance bottlenecks.
  • Strategies:
    • Small number of entities (<500): Use Composition Pattern. Define the
      GameObject
      struct, embedding
      *Sprite
      and
      *Position
      .
    • Large number of entities (>1000): Must use ECS (Entity Component System). Recommended libraries are
      donburi
      or
      arche
      .
  • Actions:
    1. Define
      Component
      interfaces or struct data.
    2. Implement
      System
      (such as
      MovementSystem
      ), only iterating over entities with the
      Velocity
      component.

Phase 4: 输入与资源抽象 (Input & Asset Abstraction)

Phase 4: Input & Asset Abstraction

不要直接在逻辑代码里写
ebiten.IsKeyPressed(ebiten.KeySpace)
  • 输入映射 (Input Mapping):
    • 创建
      InputSystem
      ,将物理按键(Space, A, GamepadA)映射为逻辑意图(
      ActionJump
      ,
      ActionShoot
      )。
    • 逻辑层只判断
      input.IsActionJustPressed(ActionJump)
  • 资源池化:
    • 建立全局(或场景级)
      AssetLoader
    • 使用
      sync.Map
      或普通
      map
      缓存加载过的图片,避免重复 I/O。
Don't directly write
ebiten.IsKeyPressed(ebiten.KeySpace)
in logic code.
  • Input Mapping:
    • Create
      InputSystem
      to map physical keys (Space, A, GamepadA) to logical intents (
      ActionJump
      ,
      ActionShoot
      ).
    • The logic layer only checks
      input.IsActionJustPressed(ActionJump)
      .
  • Resource Pooling:
    • Establish a global (or scene-level)
      AssetLoader
      .
    • Use
      sync.Map
      or ordinary
      map
      to cache loaded images to avoid repeated I/O.

Phase 5: 构建自动化 (Build Automation)

Phase 5: Build Automation

本地能跑不代表能发给玩家。
  • 动作:
    1. 配置
      .air.toml
      实现代码热重载(虽然对图形窗口支持有限,但对逻辑调试有用)。
    2. 编写
      Makefile
      scripts/build.py
      ,固化构建参数:
      • Windows:
        GOOS=windows GOARCH=amd64 go build -ldflags="-H windowsgui -s -w"
      • Web:
        GOOS=js GOARCH=wasm go build -o game.wasm

Working locally doesn't mean it can be distributed to players.
  • Actions:
    1. Configure
      .air.toml
      to implement code hot reloading (support for graphical windows is limited, but useful for logic debugging).
    2. Write
      Makefile
      or
      scripts/build.py
      to formalize build parameters:
      • Windows:
        GOOS=windows GOARCH=amd64 go build -ldflags="-H windowsgui -s -w"
      • Web:
        GOOS=js GOARCH=wasm go build -o game.wasm

Bundled Resources

Bundled Resources

  • References:
    • references/ebitengine_patterns.md
      : Ebitengine 深度设计模式、性能陷阱与优化建议。
    • references/vfx_guide.md
      : 视觉特效指南 (Screen Shake, Shaders, Particles)。
    • references/publishing.md
      : Steam, Itch.io 及移动端商店的官方发布规则、编译参数与审核指南。
    • references/genre_cardgame.md
      : 卡牌游戏工程化指南 (手牌算法, 数据结构, 状态机)。
    • references/genre_simulation.md
      : 模拟经营架构通识 (区块网格, 资源流图, 确定性 Tick)。
  • Scripts:
    • scripts/build_all.py
      : 一键式多平台交叉编译自动化工具(支持 Wasm, Windows, Linux, macOS)。
  • References:
    • references/ebitengine_patterns.md
      : Ebitengine in-depth design patterns, performance pitfalls, and optimization suggestions.
    • references/vfx_guide.md
      : Visual Effects Guide (Screen Shake, Shaders, Particles).
    • references/publishing.md
      : Official release rules, compilation parameters, and review guidelines for Steam, Itch.io, and mobile app stores.
    • references/genre_cardgame.md
      : Engineering Guide for Card Games (Hand algorithms, data structures, state machines).
    • references/genre_simulation.md
      : General Architecture for Simulation Games (Block grids, resource flow diagrams, deterministic ticks).
  • Scripts:
    • scripts/build_all.py
      : One-click cross-platform cross-compilation automation tool (supports Wasm, Windows, Linux, macOS).