Skip to content
bFormat edited this page Apr 28, 2025 · 2 revisions

SkillScript 위키

소개

SkillScript는 Bukkit/Spigot 서버 관리자와 개발자가 YAML 파일을 사용하여 커스텀 스킬을 쉽게 만들 수 있도록 설계된 플러그인입니다. 복잡한 Java 코딩 없이 다양한 게임 내 동작(액션)을 조합하여 강력하고 유연한 스킬을 구현할 수 있습니다.

시작하기: 스크립트 기본 구조

SkillScript 스크립트는 플러그인 폴더 내 scripts/ 디렉토리에 .yaml 또는 .yml 확장자를 가진 파일로 저장됩니다. 각 파일은 하나의 스킬을 정의하며, 파일 이름(확장자 제외)이 해당 스킬의 고유한 이름으로 사용됩니다.

예를 들어, Fireball.yaml이라는 파일을 생성하면, /cast Fireball 명령어로 해당 스킬을 사용할 수 있습니다.

스크립트 파일의 기본적인 구조는 다음과 같습니다:

# scripts/Fireball.yaml

# 최상위 레벨에 바로 스킬 트리거를 정의합니다.
OnCast: # 플레이어가 스킬을 시전했을 때(/cast Fireball) 발동되는 트리거입니다.
  # 여기에 이 트리거가 발동될 때 순서대로 실행될 액션 목록을 정의합니다.
  - Variable.SetVariable: { name: "projectileSpeed", value: 1.5 }
  - TargetBehaviour.SendMessage:
      message: "&cLaunching Fireball!"
  - TargetBehaviour.PlayEffect:
      location: "@CasterLocation"
      particle: "LAVA"
      offset: { y: 1.5 } # 시전자 머리 위에서 발사되는 것처럼 보이게
  # ... Fireball 관련 다른 액션들 ...

# OnHit: # (향후 지원 예정) 스킬 투사체 등이 적중했을 때
#   - TargetBehaviour.Damage: { amount: 10 }
#   - TargetBehaviour.PlayEffect: { particle: "EXPLOSION_LARGE" }

# 다른 트리거가 있다면 여기에 추가...
  • 하나의 파일은 하나의 스킬을 나타냅니다. 여러 스킬을 만들려면 여러 YAML 파일을 생성하세요. (예: Heal.yaml, Teleport.yaml)
  • 파일의 최상위 레벨에는 스킬이 발동될 조건을 나타내는 트리거(Trigger) 키(예: OnCast, OnHit)가 위치합니다.
  • 각 트리거 아래에는 실행될 액션(Action)들의 목록(List)이 YAML 리스트 형식(-)으로 나열됩니다.
  • 현재 주로 사용되는 트리거는 /cast 명령어와 연동되는 OnCast 입니다.

액션 (Actions)

액션은 스킬이 수행하는 개별적인 동작 단위입니다. 각 액션은 정해진 이름과 필요한 파라미터(Parameters)를 가집니다.

기본 형식:

- ActionRegistryName: # ActionRegistry에 등록된 액션의 전체 이름 (예: TargetBehaviour.SendMessage)
    parameter1: value1  # 해당 액션이 요구하는 파라미터와 값
    parameter2: value2
    # ...

파라미터 타입:

액션 파라미터는 다양한 데이터 타입을 가질 수 있습니다.

  • String: 문자열. 보통 따옴표는 생략 가능하나, 특수문자가 포함되거나 명확성을 위해 사용하는 것이 좋습니다. (예: message: "&aHello World!")
  • Integer: 정수 숫자. (예: duration: 20)
  • Double: 실수 숫자. (예: amount: 10.5)
  • Boolean: 논리값. true 또는 false. (예: ignoreArmor: true)
  • Location: 게임 내 위치 좌표. 변수, 셀렉터, 또는 맵 형식으로 지정 가능. (자세한 내용은 아래 참조)
  • Vector: 3차원 벡터 (방향 또는 오프셋). 변수, 셀렉터, 리스트 [x, y, z], 또는 맵 {x: val, y: val, z: val} 형식으로 지정 가능.
  • List: 항목의 목록. (예: tags: ["mytag", "effect_tag"])
  • Map: 키-값 쌍의 집합. (예: particleData: { count: 5, speed: 0.1 })
  • Material: 마인크래프트 아이템/블록 종류 이름 (대소문자 구분 없음). (예: material: "DIAMOND_SWORD")

셀렉터 및 키워드 (Selectors & Keywords)

스크립트 실행 시점의 동적인 값을 참조하기 위해 @ 기호로 시작하는 특별한 키워드(셀렉터)를 사용할 수 있습니다.

