跳到主要内容

Python SDK 接口参考

  • 安装包:arena-hero
  • 导入名:arena_hero
  • Python:3.11 或更高版本

所有公开模型都有完整类型,底层是不可变的 Pydantic 模型。服务端状态会先通过校验, 然后才交给你的循环。

客户端​

ArenaHeroClient​

同步客户端:

ArenaHeroClient(
*,
api_key: str,
base_url: str = "https://api.arenahero.io",
websocket_url: str | None = None,
request_timeout: float = 5.0,
request_retries: int = 2,
reconnect_min_delay: float = 0.25,
reconnect_max_delay: float = 5.0,
max_message_size: int = 2 * 1024 * 1024,
)

AsyncArenaHeroClient​

异步客户端接受完全相同的参数:

AsyncArenaHeroClient(
*,
api_key: str,
base_url: str = "https://api.arenahero.io",
websocket_url: str | None = None,
request_timeout: float = 5.0,
request_retries: int = 2,
reconnect_min_delay: float = 0.25,
reconnect_max_delay: float = 5.0,
max_message_size: int = 2 * 1024 * 1024,
)
参数含义
api_key必填。通过 Authorization: Bearer … 发送的凭据。
base_urlHTTP API 基址,命令地址会从这里推导。
websocket_urlWebSocket 地址。省略时从 base_url 推导。
request_timeout单次 HTTP 命令请求的超时秒数。
request_retries第一次请求失败后,最多再安全重试多少次。
reconnect_min_delayWebSocket 首次重连前等待的秒数。
reconnect_max_delayWebSocket 重连等待上限,单位为秒。
max_message_size接受的 WebSocket 单条消息最大字节数。

SDK 不会从环境变量读取这些参数。

turns()​

同步:ArenaHeroClient.turns() -> Iterator[Turn]

异步:AsyncArenaHeroClient.turns() -> AsyncIterator[AsyncTurn]

每个可操作的 Tick 只返回一次。回执仍然会在内部处理,并写入 latest_receipts。

events()​

同步:ArenaHeroClient.events() -> Iterator[Tick | Turn | Received]

异步:AsyncArenaHeroClient.events() -> AsyncIterator[Tick | AsyncTurn | Received]

返回完整的应用层 WebSocket 事件流:

事件何时出现你该做什么
Tick新 Tick 已经宣布。记下编号;这时还没有状态可以操作。
Turn / AsyncTurn完整玩家状态已经准备好。读取状态、排好动作,然后提交。
ReceivedAGENT 或 MANUAL 的计划已保存。替换这个来源、这个 Tick 之前的回执。

一个客户端同一时间只能有一个 events() 或 turns() 迭代器。

latest_receipts​

from arena_hero import CommandSource


agent_receipt = game.latest_receipts.get(CommandSource.AGENT)
manual_receipt = game.latest_receipts.get(CommandSource.MANUAL)

这个只读映射保存当前 Tick 每个来源最新的 Received。新 Tick 开始时会清空。

submit()​

提交一份已经构造好的完整计划:

accepted = game.submit(plan, idempotency_key="agent-10583-plan-1")

异步写法:

accepted = await game.submit(plan, idempotency_key="agent-10583-plan-1")

返回类型是 Accepted。不传 idempotency_key 时,SDK 会自动生成。如果网络失败导致 结果不确定,SDK 会带着同一个 Key 重试完全相同的请求字节。

自定义 Key 必须是 8–128 个可见 ASCII 字节,不能包含空格。

close()​

关闭当前 WebSocket 和 HTTP 连接池。优先使用 with 或 async with,这样退出时会 自动关闭。

Turn​

Turn 和 AsyncTurn 的状态与控制接口完全一致。唯一的区别是 AsyncTurn.submit() 需要 await。

状态​

