Documentation
¶
Overview ¶
Package ability 提供泛型技能/效果管线(Ability Pipeline)原语,类似虚幻引擎的 GAS (Gameplay Ability System)的核心骨架,但遵循"机制而非策略"——只提供管线调度机制, 不绑定具体伤害公式/buff 类型/特效系统。
解决的问题:MOBA/RPG/ACT 类游戏中,技能数量常达数百个,但底层运作模式高度一致: "判定前置条件 → 扣资源 → 分阶段执行(蓄力/施法/释放) → 产出效果(伤害/buff) → 发送表现提示(特效/音效)"。没有统一管线时,每个技能各写一套 if/else,维护成本 爆炸且策划无法配表驱动。
核心管线:
Ability 定义 运行时 ┌──────────┐ ┌──────────────┐ │ CanUse? │──检查前置──────────▶│ 资源扣除 │ │ Cost │ │ │ │ Phases[] │──按序执行──────────▶│ Phase.Tick() │──▶ PhaseResult │ │ │ .Effects │ │ │ │ │ .Cues │ ├─ Effect (业务消费) │ │ │ .Status │ └─ Cue (客户端消费) └──────────┘ └──────────────┘
泛型参数:
- E: 实体类型(施法者/目标,业务定义);
- R: 资源类型(蓝量/怒气/弹药,业务定义)。
与相邻原语的关系:
- gameloop/match 的 OnTick 中调用 Runner.Tick(frame) 驱动管线;
- fsm 管理实体的宏观状态(正常/眩晕/死亡),ability 管理"施法中"的微观阶段;
- cooldown 可用于管线外的技能冷却追踪,但 Runner 内置了 CD 管理;
- fixedpoint 可用于 Effect 的伤害公式计算以保证确定性;
- eventbus 消费 Effect/Cue(如任务系统监听"造成伤害"事件)。
并发安全:Runner 不加锁(由单个游戏循环驱动,每实体一个)。 零值不可用:用 NewRunner 构造。
Index ¶
- type CastError
- type CastState
- type Cost
- type Cue
- type Effect
- type Phase
- type PhaseFunc
- type PhaseResult
- type PhaseStatus
- type ResourceChecker
- type ResourceFunc
- type Runner
- func (r *Runner[E, R]) Cancel()
- func (r *Runner[E, R]) Cast(skill *Spec[E, R], frame uint64) error
- func (r *Runner[E, R]) CooldownRemaining(skillID string, frame uint64) int
- func (r *Runner[E, R]) CurrentSkill() string
- func (r *Runner[E, R]) IsIdle() bool
- func (r *Runner[E, R]) State() CastState
- func (r *Runner[E, R]) Tick(frame uint64) TickResult[E]
- type Spec
- type TickResult
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cue ¶
type Cue struct {
Tag string // 提示类型(如 "vfx"、"sfx"、"camera_shake")
Asset string // 资源标识(特效/音效文件名)
Value float64 // 参数(强度、持续时间等)
}
Cue 是客户端表现提示(特效、音效、镜头震动)。 服务器产出后广播给客户端,客户端据此播放表现,不影响逻辑状态。
type Effect ¶
type Effect[E any] struct { Tag string // 效果类型标签 Value float64 // 效果数值(伤害值、治疗量、持续时间等) Source E // 施法者 Target E // 受击者 }
Effect 是技能产出的逻辑效果(伤害、治疗、buff/debuff、位移等)。 由业务层消费:修改 HP、应用 buff、触发事件等。 Tag 用于分类(如 "damage"、"heal"、"stun"),Value 是效果量(含义由 Tag 决定), Source/Target 标识来源与目标。
type Phase ¶
type Phase[E any] interface { // Tick 推进阶段。返回 PhaseComplete 时管线自动进入下一阶段; // 返回 PhaseCancelled 时整个技能中止。 Tick(frame uint64) PhaseResult[E] // Reset 重置阶段内部状态(技能再次使用时调用)。 Reset() }
Phase 是技能执行的一个阶段。业务实现此接口定义具体行为。 Tick 每帧被调用(Running 期间),frame 是全局帧号。 管线保证同一时刻只有一个 Phase 在 Tick。
type PhaseFunc ¶
type PhaseFunc[E any] func(frame uint64) PhaseResult[E]
PhaseFunc 把普通函数适配为 Phase(无状态阶段的简写)。
func (PhaseFunc[E]) Tick ¶
func (f PhaseFunc[E]) Tick(frame uint64) PhaseResult[E]
type PhaseResult ¶
type PhaseResult[E any] struct { Status PhaseStatus Effects []Effect[E] Cues []Cue }
PhaseResult 是阶段单次 Tick 的产出。
type PhaseStatus ¶
type PhaseStatus int
PhaseStatus 是阶段的执行状态。
const ( // PhaseRunning 阶段尚在进行中,下次 Tick 继续。 PhaseRunning PhaseStatus = iota // PhaseComplete 阶段已完成,管线推进到下一阶段。 PhaseComplete // PhaseCancelled 阶段被取消(打断/眩晕),整个技能中止。 PhaseCancelled )
type ResourceChecker ¶
type ResourceChecker[E, R any] interface { // CanAfford 检查 caster 是否有足够资源支付 costs。 CanAfford(caster E, costs []Cost[R]) bool // Spend 扣除资源。调用方保证已通过 CanAfford 检查。 Spend(caster E, costs []Cost[R]) }
ResourceChecker 检查并扣除资源(业务实现)。
type ResourceFunc ¶
type ResourceFunc[E, R any] struct { CheckFn func(caster E, costs []Cost[R]) bool SpendFn func(caster E, costs []Cost[R]) }
ResourceFunc 用两个函数适配 ResourceChecker。
func (ResourceFunc[E, R]) CanAfford ¶
func (r ResourceFunc[E, R]) CanAfford(caster E, costs []Cost[R]) bool
func (ResourceFunc[E, R]) Spend ¶
func (r ResourceFunc[E, R]) Spend(caster E, costs []Cost[R])
type Runner ¶
type Runner[E, R any] struct { // contains filtered or unexported fields }
Runner 为单个实体管理技能施放生命周期:冷却 → 资源检查 → 分阶段执行。 每帧调用 Tick(frame) 驱动。非并发安全(每实体一个,由游戏循环串行驱动)。
func NewRunner ¶
func NewRunner[E, R any](caster E, res ResourceChecker[E, R]) *Runner[E, R]
NewRunner 创建技能管线运行时。caster 是施法者实体,res 是资源检查器。
func (*Runner[E, R]) Cast ¶
Cast 尝试施放技能。成功则进入 Casting 状态(后续 Tick 驱动阶段执行)。 frame 是当前帧号,用于冷却判定。失败返回 CastError。
func (*Runner[E, R]) CooldownRemaining ¶
CooldownRemaining 返回技能剩余冷却帧数(无冷却或已就绪返回 0)。
func (*Runner[E, R]) CurrentSkill ¶
CurrentSkill 返回当前施放的技能 ID(空闲时为空)。
func (*Runner[E, R]) Tick ¶
func (r *Runner[E, R]) Tick(frame uint64) TickResult[E]
Tick 驱动管线一帧。由游戏循环每帧调用。