기본 셀렉터:

  • @Caster: 스킬을 시전한 플레이어 엔티티.
  • @Target 또는 @CurrentTarget: 현재 액션의 대상이 되는 엔티티 또는 위치. (액션에 따라 달라짐, Target.* 액션으로 설정 가능)
  • @CastLocation: 스킬이 처음 시전된 위치 (Location).
  • @CasterLocation: 현재 시전자의 실시간 위치 (Location).
  • @TargetLocation 또는 @CurrentTargetLocation: 현재 대상의 위치 (Location). 대상이 엔티티가 아니면 동작하지 않을 수 있음.
  • @CastDirection: 스킬이 처음 시전된 방향 (Vector).
  • @CasterDirection: 현재 시전자의 실시간 방향 (Vector).
  • @TargetDirection 또는 @CurrentTargetDirection: 현재 대상의 방향 (Vector). 대상이 엔티티여야 함.

속성 접근:

. (점)을 사용하여 셀렉터가 참조하는 객체의 특정 속성 값을 가져올 수 있습니다. (주로 variable.calculate 액션의 표현식 내에서 사용)

  • Location 속성:
    • @CasterLocation.X, @TargetLocation.Y, @CastLocation.Z
  • Entity 속성:
    • @Caster.X, @Target.Y, @Caster.Z (엔티티의 현재 위치)
    • @Caster.Yaw, @Target.Pitch (엔티티의 방향)
    • @Caster.Health, @Target.Health (엔티티의 현재 체력, Damageable이어야 함)
    • @Caster.MaxHealth, @Target.MaxHealth (엔티티의 최대 체력, LivingEntity이어야 함)
    • (향후 추가 가능: @Caster.FoodLevel 등)

변수 (Variables)

스크립트 실행 중에 데이터를 임시로 저장하고 사용하기 위한 기능입니다. 변수는 스크립트 실행 컨텍스트 내에서 유효하며, 다른 스크립트 실행에 영향을 주지 않습니다. 변수 이름은 대소문자를 구분하지 않습니다.

변수 설정:

  • Variable.SetVariable 액션 사용:
    - Variable.SetVariable:
        name: "myCounter" # 변수 이름
        value: 0          # 저장할 값 (모든 파라미터 타입 가능)
    - Variable.SetVariable:
        name: "targetEntity"
        value: "@Target"  # 셀렉터 결과(Entity)를 저장
    - Variable.SetVariable:
        name: "startPos"
        value: "@CasterLocation" # 셀렉터 결과(Location)를 저장
  • Variable.Calculate 액션 사용 (숫자): 수학적 계산 결과를 저장합니다. (아래 '표현식' 섹션 참조)
    - Variable.Calculate:
        variable: "damageMultiplier"
        expression: "1.5 + @Caster.Health / 20"
  • Variable.GetLocation, Variable.GetDirection, Variable.GetOffsetLocation 액션 사용: 특정 위치/방향 관련 값을 계산하여 변수에 저장합니다.

변수 사용:

  • 액션 파라미터 값으로 사용: 대부분의 액션 파라미터에 변수 이름을 직접 지정하여 해당 변수의 값을 사용할 수 있습니다. (단, 해당 파라미터가 요구하는 타입과 변수 타입이 일치해야 함)
    - Variable.SetVariable: { name: "targetToDamage", value: "@Target" }
    - Variable.SetVariable: { name: "calculatedDamage", value: 15.0 }
    - TargetBehaviour.Damage:
        target: targetToDamage     # Entity 타입 변수 사용
        amount: calculatedDamage # Double 타입 변수 사용
  • Variable.Calculate 표현식 내에서 사용: 숫자 타입 변수를 수학 표현식 내에서 사용할 수 있습니다.
    - Variable.Calculate:
        variable: "finalDamage"
        expression: "baseDamage * damageMultiplier + bonusDamage" # baseDamage, damageMultiplier, bonusDamage 변수 사용

문자열 내 값 삽입 (플레이스홀더)

TargetBehaviour.SendMessage와 같이 문자열을 사용하는 일부 액션에서는 문자열 내에 변수 값이나 셀렉터 값을 직접 삽입하여 동적인 내용을 만들 수 있습니다. 다음과 같은 플레이스홀더 형식을 사용합니다.

  • {var:변수이름}: 지정된 이름의 변수 값을 문자열로 변환하여 삽입합니다.
  • {sel:셀렉터.속성}: 지정된 셀렉터와 속성을 평가하여 그 값을 문자열로 변환하여 삽입합니다.

예시:

- Variable.SetVariable: { name: "kills", value: 10 }
- Target.SetSelf: {}
- TargetBehaviour.SendMessage:
    target: "@Caster"
    message: "&aYour Stats: &fHP: {sel:@Caster.Health}/{sel:@Caster.MaxHealth}, Kills: {var:kills}"
    # 예상 출력 (체력이 15/20 이고 kills 변수가 10일 때):
    # Your Stats: HP: 15/20, Kills: 10

- Variable.GetLocation: { target: "@Target", variable: "enemyPos" }
- TargetBehaviour.SendMessage:
    target: "@Caster"
    message: "&eTarget spotted at: {var:enemyPos}"
    # 예상 출력 (enemyPos 변수가 Location 객체일 때):
    # Target spotted at: world, 123.5, 65.0, 45.2

주의사항:

  • 플레이스홀더 안의 변수명이나 셀렉터 문자열에는 공백이 포함될 수 없습니다.
  • 변수나 셀렉터를 찾을 수 없는 경우, 기본적으로 플레이스홀더 문자열({var:nonExistentVar})이 그대로 남거나 빈 문자열로 대체될 수 있습니다. (정확한 동작은 플러그인 설정이나 버전에 따라 다를 수 있음)
  • 현재 모든 액션의 모든 문자열 파라미터에서 이 기능이 지원되는 것은 아닙니다. 주로 메시지, 명령어 관련 액션에서 지원됩니다. (지원 여부는 각 액션 설명 참조)

표현식 (Expressions) - variable.calculate

Variable.Calculate 액션은 강력한 수학 표현식 계산 기능을 제공합니다. 내부적으로 mXparser 라이브러리를 사용합니다.

구문:

- Variable.Calculate:
    variable: "resultVariableName" # 계산 결과를 저장할 변수 이름
    expression: "Your mathematical expression here" # 계산할 표현식 문자열

표현식 내 사용 가능 요소:

  • 숫자: 10, -5.2, 1.2E3
  • 기본 연산자: +, -, *, / (나눗셈), ^ (거듭제곱), % (나머지)
  • mXparser 내장 함수:
    • 삼각함수: sin(rad), cos(rad), tan(rad), asin(x), acos(x), atan(x) 등 (각도는 라디안 사용)
    • 지수/로그: exp(x), log(base, x), ln(x), log2(x), log10(x)
    • 기타 유용 함수: sqrt(x) (제곱근), abs(x) (절댓값), round(value, places) (반올림), floor(x) (내림), ceil(x) (올림), min(a, b, ...) (최솟값), max(a, b, ...) (최댓값), rand() (0~1 사이 난수), if(condition, true_expr, false_expr) 등 매우 다양합니다. (자세한 내용은 mXparser 문서 참조)
  • mXparser 내장 상수: pi, e, [deg] (각도->라디안 변환), [rad] (라디안->각도 변환) 등
  • SkillScript 셀렉터: 표현식 문자열 안에 @Caster.Health, @TargetLocation.Y 와 같이 직접 작성하여 현재 값을 사용합니다.
  • SkillScript 변수: 표현식 문자열 안에 변수 이름을 직접 작성하여 해당 변수의 숫자 값을 사용합니다. (예: myVar, calculatedDamage)

예시:

- Variable.Calculate:
    variable: "launchAngle"
    expression: "atan(@TargetLocation.Y - @CasterLocation.Y, sqrt( (@TargetLocation.X-@CasterLocation.X)^2 + (@TargetLocation.Z-@CasterLocation.Z)^2 )) * [rad]" # 라디안 결과를 각도로 변환
- Variable.Calculate:
    variable: "randomOffset"
    expression: "(rand() - 0.5) * 10" # -5 ~ 5 사이의 랜덤 값
- Variable.Calculate:
    variable: "adjustedHealth"
    expression: "max(1, @Caster.Health - receivedDamage)" # 최소 1 보장

사용 가능한 액션 목록 (Action Reference)

여기에 ActionRegistry에 등록된 모든 액션의 이름, 파라미터, 설명을 상세히 기술합니다.