属性类型含义
tickint这份状态和计划所属的 Tick。
statePlayerState完整、权威的玩家状态模型。
resourcesint当前存放在 Core 里的资源。
resource_capacityint当前容量:max(10, state.population * 5)。
resource_spaceint还能接收多少资源;最小为 0。
core`CoreNone`
unitstuple[Unit, ...]自己控制的所有 Unit。
workerstuple[Worker, ...]自己控制的 Worker。
vanguardstuple[Vanguard, ...]自己控制的 Vanguard。
rangerstuple[Ranger, ...]自己控制的 Ranger。
visible_enemies`tuple[UnitViewCoreView, ...]`
terraintuple[TerrainView, ...]可见障碍与当前可用资源的批次。
resource_cellsfrozenset[Position]仅本 Turn 可见且可用的资源点。
obstacle_cellsfrozenset[Position]当前可见的障碍格。
beaconChampionBeacon经过视野裁剪的信标状态。
eventstuple[ResolutionEvent, ...]上一个 Tick 的私有结算结果。
planCommandPlan当前在内存里排好的完整计划。

Position 是 (x, y) 顺序的 tuple[int, int]。

生产价格动态变化。用 unit_cost(unit_type, state.population) 计算当前状态显示的价格。 服务端会在 SPAWN 结算时按同 Tick 自毁和战斗死亡后的实际人口重新计算。

方法​

方法含义
unit(unit_id)按 UUID 或 UUID 字符串查找一个受控 Unit。
clear()清掉所有 Unit 和 Core 的待提交动作。
submit(idempotency_key=None)提交当前排好的完整计划。

新的 Tick 到来后,再调用旧 Turn 上的动作会抛出 TurnClosedError。不要跨 Tick 保存并 复用 Unit 或 Core 控制对象。

Unit 控制接口​

所有受控 Unit 都有这些成员:

成员类型或签名
viewUnitView
idUUID
positionPosition
hpint
unit_typeUnitType
move(direction)移动一格。
pickup_beacon()拾取当前格的信标。
drop_beacon()放下携带的信标。
heal()与己方静止 Core 同格时,在战斗后恢复 HP。
self_destruct()在移动前移除这个 Unit;不返还资源,也不造成范围伤害。
wait()明确提交 WAIT。
clear_action()把这个 Unit 从待提交计划里移除。

每个 Unit 最多只有一个待提交动作。后调用的方法会替换之前的动作。

Worker​

额外状态:

成员类型含义
cargoint当前携带的资源量。

额外控制:

方法含义
harvest()尝试消耗当前格的资源点。
deposit()与 Core 同格时存入能装下的量,剩余 Cargo 留在 Worker 身上。

一次成功采集消耗一个自然资源点。普通赢家携带 1 资源;所属玩家持有 Beacon 的赢家 从同一个点携带 2。死亡 Worker 留下的 Cargo 资源堆会被优先回收,而且不会取得超过 实际剩余量的资源。多个合格 Worker 采同一格时,只有最低 UUID 成功,其他人收到 HARVEST_FAILED,reason 是 RESOURCE_DEPLETED。

Core 已满时,交付结算为 DEPOSIT_FAILED / CORE_RESOURCE_FULL。人口下降后,高于 新容量的资源会立刻销毁,并通过 CORE_RESOURCE_OVERFLOW_DESTROYED 返回。

Worker 因战斗、Core 摧毁或主动自毁死亡时,携带的全部 Cargo 都会留在最后所在格形成 资源堆。

摧毁敌方 Core 后可能收到 CORE_RESOURCES_CAPTURED。通过 event.core_resource_capture 读取实际存入量、受害者原库存、销毁量和获胜者容量。对该 Core 总伤害最高者获胜,伤害相同时按玩家 UUID 原始字节序;超额资源销毁,获胜方 Core 同 Tick 也死亡时全部战利品销毁。

Vanguard​

方法含义
sweep(direction)攻击指定方向的相邻格。

Ranger​

ranger.shoot_cell((120, 85))
ranger.shoot(target)
ranger.shoot(target_id, expected_cell=(120, 85))

shoot_cell(expected_cell) 不需要当前目标。移动先结算;服务端命中届时格内 HP 最低的 敌方对象,HP 相同时按 UUID 排序;格子为空则返回 SHOT_MISSED。

