Files
EVEngine/docs/dev
西风逍遥游 9c11bf1d02 feat(dnut): add host-injected movement and animation ports
The `move` and `animation` steps previously had no dispatch point: the story
always suspended as a host-presented step and the host had to switch on the
step kind in its own loop, or reimplement movement per game mode.

Add two optional ports to `RpgStoryBinding`:

  StoryMoveHandler      moveActor      drives `move`
  StoryAnimationHandler playAnimation  drives `animation`

Each handler returns a three-state status, so one port serves every shape of
host without the dialect assuming a game mode:

  Arrived / Finished      step completes inline, the story never suspends
  Travelling / Playing    the story suspends until the host calls advance()
  Unreachable / Unavailable  the step fails with a structured diagnostic

A failed `Result` from a handler is reported verbatim, so causes such as "the
navigation service is not loaded" are not swallowed.

Both payloads stay in the host's own space. `move`'s `x`/`y` are whatever the
host's movement model uses (tile indices, board cells, world units, lanes) and
never interpreted or rounded here; `animation`'s `clip` is an opaque locator
and is never resolved, loaded, or assumed to name a rig. The `actor` / `actor`
projection is null when the id belongs to another subject space (a map prop, a
camera, a squad) and the step still runs.

Omitting a handler leaves behaviour byte-for-byte unchanged: the step stays
host-presented and the host acknowledges it with advance(). That is the escape
hatch for hosts whose movement or playback must go through their own queue or
state machine, and the compatibility path for existing content.

Also let `RPGStorySession.begin` take `null` for `party` / `bag` / `equipment`
in scripts. They are optional collaborators -- a purely presentational story
needs none of them -- and the C++ entry point already documents them as
nullable, but ssq's default pointer binding rejects Squirrel `null`. Translate
through ssq::Object, matching the idiom in avatar/Avatar.cpp's addLayer.
`gameState` stays typed and required because it owns the completion fact.

Tests: 19 new zeroerr cases. 14 in test/rpg_dialect.cpp cover the semantics of
both ports -- dispatch, inline completion, unreachable/unavailable failure,
verbatim controller failure, the no-controller host-presented path, subjects
outside the party roster, and travelling/playing state across capture and
restore. 5 in test/rpg_dnut_script.cpp drive the steps end to end from
Squirrel and verify the effect, including movement the script controls itself.

Docs: docs/usr/modules/rpg.md documents both ports and the recommended
script-owned movement path; the L1 plan records the deliberate deviation from
its own "grid movement controller" design and why a map::Pathfinder binding
would weld the dialect to one game mode (and add an upward L1->map dependency).
2026-09-18 12:47:55 +08:00
..

EVEngine 开发者文档

本目录保存引擎的架构、模块设计、测试策略和实现计划,面向 EVEngine 本身的维护者与贡献者。

如果你是游戏开发者而不是引擎开发者:请从官网发布页 下载预编译 SDK 直接使用,不需要编译引擎;用户文档见用户指南与 模块使用手册。本目录及下文“从源码构建”只对需要修改引擎的人有意义。

架构与工程约定

功能设计

实施记录

阶段性设计稿与实施计划位于 superpowers/。文档使用的图示位于 img/。

构建与文档

  • 生成 C++ API 文档(Doxygen):make docs(或 cmake --build <build-dir> --target docs), 产物位于 docs/api/html/(已加入 .gitignore)。需要先安装 doxygen: Ubuntu/WSL sudo apt install doxygen、macOS brew install doxygen、Windows choco install doxygen。 文档配置见 docs/Doxyfile.in 与 docs/CMakeLists.txt,入口 src/、Readme.md 与 docs/usr/。 在线版由 GitHub Pages 持续发布:https://evengine.github.io/EVEngine/。

  • 运行时断言:引擎统一通过 zeroerr 的 ASSERT 系列宏做函数参数校验与内部不变量检查, 入口见 src/engine/common/Assert.h(EV_PARAM_CHECK / EV_ASSERT)。

    • Debug 构建默认启用;
    • Release 等非 Debug 构建默认通过 ZEROERR_NO_ASSERT 编译剔除,零运行时开销;
    • 需要手动开启时:make build/linux CMAKE_EXTRA_ARGS=-DEVENGINE_ENABLE_ASSERTS=ON (或 CMake 配置时加 -DEVENGINE_ENABLE_ASSERTS=ON)。

如果你是使用 EVEngine 制作游戏,而不是修改引擎,请从用户指南开始。