(각 액션별 상세 설명 추가)

  • ControlFlow.Delay
    • duration (Integer, Required): 지연시킬 시간 (서버 틱 단위, 1초 = 20틱).
    • 설명: 스크립트 실행을 지정된 시간 동안 일시 중지합니다.
  • ControlFlow.IfCondition
    • condition (Boolean/String/Number, Required): 평가할 조건. true, "true", 1 등은 참으로, 나머지는 거짓으로 간주됩니다. (향후 표현식 지원 예정)
    • Then (List, Optional): 조건이 참일 때 실행할 액션 목록.
    • Else (List, Optional): 조건이 거짓일 때 실행할 액션 목록.
    • 설명: 조건에 따라 다른 액션 흐름을 실행합니다. (주의: 현재 중첩된 제어 흐름(If, Delay 등) 실행에 제약이 있을 수 있습니다.)
  • Object.CreateObject
    • initialLocation (Location, Required): 오브젝트가 생성될 초기 위치.
    • objectId (String, Optional): 생성될 오브젝트의 고유 ID (지정하지 않으면 자동 생성될 수 있음).
    • lifespan (Integer, Optional): 오브젝트 지속 시간 (틱). -1 또는 미지정 시 영구.
    • appearance (Map, Optional): 오브젝트 외형 관련 데이터 (파티클, 모델 등).
    • initialVector (Vector, Optional): 오브젝트의 초기 이동 벡터.
    • shapeDefinition (Map, Optional): 오브젝트의 충돌/형태 정의.
    • tags (List, Optional): 오브젝트에 부여할 태그 목록.
    • ObjectBehaviour.* (List, Optional): 오브젝트 자체의 동작 정의 (예: ObjectBehaviour.OnTick, ObjectBehaviour.OnCollision).
    • 설명: 게임 월드에 스킬 오브젝트(투사체, 장판 등)를 생성합니다. (주의: 현재 실제 오브젝트 생성 및 관리 로직은 구현되지 않았습니다.)
  • Target.SetSelf
    • (파라미터 없음)
    • 설명: 현재 액션 대상을 스킬 시전자 자신(@Caster)으로 설정합니다.
  • TargetBehaviour.Damage
    • target (Entity Selector/Variable, Optional): 피해를 입힐 대상. 미지정 시 현재 대상(@Target).
    • amount (Double, Required): 입힐 피해량 (0보다 커야 함).
    • ignoreArmor (Boolean, Optional): 방어력 무시 여부 (기본값 false). (주의: Bukkit API 제약으로 완벽히 동작하지 않을 수 있음)
    • source (Entity Selector/Variable, Optional): 피해 발생원. 미지정 시 시전자(@Caster).
    • 설명: 대상 엔티티에게 피해를 입힙니다.
  • TargetBehaviour.PlayEffect
    • location (Location Selector/Variable, Required): 효과가 재생될 중심 위치.
    • offset (Vector Selector/Variable/Literal, Optional): location에서 추가될 위치 오프셋.
    • particle (String, Optional): 재생할 파티클 이름 (Bukkit Particle enum 이름).
    • particleData (Map, Optional): 파티클 세부 설정 (아래 참조).
    • sound (String, Optional): 재생할 사운드 이름 (Bukkit Sound enum 이름).
    • soundData (Map, Optional): 사운드 세부 설정 (아래 참조).
    • 설명: 지정된 위치에 파티클 효과나 사운드를 재생합니다.
    • particleData 하위 파라미터:
      • count (Integer, Optional, 기본값 1): 파티클 생성 개수.
      • speed (Double, Optional, 기본값 0.0): 파티클 속도/퍼짐 정도.
      • offset (Vector, Optional): 파티클 생성 위치의 분산 오프셋 (Location 오프셋과 다름!). 예: {x: 0.5, y: 0.5, z: 0.5}
      • color (Map, Optional, DustOptions 전용): {r: 0-255, g: 0-255, b: 0-255, size: float}.
      • material (String, Optional, 아이템/블록 파티클 전용): Material 이름.
    • soundData 하위 파라미터:
      • volume (Float, Optional, 기본값 1.0): 사운드 크기.
      • pitch (Float, Optional, 기본값 1.0): 사운드 높낮이.
  • TargetBehaviour.SendMessage
    • message (String, Required): 전송할 메시지. Bukkit 색상 코드(&) 지원.
    • target (Player/Console Selector/Variable, Optional): 메시지를 받을 대상. 미지정 시 현재 대상(@Target, 플레이어여야 함), 그 다음 시전자(@Caster).
    • 설명: 대상에게 채팅 메시지를 보냅니다.
  • Variable.Calculate
    • variable (String, Required): 계산 결과를 저장할 변수 이름.
    • expression (String, Required): 계산할 수학 표현식. (자세한 내용은 '표현식' 섹션 참조)
    • 설명: 표현식을 계산하여 결과를 변수에 저장합니다.
  • Variable.GetDirection
    • target (Entity/Location Selector/Variable, Required): 방향을 가져올 대상. (예: @Caster, @Target, myLocationVar)
    • variable (String, Required): 결과를 저장할 변수 이름.
    • normalize (Boolean, Optional, 기본값 true): 결과를 단위 벡터(길이 1)로 정규화할지 여부.
    • 설명: 대상의 현재 바라보는 방향(Vector)을 가져와 변수에 저장합니다.
  • Variable.GetLocation
    • target (Entity/Location Selector/Variable, Required): 위치를 가져올 대상. (예: @Caster, @Target, myLocationVar)
    • variable (String, Required): 결과를 저장할 변수 이름.
    • 설명: 대상의 현재 위치(Location)를 가져와 변수에 저장합니다.
  • Variable.GetOffsetLocation
    • baseLocation (Location Selector/Variable, Required): 기준 위치.
    • offset (Vector Selector/Variable/Literal, Required): 더할 오프셋 벡터.
    • variable (String, Required): 계산된 최종 위치를 저장할 변수 이름.
    • 설명: 기준 위치에 오프셋 벡터를 더한 새 위치를 계산하여 변수에 저장합니다.
  • Variable.SetVariable
    • name (String, Required): 설정할 변수의 이름.
    • value (Any, Required): 변수에 저장할 값 (문자열, 숫자, 불리언, 셀렉터 결과 등).
    • 설명: 지정된 이름의 변수에 값을 설정하거나 덮어씁니다.

