Files
test/agent-skills/04-architecture-understanding.md
2026-02-24 09:50:08 +07:00

6.7 KiB

Architecture Understanding

System Overview

The Skill GFX system manages visual effects when skills are cast in Perfect World. It handles projectile flight, hit effects, and various movement patterns.

High-Level Flow

Player Casts Skill
    ↓
CECAttacksMan.AddSkillAttack()
    ↓
CECAttackEvent.Tick() - Timing system
    ↓
CECAttackEvent.DoFire() - Triggers when skill fires
    ↓
A3DSkillGfxComposerMan.Play() - Finds composer by skill ID
    ↓
A3DSkillGfxComposer.Play() - Iterates targets, calls AddOneTarget
    ↓
A3DSkillGfxMan.AddSkillGfxEvent() - Creates GFX event
    ↓
A3DSkillGfxEvent.Tick() - State machine (Wait → Flying → Hit → Finished)
    ↓
CGfxMoveBase.TickMove() - Updates projectile position
    ↓
Unity VFX System - Renders effects

Core Components

1. Attack Event System

  • CECAttacksMan: Manages all attack events
  • CECAttackEvent: Individual attack event, handles timing
  • Purpose: Determines WHEN to trigger GFX (based on skill timing)

2. GFX Composer System

  • A3DSkillGfxComposerMan: Manages composers, loads from SkillStub
  • A3DSkillGfxComposer: Contains GFX paths and parameters for a skill
  • Purpose: Maps skill ID → GFX configuration

3. GFX Event System

  • A3DSkillGfxMan: Base manager (abstract)
  • A3DSkillGfxEvent: Base event class (abstract)
  • CECSkillGfxMan: Unity-specific manager (inherits A3DSkillGfxMan)
  • CECSkillGfxEvent: Unity-specific event (inherits A3DSkillGfxEvent)
  • Purpose: Manages active GFX instances and state machine

4. Movement System

  • CGfxMoveBase: Abstract base class for movement patterns
  • CGfxLinearMove: Straight-line projectile
  • CGfxOnTargetMove: Instant hit (no flight)
  • CGfxParabolicMove: Arc trajectory
  • CGfxMissileMove: Homing missile
  • Purpose: Calculates projectile position over time

Class Hierarchy

Movement Classes

CGfxMoveBase (abstract)
├── CGfxLinearMove
├── CGfxOnTargetMove
├── CGfxParabolicMove
├── CGfxMissileMove
├── CGfxMeteoricMove
├── CGfxHelixMove
├── CGfxCurvedMove
├── CGfxAccMove
├── CGfxLinkMove
└── CGfxRandMove

Event Classes

A3DSkillGfxMan (abstract)
└── CECSkillGfxMan (Unity implementation)

A3DSkillGfxEvent (abstract)
└── CECSkillGfxEvent (Unity implementation)

Composer Classes

A3DSkillGfxComposerMan
└── A3DSkillGfxComposer

State Machine

A3DSkillGfxEvent States

  1. enumWait: Waiting for delay time

    • Increments m_dwCurSpan
    • Transitions to enumFlying when delay expires
  2. enumFlying: Projectile in flight

    • Calls m_pMoveMethod.TickMove() each frame
    • Updates GFX position
    • Transitions to enumHit when TickMove() returns true OR timeout
  3. enumHit: Hit effect playing

    • Plays hit GFX at target position
    • Transitions to enumFinished when hit GFX completes
  4. enumFinished: Event complete

    • Event can be recycled/pooled

Data Flow

Skill Configuration

SkillStub (C# data structure)
    ↓
A3DSkillGfxComposer.Load(SkillStub)
    ↓
Populates:
- Fly GFX path
- Hit GFX path
- Movement mode
- Fly time
- Scales
- Parameters

Event Creation

A3DSkillGfxComposer.Play()
    ↓
For each target:
    A3DSkillGfxMan.AddSkillGfxEvent(
        composer,
        hostID,
        targetID,
        flyGfxPath,
        hitGfxPath,
        flyTimeSpan,
        moveMode,
        ...
    )
    ↓
Creates A3DSkillGfxEvent:
    - Sets composer
    - Creates movement method (CGfxMoveBase.CreateMoveMethod)
    - Sets parameters
    - Initializes state to enumWait

Runtime Update

A3DSkillGfxMan.Tick() (called each frame)
    ↓
For each active event:
    A3DSkillGfxEvent.Tick(deltaTime)
        ↓
        State machine:
        - enumWait: Check delay
        - enumFlying: 
            - m_pMoveMethod.TickMove()
            - Update GFX position
            - Check timeout
        - enumHit: Check hit GFX completion
        - enumFinished: Mark for cleanup

Key Relationships

A3DSkillGfxEvent → CGfxMoveBase

  • Relationship: Composition
  • Field: m_pMoveMethod : CGfxMoveBase
  • Usage: Delegates movement calculation to movement method
  • Creation: CGfxMoveBase.CreateMoveMethod(mode)

A3DSkillGfxEvent → A3DSkillGfxComposer

  • Relationship: Reference
  • Field: m_pComposer : A3DSkillGfxComposer
  • Usage: Accesses GFX paths and parameters
  • Set: SetComposer(composer)

A3DSkillGfxMan → A3DSkillGfxEvent

  • Relationship: Container/Manager
  • Storage: List/array of active events
  • Management: Creates, updates, destroys events
  • Pooling: Reuses finished events

CECSkillGfxEvent → Unity VFX

  • Relationship: Unity integration
  • Fields: m_flyGfxInstance : GameObject, m_hitGfxInstance : GameObject
  • Usage: Instantiates Unity particle systems/prefabs
  • Loading: Uses Addressables for async loading

Memory Management

C++ Pattern

  • Manual new/delete
  • Object pooling for events
  • GFX caching system

C# Pattern

  • Automatic garbage collection
  • Object pooling still recommended for performance
  • Unity Addressables for asset loading

Threading Model

  • C++: Single-threaded game loop
  • C#: Unity main thread (MonoBehaviour.Update)
  • Async: Addressables loading can be async, but GFX updates on main thread

Performance Considerations

  1. Object Pooling: Reuse A3DSkillGfxEvent instances
  2. GFX Caching: Cache loaded GFX prefabs
  3. Batch Updates: Update all events in single loop
  4. Early Exit: Skip finished events quickly
  5. LOD System: Use m_bGfxUseLod for distance-based quality

Integration Points

With Attack System

  • Trigger: CECAttackEvent.DoFire() calls A3DSkillGfxComposerMan.Play()
  • Timing: GFX starts when skill "fires" (not when cast begins)

With Character System

  • Position: GetTargetCenter() gets character position
  • Tracking: m_bTraceTarget enables position updates during flight
  • Hooks: Future feature for bone attachment

With Unity VFX

  • Loading: Addressables async loading
  • Instantiation: Unity GameObject/Prefab system
  • Rendering: Unity Particle System or custom VFX

Extension Points

New Movement Modes

  1. Create new class inheriting CGfxMoveBase
  2. Implement StartMove() and TickMove()
  3. Add case to CreateMoveMethod()

New Event Types

  1. Create new class inheriting A3DSkillGfxEvent or CECSkillGfxEvent
  2. Override GetTargetCenter() and other virtual methods
  3. Implement Unity-specific rendering

Custom GFX Systems

  1. Override LoadFlyGfx() / LoadHitGfx()
  2. Implement custom VFX loading/instantiation
  3. Use Unity Addressables or custom asset system