跳转到正文

Go SDK 行为参考 ​

包名 neomega,module 为 github.com/OmineDev/neomega-sdk-go,Go 1.23+。公开工具包内的独立模块不依赖私有 Host。开始使用见Go Worker 教程;基础 Worker 协议要求 Host API 1.9、wire 1.0;1.1.0 新增的 Scope、远程会话与投影要求配套 Host API 1.10。

Peer 与连接 ​

Open(ctx) (*Peer, error) 读取 Host 提供的传输参数,完成连接和 hello。默认 stdio;unix 使用绝对 socket 路径;tcp-loopback 只接受 loopback IP。socket 使用 Host 提供的 token,插件不能自行替换安装身份。连接及握手共享最多 10 秒预算,不自动重连。Windows 不支持 unix。

Peer.Call(ctx, method, payload) (map[string]any, error) 是底层 RPC;优先使用下面的封装。Session() 返回安装握手信息,游戏 session 应从 capabilities.get 获取,两者不能混用。Close() 关闭连接,Done() 与 Err() 提供结束状态。

NewPeer(reader, writer) 用于自行接入同一受管协议;Handshake、NextRequest、NextEvent、NextNotification、Respond 和 Reject 是底层接口。使用 Worker.Run 后不要再由另一段代码消费相同消息队列。

生命周期与并发 ​

NewWorker(peer, Callbacks{...}) 返回单次使用的 Worker,Run(ctx) error 拥有连接和 Spawn 注册的后台任务。

回调参数及语义
Validate(context.Context, *Peer, map[string]any) (map[string]any, error);只验证配置/状态,可返回 Bus 导出声明
Activate / Drain(context.Context, *Peer, map[string]any) error;开始活动工作 / 完成排空
Event同上;串行处理事件,返回成功不自动 ACK
Bus / ServiceBus 返回 (any, error) 的 tagged value;Service 与 Validate 相同签名,返回在线服务结果 map
Maintenance与 Validate 相同签名;原 token 绑定的 seal/release 协作维护

前四个生命周期回调 Validate、Activate、Drain、Event 不可缺失。Validate 无导出时返回 nil, nil;非 nil 返回必须包含 "bus_exports": []any{...}。不得在 Validate 开始计时器或其他活动工作。

Spawn(func(context.Context) error) error 最多接纳 32 个受管任务,只在激活或活动期间开放;非协作取消错误会使 Run 失败。Bus 回调可并发,Worker 同时最多接纳 16 个服务调用;共享 Go 状态自行同步。

Drain 等待此前接纳的事件与在线服务,取消受管 Bus/后台活动并实际等待退出,再调用 Drain 回调。成功后恢复接纳,不会再次调用 Activate;要恢复的计时器需在后续事件等明确入口重新创建。不响应取消的 goroutine 仍需 Host 进程终止边界,SDK 不伪造成功排空。

Maintenance 未注册时返回 unsupported。注册后按请求 operation 返回 sealed 或 released,也可返回 busy/unsupported,并原样返回 token。失败返回 maintenance_failed;维护回调不代表自动完成业务状态备份。

配置、KV 与 durable ACK ​

LoadConfig(dst any) error 优先读取 NEOMEGA_CONFIG_OVERRIDE_FILE,否则读取安装数据目录的 config.json。文件缺失保留预设默认值;内容必须是单个 JSON object、最多 256 KiB。解析拒绝 struct 未知字段和尾随 JSON;读取失败不会静默改用其他配置。

Storage{Peer: peer} 提供下列操作:

方法返回及约束
Snapshot(ctx, keys)Snapshot{Revision, Values, Session};Values 为 map[string]json.RawMessage,revision 是全局 CAS revision
SetValue(key, value) / DeleteKey(key)生成 Mutation;写 JSON null 与删除是不同操作
PrepareCommit(id, snapshot, mutations, actions, event)零 IO 冻结 Intent;actions 只能是同 session 的 operation intent
Submit(ctx, intent) / Receipt(ctx, id)提交一次 / 查询原 commit;不自动重试
Ack(ctx, id, snapshot, event)返回 (Intent, receipt, error),只 ACK 也使用 CAS,错误时仍保留 Intent

PrepareCommit 的 ID 仅允许 1–128 个字母、数字、下划线或连字符,提交 JSON 上限 256 KiB。event 为 nil 时使用 state.commit;提供 EventDelivery{SubscriptionID, EventID, DeliveryToken} 时使用 events.commit,同事务提交状态、动作意图和事件进度。三个事件身份字段必须取自原投递,不能重新编造。

订阅写在 manifest 的 subscriptions;SDK 没有自行发明的订阅 RPC。CAS 冲突后不要只换 revision 重放旧业务决定。回执包含原 commit ID、revision、duplicate 和 operation IDs;保留这些证据查询原结果。

游戏操作与不确定结果 ​