예제 스크립트

다음은 여러 액션과 변수, 계산을 활용하는 예제 스크립트입니다.

# scripts/examples.yaml
Skills:
  AdvancedProjectile:
    Triggers:
      OnCast:
        # 1. 초기 설정
        - Target.SetSelf: {} # 대상을 시전자로 초기화
        - Variable.SetVariable: { name: "baseDamage", value: 10.0 }
        - Variable.SetVariable: { name: "speedMultiplier", value: 1.2 }
        - Variable.GetLocation: { target: "@Caster", variable: "spawnLoc" }
        - Variable.GetDirection: { target: "@Caster", variable: "spawnDir" } # 정규화된 방향 벡터

        # 2. 시전자 체력 비례 추가 데미지 계산
        - Variable.Calculate:
            variable: "healthBonusDmg"
            expression: "max(0, @Caster.Health / 5)" # 체력 5당 1의 보너스 데미지, 최소 0
        - Variable.Calculate:
            variable: "finalDamage"
            expression: "baseDamage + healthBonusDmg"

        # 3. 발사 위치 조정 (머리 위 약간 앞)
        - Variable.GetOffsetLocation:
            baseLocation: spawnLoc
            offset: { x: 0, y: 1.8, z: 0 } # 눈 높이 근처
            variable: "eyeLoc"
        - Variable.Calculate: # 방향 벡터에 속도 곱하기
            variable: "velocity"
            expression: "spawnDir * speedMultiplier * 20" # mXparser는 벡터*스칼라 자동 지원 안할 수 있음. 확인 필요
            # 만약 위 표현식이 안된다면, 각 요소별 계산 필요:
            # variable: velocityX, expression: spawnDir.X * speedMultiplier * 20
            # variable: velocityY, expression: spawnDir.Y * speedMultiplier * 20
            # variable: velocityZ, expression: spawnDir.Z * speedMultiplier * 20
            # 이후 Vector 생성 액션 필요 (현재 없음)

        # 4. 발사 효과 및 메시지
        - TargetBehaviour.SendMessage:
            message: "&eLaunching projectile! Damage: {var:finalDamage}" # 변수 치환 안됨! 메시지 분리 필요
        - TargetBehaviour.SendMessage:
            target: "@Caster"
            message: "&eCalculated Damage: &f" # 값 부분은 다음 액션에서? (현재 불편함)
            # 또는 최종 데미지를 다음 단계 액션의 파라미터로만 사용

        - TargetBehaviour.PlayEffect:
            location: eyeLoc # 조정된 위치에서 효과 재생
            particle: "FLAME"
            particleData: { count: 20, speed: 0.1, offset: {x: 0.2, y: 0.2, z: 0.2} }
            sound: "ENTITY_GHAST_SHOOT"

        # 5. 실제 투사체 생성 (CreateObject 구현 시)
        # - Object.CreateObject:
        #     initialLocation: eyeLoc
        #     initialVector: velocity # Vector 타입 변수 사용
        #     # ... 투사체 외형, 충돌 시 동작 등 정의 ...
        #     # 예: ObjectBehaviour.OnHit: [ { TargetBehaviour.Damage: { amount: finalDamage } } ]

(주의: 위 예제는 현재 기능 및 제약을 반영했으며, 특히 문자열 내 변수 치환 및 벡터 연산, 오브젝트 생성 부분은 향후 개선이 필요할 수 있습니다.)