target 可以是可见的 Unit、Core、UnitView 或 CoreView。SDK 会把目标 UUID 和当前位置一起写入命令。只传 UUID 或 UUID 字符串时,必须同时传 expected_cell。

服务端仍会按照游戏规则结算射击。命令能成功构造,不代表一定命中。

Core 控制接口​

Core 控制对象有这些成员:

成员类型或签名
viewCoreView
idUUID
owner_usernamestr
positionPosition
hpint
shieldint
spawn(unit_type)生产 WORKER、VANGUARD 或 RANGER。
heal()战斗后恢复 Core HP。
repair_shield()消耗资源修复护盾。
start_move(direction)开始移动 Core。
cancel_move()取消 Core 当前的移动。
pickup_beacon()拾取当前格的信标。
drop_beacon()放下携带的信标。
self_destruct()战斗后销毁 Core、库存和所有己方 Unit,然后进入普通重生流程。
wait()明确提交 WAIT。
clear_action()清掉 Core 的待提交动作。

Core 也只有一个动作槽。后调用的方法会替换之前排好的动作。

Core 自毁在迁移中也有效,不检查资源、Unit 数量或冷却。战斗摧毁优先;否则 Core 销毁 库存和全军,让 Cargo 与 Beacon 掉落,不产生摧毁归属或战利品,并立即进入普通重生流程。

状态模型​

PlayerState​