Operations{Peer: peer, Session: gameSession} 使用 capabilities.get 的游戏 session。

  1. Prepare(operation, arguments, key, deadline) 冻结原 session、幂等键、期限及参数,不发送请求。
  2. Submit(ctx, intent) 提交一次并返回包含 operation_id/state/duplicate 的接纳回执。
  3. Get(ctx, operationID) 查询原回执;Cancel(ctx, operationID) 显式请求取消。

接纳不代表游戏效果完成。context 取消只是停止等待,不撤销已接纳动作;显式取消也不能宣称撤销已发送效果。unknown 保持不确定,禁止自动重放或替换 ID。

传输失败或回执不合法时可能返回 *Uncertain,其中 Intent 保留原请求、ID 保留已知 ID、Err 保留原因。Host 明确拒绝通过 *IPCRejected{Code, Retryable} 返回;Retryable 字段不授予业务自动重试许可。错误不意味着请求未发送。

跨进程恢复前持久保存 Intent.Method() 与 Intent.Payload()。RestoreIntent(method, payload) 只恢复 state.commit/events.commit/operations.submit 的请求数据,不提交,不刷新期限或 ID。先用 Storage.Receipt 或 Operations.Get 对账;旧 unknown、journal 与 receipt 不应被恢复流程改成成功。

Bus read/service 消费与导出 ​

Bus{Peer: peer}.Catalog(ctx) 返回目录。BusRequest 显式包含 Target、Major、SchemaDigest、Args、Deadline、Kind,可带 Provider 与 Cause。Target、major、digest 和 tagged args 从目录合同取得;SDK 不会把任意 Go struct 自动推断成匹配合同。

方法行为
Submit(ctx, request)仅支持 read/service,必须给出 Deadline;返回原 call receipt
Get(ctx, id) / Cancel(ctx, id)查询 / 显式取消原 call ID
Wait(ctx, receipt, poll)poll 必须大于零;到终态或 context 结束,错误时保留最后回执,不隐式取消
Result(ctx, receipt)只解码 succeeded 结果,不修改原回执
Call(ctx, request, poll)一次提交、等待、解码;返回 (receipt, value, error),终态失败仍保留 receipt

Wait 的终态为 succeeded/failed/cancelled/deadline_exceeded/unavailable;取消或 deadline 结果仍需关注 actual_done,不能据此推断提供者代码已经退出。需要远端取消时,使用单独有效的清理 context 调用 Cancel。

导出时由 Validate 返回 bus_exports:每项提供 name/member/kind/major/shared/candidate_readable/contract,其中 contract 包含 major/schema_digest/schema,并在 manifest 中声明相同导出;Callbacks.Bus 处理 Host 鉴权后的调用。kind=read 且 candidate_readable=true 的声明可在激活前接受候选只读调用,不能借此写游戏状态。Bus 回调应响应 Host 传入的 deadline 与取消。Go SDK 不提供 View/Publish 流提供者,bus.streams.start 返回 provider_unavailable。

Bus 消费按精确成员声明 permissions.services,管理员授予 service:<member>;manifest 声明不等于已有授权。游戏 operation 使用对应 operation 权限,事件使用对应订阅和事件权限,不能用 Bus 服务 grant 替代。权限参考与Bus 合同说明 Host 侧约束。

值编码与 bulk ​

DecodeJSON 保留数字为 json.Number,拒绝重复 object key、非 UTF-8、尾随数据及超限输入;EncodeJSON 使用同一限制。单值最多 16 MiB,嵌套最多 256 层、节点最多 1,000,000。整数宽度、float bit pattern、NBT 等继续使用目录定义的 tagged value,不以 float64 中转整数。

EncodeBusValue(ctx, peer, value, deadline) 与 DecodeBusValue(ctx, value) 处理内联值或 Host 有界 bulk 引用。UploadBulk / DownloadBulk 只消费 Host 发放的 descriptor;不要把 base64 字符串当作任意协议的通用二进制包装。Bus Submit/Result 已接入这条路径。

完整公开类型、函数及方法声明见 Go API 目录。

1.1.0 资源会话与观察 ​

这些包包含在公开 sdk/go 中,沿用同一 module,无需导入私有框架包。Worker 用 neomega.NewManagedBus(peer) 将已有连接适配成 typed Bus,再传给 scopes.New 或 busview.OpenProjection;适配器借用 Peer,调用方仍负责关闭所有 Scope 与观察流。

包能力与用法
scopes手动 Acquire/AcquireRequest、单次回调 Run、续租、关闭与证据;见Go 资源会话。
bushttpConfig、New 和原动作 Operation 查询;与 scopes.NewRemote 组合,见Go 远程客户端。
busviewOpenProjection、Snapshot/Read/Close 与后台恢复;见Go 可恢复投影。
busapityped Bus 的合同、请求、动作意图、View 与 Scope 句柄。
busvalue结构类型绑定、合同摘要及 tagged 值编解码;按成员目录核对合同。

Scope 不替代业务权限,不提供游戏世界回滚。关闭未完成或动作 unknown 时,保存原身份与回执继续核对;不要在重新连接后重新执行业务回调。

Neomega · 使用、开发与参考文档