字段类型
statusPlayerStatus
respawn_at_tick`int
resourcesint
populationint
champion_beaconChampionBeacon
objects`tuple[TerrainView
eventstuple[ResolutionEvent, ...]

每个字段的含义和视野规则见状态模型。

对象模型​

模型主要字段
UnitViewkind、id、controlled、position、hp、unit_type、cargo
CoreViewkind、id、owner_username、controlled、position、hp、shield、state、移动字段
TerrainViewkind、positions;RESOURCE 表示当前可见的可用位置
ChampionBeaconposition、status、carrier_id

控制类(Worker、Vanguard、Ranger、Core)是受控对象的便捷接口。敌方对象仍然是 不可变的 UnitView 或 CoreView。

每个 CoreView 都有 owner_username,值不含 @。显示时写成 f"@{core.owner_username}"。Unit 没有这个字段,也不会暴露所属玩家。

ResolutionEvent​

字段类型
event_idUUID
tickint
event_typestr
reason_code`str
actor_id`UUID
target_id`UUID
position`Position
values`dict[str, Any]
resource_amount`int
core_resource_capture`CoreResourceCapture
healing`HealingResult
harvest_source`HarvestSource

事件名和原因码保留为字符串,这样服务端以后新增值时,旧版 SDK 不会直接崩掉。具体 含义见结算结果。

其中 HARVEST_FAILED/RESOURCE_DEPLETED 表示同 Tick 有 UUID 更低的合格 Worker 消耗了被竞争的资源点。resource_amount 可以读取 CORE_RESOURCES_CAPTURED、CORE_RESOURCE_OVERFLOW_DESTROYED、DEPOSIT_SUCCEEDED、 WORKER_CARGO_DROPPED 和 HARVEST_SUCCEEDED 中的正数 amount。 core_resource_capture 会把格式正确的 CORE_RESOURCES_CAPTURED 解析成带 amount、available、destroyed 和 capacity 的类型化模型。满仓时 amount 可以为零,并且始终满足 amount + destroyed == available。 healing 会把成功的 Unit 或 Core 恢复解析成带 amount、恢复后 hp 和 cost 的 类型化模型。恢复失败时它是 None,具体原因读取 reason_code。 harvest_source is HarvestSource.DROPPED_CARGO 表示正在回收掉落资源; HarvestSource.RESOURCE_NODE 表示普通自然资源采集。不适用或无法识别的值会返回 None。

规则辅助函数​

from arena_hero import (
CORE_RESOURCE_CAPACITY_PER_UNIT,
CORE_RESOURCE_MINIMUM_CAPACITY,
UNIT_BASE_COSTS,
UnitType,
core_resource_capacity,
unit_cost,
)

CORE_RESOURCE_CAPACITY_PER_UNIT 的值是 5。 CORE_RESOURCE_MINIMUM_CAPACITY 的值是 10。 core_resource_capacity(population) 返回 max(10, population * 5);人口为负数时会报错。 UNIT_BASE_COSTS 是只读映射,Worker、Vanguard、Ranger 分别为 5、10、12。 unit_cost(unit_type, population) 使用当前精确生产公式,并拒绝负人口:

exponent = max(0, floor((population - 20) / 5) + 1)
price = round_half_up(base_price × (13 / 10)^exponent)

只在最终结果上舍入一次。第 21 个 Unit 是第一个涨价的 Unit。实际结算价格以 CORE_SPAWN_SUCCEEDED.values.cost 和 CORE_SPAWN_FAILED/INSUFFICIENT_RESOURCES.values.required 为准。

Tick、Received 和 Accepted​

模型字段
Ticktick
Receivedtick、source、received_at、plan
Acceptedaccepted、tick、source、received_at

Accepted 是 HTTP 202 确认。Received 是 WebSocket 广播给这名玩家所有在线客户端 的权威计划。

命令模型​

大多数代码应该通过 Turn 排动作。需要直接控制协议模型时,也可以自己构造:

from uuid import UUID

from arena_hero import CommandPlan, Direction, MoveAction


plan = CommandPlan(
tick=10583,
unit_actions={
UUID("9d3e4941-2816-4a39-a220-df8cd95e877d"): MoveAction(
direction=Direction.UP
)
},
)

accepted = game.submit(plan)

公开的 Unit 动作模型:

Unit 动作必填数据
WaitAction无
MoveActiondirection
HarvestAction无
DepositAction无
SweepActiondirection
ShootActionexpected_cell;可选 target_id
PickupBeaconAction无
DropBeaconAction无
SelfDestructAction无
HealAction无
Core 动作必填数据
WaitAction无
SpawnActionunit_type
RepairShieldAction无
HealAction无
StartMoveActiondirection
CancelMoveAction无
PickupBeaconAction无
DropBeaconAction无
SelfDestructAction无

CommandPlan.unit_actions 是 Unit UUID 到动作的映射。 CommandPlan.core_action 是一个 Core 动作,也可以是 None。

枚举​

枚举可选值
DirectionUP、DOWN、LEFT、RIGHT
UnitTypeWORKER、VANGUARD、RANGER
PlayerStatusACTIVE、RESPAWNING
CoreStateNORMAL、MOVING
CommandSourceAGENT、MANUAL
BeaconStatusGROUND、CARRIED
HarvestSourceRESOURCE_NODE、DROPPED_CARGO

Direction.delta 会返回对应的 (dx, dy)。

异常​

所有 SDK 异常都继承自 ArenaHeroError。

异常含义
ConfigurationError构造参数或幂等键无效、客户端已关闭,或者同时启动了两个迭代器。
AuthenticationErrorWebSocket 握手拒绝了 API Key。
PolicyViolationErrorWebSocket 以策略违规码 1008 关闭。
ProtocolError服务端消息不符合公开协议。
APIError命令 API 返回了结构化拒绝。
TransportError安全重试用完后,网络操作仍然失败。
TurnClosedError代码试图修改已经过期的 Turn。
InvalidActionError本地目标或动作无法安全表示成协议命令。

APIError 提供 status_code、error、message 和 details。

游戏里的动态失败不是 Python 异常。它们会作为 ResolutionEvent 出现在下一次 Turn.events 里。

连接行为​

SDK 会:

  • 只在 Authorization 请求头中发送 API Key;
  • 关闭 WebSocket 消息压缩,保持与服务端约定一致;
  • 自动处理协议层 Ping/Pong;
  • 对临时 WebSocket 故障使用带随机抖动的指数退避重连;
  • 遇到关闭码 1008 后停止重连;
  • 把每个 state 都当成完整替换;
  • 对结果不确定的命令提交,使用相同字节和同一个幂等键安全重试。

服务端命令窗口是全局的,Turn 到达时可能已经过去一部分。计划算好就尽快提交。完整的 时间与恢复规则见可靠的命令循环。