최근 수정 시각 : 2024-05-03 22:03:22

Trigger Reactor


파일:하위 문서 아이콘.svg   하위 문서: Trigger Reactor/예제
,
,
,
,
,
#!wiki style="display: inline; display: none;"
, }}}
파일:관련 문서 아이콘.svg   관련 문서: 마인크래프트/플러그인
,
,
,
,
,
트리거 리액터
Trigger Reactor
파일:TriggerReactor-logo.png
다운로드 페이지 Spigot Bukkit Github[추천]
버전 1.5.2 ~ 1.20[2]
개발자 wysohn[3]
개발 협력자 gerzytet(외국인) Dr_Romantic(한국인)[4]
공식 설명서 파일:GitHub 아이콘.svg파일:GitHub 아이콘 화이트.svg
설명서 번역가 Dr_Romantic, RedLime
공식 링크 파일:디스코드 아이콘.svg ~파일:KakaoTalk_20200530_231823522.png~[5] 파일:GitHub 아이콘.svg파일:GitHub 아이콘 화이트.svg
1. 개요2. 특징
2.1. 스크립트 파일 확장자2.2. 문법2.3. 기능2.4. 접근성 및 작성 난이도
3. Trigger Reactor 구문 작성
3.1. 기본
3.1.1. 자료형 처리
3.1.1.1. 문자열3.1.1.2. 정수, 실수3.1.1.3. 이진법(Boolean)
3.1.2. 변수
3.1.2.1. 지역변수(Local Variable)3.1.2.2. 전역변수(Global Variable)3.1.2.3. 임시 전역 변수 (Temporary Global Variable)
3.1.3. 실행자(Executor)
3.2. 심화(Advanced 부분)
3.2.1. 서드파티 플러그인 접근3.2.2. 임포트(Import)
3.2.2.1. AS 부속 표시자

[clearfix]

1. 개요

마인크래프트에서 사용하는 스크립터 플러그인 중 하나로, 타 스크립터 플러그인에 비해 상대적으로 최근에 알려졌다. 국내애서나 해외에서나 인지도가 그리 높지는 않고, 해외보다는 한국 내에서의 인지도가 높다. 개발자 중 한 명인 Dr_Romantic에 따르면 한국어 표기는 트리거 리터라고 한다. 트리거 리액터의 소스코드는 GNU GPLv3 라이센스에 따라 배포되고 있다.

트리거 리액터는 자바 16부터 자바 자체에 포함되어 있던 Nashorn 자바스크립트 엔진이 제거됨에 따라 자바스크립트로 짜인 모듈을 실행하기 위해 JShader 플러그인을 사용하고 있다. 자바 16 이상을 사용 중이라면 해당 플러그인을 같이 버킷 plugins 폴더 안에 넣어야 정상적으로 작동한다.

2. 특징

2.1. 스크립트 파일 확장자

트리거 리액터 스크립트 파일은 .trg라는 고유의 확장자를 사용하며, 트리거의 세부적인 설정을 저장하기 위해 동일한 이름의 JSON 파일을 생성한다. 세부적인 설정은 트리거의 종류마다 달라지는데, Area 트리거라면 Area의 범위 좌표 정보와 SYNC여부, Command 트리거라면 aliases, SYNC여부, 펄미션, Custom 이벤트 트리거는 이벤트, Sync여부, Inventory 트리거는 인벤토리 GUI 레이아웃 정보 등등이다. 자바 플러그인 개발에서 Listener와 config 파일이 담고 있을 정보를 JSON 파일에 담고 실제 작동 코드는 .trg 파일에 담는다고 생각하면 쉽다.

.trg은 단순 텍스트 파일이기 때문에 기본 메모장 앱이나 VS Code 등으로 직접 파일을 수정하여 작성할 수도 있다. 고유 확장자는 플러그인이 다른 파일들을 스크립트 파일로 인식해 불러오려 시도하는 것을 방지하기 위함이다. 파일 인코딩을 UTF-8(BOM 없음)으로 설정하지 않을 경우 파일이 깨지고 한글이 제대로 출력이 안되는 문제가 발생할 수 있다.

인게임에서 'In-Game Editor' 이라 불리는 트리거 리액터 고유의 인게임 구문작성 솔루션으로도 구문작성이 가능하다.

2.2. 문법

기본적 기능과 문법, 예를 들면 일시적 OP 권한으로 명령어를 실행하는 실행자(Executor)가 VT의 @CMDOP와 유사한 #CMDOP라 거나, 트리거를 실행하는 플레이어의 이름을 문자열로 반환하는 플레이스홀더가 $playername이라거나 한 스코프를 ~, END~[6]로 표기하는 점, 그리고 전역변수의 기본 형식이 {"a.b"}[7]인 점 등이 VT의 문법과 유사하다. 실제로 설명서 소개 페이지에 VariableTriggers에 영감을 얻었다고 명시되어있다.

전체적인 문법은 BASIC과 유사했던 VT보다 더 유연하고 현대적인 편이며, 같은 인터프레터 방식의 언어인 파이썬에서 따온 부분이 보인다. 예를 들면 변수의 타입을 선언하지 않아도 인터프레터가 자동으로 처리해주는 점이나[8], 파이썬의 for 루프와 유사하게 FOR i in 0:10, FOR p in getPlayers()와 같은 식으로 쓸 수 있다는 점에서 그렇다. 때문에 심화적인 기능으로 가면 갈수록 구문의 대부분이 인터프레터 프로그래밍 언어를 연상시킨다. 철저히 절차지향적인 VT와는 다르게 다소 객체지향적 문법을 가지고 있기도 하다. 리스트와 맵도 내부적으로 자바의 List<Object>, Map<Object, Object>로 처리되기 때문에 어떤 타입이든 관계없이 넣을 수 있다.

#MESSAGE "Hello, world!" 라는 BASIC 같은 구문을 player.sendMessage("Hello, world!")와 같이 객체지향적으로 쓸 수도 있고, 자바처럼 접근자(getter)와 설정자(setter)를 자주 쓰게 되는 등 전체적인 문법의 형식이 다소 혼잡해질 여지가 있다. 다만 실행자의 존재 인해 스크립트를 더 짧고 직관적으로 쓸 수 있고, 초급자들은 더 직관적인 실행자를 사용하는 것을 편하게 느끼기 때문에 장단점이 있다.

3.3.0.1 버전 이후 LAMBDA 가 추가되어 Consumer와 같은 함수형 문법도 처리할 수 있게 되었다. Switch문 등 일부 편리성을 더하는 프로그래밍 문법은 구현되지 않았다.

2.3. 기능

트리거 리액터의 가장 강력한 기능 중 하나는 IMPORT와 plugins() 기능으로 이 둘만 있다면 Bukkit API를 비롯, 제 3자 플러그인의 클래스, 메소드와 고유 이벤트, java.io같은 JAVA 자체 내장 메소드에도 접근할 수 있다. 예를 들면 Vault에 접근해 Vault 고유 플레이스홀더를 읽어올 수 있고, java.io에 접근해 파일을 쓰고 읽어올 수 있는 기능을 만들 수도 있다. Bukkit API와 서드파티 플러그인에 접근하려면 IMPORT로 불러오면 되며, 서드파티 플러그인을 불러오려면 우선 plugins() 메소드를 사용해 서드파티 플러그인을 불러온 후 BukkitAPI와 마찬가지로 IMPORT를 사용해 내부 클래스와 메소드를 불러올 수도 있다. 이러한 어디든 접근해서 가져다 쓸 수 있는 기능은 트리거 리액터의 강력한 임포트 기능은 (플러그인 개발에 비해 한계가 명확했던 VariableTriggers에 비해서) 트리거 리액터의 가능성을 한 단계 높여준다.

스크립터 플러그인중 유일하게 구문에서 직접 동기/비동기를 제어할 수 있다. 즉, 사용자 정의의 멀티 쓰레딩을 지원하는 것이다. 덕분에 사용자의 서버 부하를 유연하게 조절할 수 있게 되었다.

#MYSQL 실행자를 이용한 DB 엑세스 역시 지원한다.

사용자 풀에 비해 사후지원이 상당히 괜찮다. 일단 공식 위키 페이지가 상당히 자세하며, 공식 디스코드 채널에 질문하면 트리거 리액터 개발 기여자들이 자세하게 직접 답변을 해준다. 이들은 개발자니 당연히 트리거 리액터와 마인크래프트 서버 시스템에 대한 이해도가 높다.

2.4. 접근성 및 작성 난이도

인게임 명령어로 트리거를 생성하고 기본적으로 주어지는 실행자와 IF 조건문, 조금 더 나아가서 전역변수 선언과 FOR, WHILE 루프문 정도만 사용한다면 기본적으로 VariableTriggers와 크게 다르지 않다. 명령어를 한글화한다던가, 간단한 인게임 상호작용 기능을 만드는 수준은 공식 한국어 위키를 참고하는 정도로도 쉽고 빠르게 개발할 수 있다.

하지만 그 이상의 기능들에 접근하기 위해선 진입장벽이 높다는 평가를 받는다.

CommonFunctions라는 트리거 리액터 자체 내장된 여러 유용한 함수들이 있으며, 기본적으로 주어진 실행자만으로 구현할 수 없는 기능에 접근하려면 Bukkit API 문서를 뒤적여야 하므로 Javadoc 형태의 문서를 읽는 능력이 필요하다. 위 두 링크와 공식 위키 페이지는 트리거 리액터로 코딩하다보면 자주 드나들게 될 페이지이다.

상술했듯 문법 역시 유명 스크립터 플러그인인 Skript와 달리[9] VT 문법의 실행자와 플레이스 홀더를 다소 가져오고, 메인은 Java 프로그래밍 언어의 문법에 파이썬을 다소 섞은 듯한 문법을 사용하기 때문에, 어느정도 객체지향 프로그래밍에 대한 기본 상식 없다면 심화접근이 어렵다. 구현 가능한 범위가 매우 넓은 장점이 있지만, 동시에 그만큼 배울 것도 많다는 단점이 있다. 다만 이미 프로그래밍의 경력이 있는 입장에서는, 어디서도 찾아보기 힘든 Skript 고유의 실제 영어 문장 같은 문법과 달리 여러 범용적 프로그래밍 언어와 닮은 문법이 더 익숙할 수도 있다.

이러한 점 때문에 플러그인을 개발하는 것과 다를 바가 없어보이기도 하나, 대부분의 인터프레터 언어가 그렇듯 트리거 리액터의 근본적인 장점은 실행하는 순간(런타임)에 컴파일 되어 효율적으로 기능을 실험하고 구현할 수 있는데에 있다. 플러그인은 퍼포먼스면에서 우월한 반면 수정을 할 때마다 해당 부분을 다시 컴파일해야 하지만, 트리거리액터 스크립트는 곧바로 수정하고 /trg reload 명령어로 스크립트 목록을 다시 한번 불러오기만 하면 되어 테스트의 효율성이 증가한다.

3. Trigger Reactor 구문 작성

TR 구문의 특성이나 여러 구문 예시를 다룬다. 2022년 7월 기준 누락된 설명이 매우 많으니 대략적인 참고만 하고 자세한 설명은 공식 위키를 참고하기 바람.

문서의 가독성을 위해 기본적인 트리거 리액터의 사용법을 설명하는 구문 이외엔 Trigger Reactor/예제에 적기 바람.

3.1. 기본

3.1.1. 자료형 처리

TR은 객체지향적이다. 때문에 변수에 대한 자료형이 여러 가지가 존재한다. 일반적으로 JAVA의 구문 내부에서는 변수 앞에 자료형을 붙임으로써 선언하지만, 트리거 리액터는 이와 다르게 자료형에 따라서 모두 오브젝트 인스턴스로 선언한다.
3.1.1.1. 문자열
트리거 리액터에서 문자열은 쌍따옴표(") 로 선언한다. String 클래스를 불러와 객체를 선언할 필요는 없다.
예를 들어,
myStr = "안녕하세요!"

위 구문은 "안녕하세요!" 의 값을 가진 문자열 인스턴스를 myStr이라는 이름을 가진 변수에 저장한다.
이때, 주의할 점이 있다면 트리거에서는 그 자체의 내용으로써 불러오는 정적 문자열 과 변수로써, 또는 변수를 통해 불러오는 동적 문자열 의 입력방식이 존재한다. 위 구문은 "안녕하세요!" 라는 그 자체의 내용을 담고있으므로 정적 문자열 입력방식을 사용한 것이다. 저 구문을 실행하고 바로 아래 줄에서
#MESSAGE myStr

위와 같은 구문을 적는다면 myStr은 "안녕하세요!" 라는 문자열의 내용을 직접적으로 서술하지 못하는 변수명이기에 동적 문자열 의 입력 방식을 사용한 것이다. 두 방식의 다른 점은 동적 문자열 입력방식은 쌍따옴표(") 가 사용되지 않는 것이다. 위와 같이 두가지 입력 방식으로 나눈 이유는 바로 PlaceHolder[10] 라는 트리거 리액터가 내장하는 기능이 있기 때문이다. 결론부터 말하자면 PlaceHolder는 동적 문자열 입력방식의 일종이다. 그도 그런게, $playername 을 입력하면 플레이어의 이름 값을 불러온다. 이는 실질적으로 구문에서 $playername을 사용함으로써 정확히 불러와지는 것이 불분명하고 사용하는 플레이어에 따라 변할 수 있기 때문인데, 이 때문에 $playername 과 같은 플레이스 홀더는 쌍다옴표(") 사이에 위치시키면 작동하지 않는다.
#MESSAGE "$playername"

위 구문은 $playername을 문자 그대로 출력한다.
#MESSAGE $playername

위 구문은 이 트리거를 실행시킨 플레이어의 닉네임을 불러온다.

이렇게 두 가지 입력방식이 있는데, 이 두개를 한번에, 가령 "<플레이어 이름> 님이 우승!" 과 같은 정적 문자열동적 문자열 을 동시에 사용하려면 사이에 +를 넣어서 두 문자열을 붙일 수 있다.
#BROADCAST $playername+"님이 우승!"
3.1.1.2. 정수, 실수
int, Double 등과 같은 정수, 실수는 위와 같은 특정 기호를 통한 선언 방식이 없다. 즉,
myDouble = 16.3||
위와 같은 방식으로 바로 정수, 실수타입을 선언할 수 있다.
3.1.1.3. 이진법(Boolean)
트리거 리액터에서는 이진법, 즉 옳고 그름(TrueFalse) 또한 특정 기호를 통한 선언 방식이 없고, 단지 truefalse 로 선언할 수 있다.
myBool = true

주의할 점은 쌍따옴표(")를 붙이면 문자열로 인식하여 이진 연산이 불가능하다는 점이다.

3.1.2. 변수

트리거 리액터의 변수는 크게 [11] 전역변수(광역변수) , 지역변수 , 그리고 임시 전역변수. 이렇게 세가지이다. 변수는 이해하기 상대적으로 쉽다.
3.1.2.1. 지역변수(Local Variable)
지역변수는 해당 구문에서 곧바로 선언하고 해당 변수를 선언한 구문에서만 사용이 가능한 변수이다. 한마디로, A.trg에서 선언한 임시변수는 B.trg에서 사용될 수 없고, A.trg의 실행이 끝나면 곧바로 삭제된다. 단, 예외적으로 A.trg에서 Named Trigger 형식의 B.trg를 호출한다면 실행 영역이 합쳐지는 것으로 처리되어 B.trg에서도 A.trg에서 선언한 지역변수를 사용할 수 있다.
지역변수의 선언 방법은 다음과 같다.
변수명 = 값

이미 이 문서 상단에서 서술한 변수 선언도 실질적으로 지역변수의 선언이다.
name = $playername

위 구문은 name이라는 지역변수에 해당 구문을 실행시킨 플레이어의 닉네임을 저장한다.

변수 선언을 위해 변수명을 정할 때, 알아둬야 할 몇 가지 사항이 존재한다.
1. 특수기호는 _(언더스코어) 이외에는 사용하지 않는다. =,+, -,*,/,>,<,!,(,),&,",?,#,${,},[,],|. 등 다수의 특수기호가 이미 트리거 리액터 내에서 연산자와 실행자, 전역변수, 임시변수 표기를 비롯해 문법상 필요한 약속된 기호로 사용되고 있으며, 인터프레터가 이를 혼동할 가능성이 있다. 또한 이모지를 비롯해 일부 특수기호는 읽지 못한다. 그러므로 변수명은 가능한 영어 소문자, 대문자 알파벳, 숫자, 그리고 _만을 사용해 쓰는 것이 권장된다.
2. player, inventory, event, command, args 등을 비롯해 일부 이름은 트리거 리액터가 기본 내장 플레이스홀더로 미리 사용하고 있다. 이러한 단어들을 변수명으로 사용한다고 에러는 나는 것은 아니지만 문제가 생길 수 있다. 예를 들면 event 변수를 덮어써버리면 해당 이벤트 인스턴스의 포인터가 사라져버려 이벤트가 담고 있던 여러 정보에 접근할 수 없다. 플레이스홀더 참고
3. 또한 IF, ENDIF, ELSE, ELSEIF, AND, OR, FOR, WHILE, SYNC, ASYNC, IMPORT (소문자도 포함), true, false, null 등 인터프레터가 예약한 수십 개의 키워드가 있으며, 이러한 단어들은 변수명으로 사용해선 안된다.
4. 트리거 리액터가 공식적으로 채택한 코딩 컨벤션은 없으나, 개발자 wysohn이 직접 쓴 예제 파일들을 보면 기본적으로 JAVA 코딩 컨벤션을 따르고 있으며 커뮤니티에서도 대체로 이를 따르고 있다. JAVA 코딩 컨벤션 참고
3.1.2.2. 전역변수(Global Variable)
전역변수는 var.json 파일에 저장되며, 어느 트리거에서나 사용가능하고 서버를 종료해도 영구적으로 저장되는 변수이다. 최초 저장 방식은 Bukkit API Configuration 포맷이었으나, 현재의 저장 방식은 JSON 포맷이다.

전역변수 선언과 사용 예시:
{"Some.Thing"} = "Coffee"
#Message {"Some.Thing"} // 메시지창에 "Coffee" 가 출력된다.
여기서 주의할 점은 {}(중괄호) 사이에 "a.b" 형식의 점으로 구분된 문자열(String)이 들어간다는 것이다.

var.json 파일을 열어보면 다음과 같이 저장된 것을 볼 수 있다.
{
"Some": {
"Thing": "Coffee"
}
}
보다시피 .을 기준으로 그룹이 나뉘어 있다. 해당 그룹의 노드를 모두 지우고 싶다면 부모 노드를 null로 바꿔주면 된다.
{"Some"} = null

다른 예시:
{$playername + ".Balance"} = 1000
#MESSAGE {$playername + ".Balance"}

var.json 파일을 열어보면 다음과 같이 저장된 것을 볼 수 있다.
{
"플레이어이름": {
"Balance": 1000
}
}

참고로 반드시 a.b의 형식이어야 할 필요는 없으며, 더 복잡한 구조의 노드를 만들 수도 있다.
{"a.b.c.d.e"} = true

var.json 파일을 열어보면 다음과 같이 저장된 것을 볼 수 있다.
{
"a": {
"b": {
"c": {
"d": {
"e": true
}
}
}
}
}
3.1.2.3. 임시 전역 변수 (Temporary Global Variable)
트리거 리액터에선 네임드 트리거를 불러왔을 때를 제외하고 서로 다른 트리거 간엔 지역변수가 공유되지 않는다. 예를 들면 커멘드 트리거 A에서 #GUI로 인벤토리 트리거 B를 불러왔을 때, A 스크립트 내에서 선언된 지역변수는 휘발하게 된다. 임시 전역 변수는 서로 다른 트리거 간에 변수를 공유하고 싶지만 파일에 저장하고 싶지는 않을 때 사용할 수 있다. 임시 전역 변수는 구조상 트리거 리액터 자체 메모리 Map에 남는 형식으로, 서버 재시작이나 플러그인 리로드 시 사라지게 된다. var.json에 쓰기를 하지 않으므로 성능에 있어 이점이 있고 수동으로 삭제해주지 않아도 되어 편리하다.

임시 전역 변수 선언과 사용 예시:
{?"Some.Thing"} = "Coffee"
#Message {?"Some.Thing"} // 메시지창에 "Coffee" 가 출력된다.
전연 변수 선언과 거의 비슷하지만 처음의 { 바로 뒤에 ?가 붙게 된다.

3.1.3. 실행자(Executor)

실행자는 트리거에서 사용할 수 있는 명령어이다. 약 50개 가량의 기본 내장 실행자도 있지만, 트리거 리액터 플러그인 폴더 - Executor 폴더에 자바스크립트로 작성된 서드파티 실행자를 추가할 수도 있다. 디스코드 채널 혹은 공식 웹페이지 등의 커뮤니티에서 트리거 리액터 사용자들이 공유하는 실행자를 찾을 수 있다.

실행자는 주로 다음과 같은 형식으로 쓸 수 있다.
#실행자 이름 [arguments]
  • 기본 내장 실행자들
대부분의 실행자들은 편리성을 더하기 위해 만들어진 것으로, 버킷 API 등을 임포트 해 메소드와 클래스를 사용함으로써 실행자를 직접 쓰지 않고도 같은 작업을 하는 구문을 쓸 수 있다. 예를 들면 #MESSAGE "Hello, Player" 는 player.sendMessage("Hello, Player!") 로도 대체해 쓸 수 있다. 그러나 일부 실행자는 위의 방법으로 대체할 수 없다.

#CALL은 네임드 트리거를 불러와 실행한다:
#CALL "경로:MyNamedTrigger" true/false)

문자열은 네임드 트리거의 이름이며, 경로는 :로 구분한다. 아무런 경로도 쓰지 않고 트리거 파일의 이름만 썼다면 트리거 리액터 플러그인 폴더의 NamedTriggers 폴더에서 트리거를 찾는다. 만약 경로를 썼다면 NamedTriggers 폴더에서 시작해 경로를 찾는다.

마지막의 Boolean은 동기화 여부이다. true는 동기적으로 트리거를 실행하며, false는 비동기적으로 실행한다. 디폴트는 true이다. 즉 아무것도 쓰지 않으면 자동으로 동기적으로 실행한다.

#STOP은 트리거의 실행을 즉각 중단한다. #STOP 아래의 구문들은 실행되지 않는다.
#STOP

GUI은 인벤토리 트리거를 불러와 실행한다:
#GUI "경로:MyInvTrigger"

GUI은 인벤토리 트리거를 불러와 실행한다:
#GUI "경로:MyInvTrigger"

CLOSEGUI은 현재 보고 있는 인벤토리 트리거 닫는다:
#CLOSEGUI

3.2. 심화(Advanced 부분)

3.2.1. 서드파티 플러그인 접근

트리거 리액터의 강력한 장점 중 하나는 외부 플러그인의 클래스와 메소드에도 접근할 수 있다는 점이다. plugin() 메소드를 사용해 플러그인을 불러올 수 있다.

플러그인 불러오기 예시:
변수이름 = plugin("<플러그인 이름>")

예시:
ess = plugin("Essentials") //Essentials 플러그인을 불러와 ess 지역변수에 저장한다.
IF ess // 에센셜 플러그인이 정상적으로 불러와졌는지 확인
{$playername+".geoloc"} = ess.getUser($playername).getGeoLocation()
ENDIF
위 구문은 플레이어의 실제 접속 위치(예: 대한민국 서울)를 {<플레이어 이름>.getloc} 번수에 저장한다.

아래에 설명된 IMPORT를 이용하여 서드파티 플러그인의 클래스도 불러올 수 있다.
SYNC
citizens = plugin("Citizens") //Citizens 플러그인을 불러와 citizens 지역변수에 저장한다.
IF citizens // 만약 플러그인에 정상적으로 불러와졌다면
IMPORT net.citizensnpcs.api.event.DespawnReason // 플러그인의 net.citizensnpcs.api.event에 있는 DespawnReason 클래스를 임포트한다.
npc = citizens.getNPCRegistry().getById(0)
#MESSAGE "&fNPC " + npc.getFullName() + "&f를 디스폰합니다."
npc.despawn(DespawnReason.PLUGIN) // 임포트한 클래스를 사용하는 구문ENDIF
ENDSYNC

3.2.2. 임포트(Import)

트리거 리액터에서는 Import를 사용해 다른 자바 클래스에 접근할 수 있다. 이름이 같은 클래스를 2번 불러오면 덮어쓰기가 된다. Import의 기본 구조는 다음과 같다.
IMPORT <클래스 이름>

인스턴스 생성 예시:
rand = Random()
#MESSAGE "0에서 99까지 범위의 랜덤 숫자:" + rand.nextInt(100)||

버킷 API에 접근하는 예시:
IMPORT org.bukkit.potion.PotionEffectType

effect = PotionEffect(PotionEffectType.WATER_BREATHING, 1000000, 0, false, false)
player.addPotionEffect(effect) // player는 트리거를 실행한 플레이어 인스턴스로 트리거 리액터의 자체 내장 변수이다.||

클래스 안에 정의된 내부 클래스에도 접근할 수 있으며 기본 구조는 다음과 같다.
IMPORT <상위 클래스 이름>$<내부클래스 이름>
클래스 안에 정의된 내부 클래스의 경로는 .대신 $로 표기한다.

예시:
//ClientConnectionEvent.Login 불러오기||
3.2.2.1. AS 부속 표시자
이름이 겹치는 서로 다른 클래스를 동시에 임포트 하면 먼저 임포트된 클래스를 나중에 임포트 된 클래스가 덮어 써버리는 문제점이 있었으나, 2022년 01월 16일 프리릴리즈된 v3.3.0.6-BETA 버전에서, 새로운 IMPORT 의 부속 표시자로 AS 가 추가되었다. 사용 방법은
IMPORT some.awesome.Class$Inner AS myInnerClass

와 같다. 기존 IMPORT 뒤에는 임포트 할 클래스를 넣고, AS 뒤에는 그 클래스 자체를 담는 변수의 이름을 지정하는 방식이다.

이를 통해서 이를테면 HoverEvent$ActionClickEvent$Action 두 가지 모두를 사용할 때 발생하는 이름 겹침 문제가 완전히 해결 될 수 있다.
IMPORT net.md_5.bungee.api.chat.ClickEvent$Action AS ClickAction
IMPORT net.md_5.bungee.api.chat.HoverEvent
IMPORT net.md_5.bungee.api.chat.HoverEvent$Action AS HoverAction
IMPORT net.md_5.bungee.api.chat.TextComponent
IMPORT net.md_5.bungee.api.chat.ComponentBuilder

message = TextComponent("Clickable Healing Text")

message.setClickEvent(ClickEvent(ClickAction.RUN_COMMAND, "/heal"))
message.setHoverEvent(HoverEvent(HoverAction.SHOW_TEXT, ComponentBuilder("Click to Heal!").create()))

player.spigot().sendMessage(message)||
[추천] 여기서 본인의 버전에 맞게 다운로드하는 것을 추천한다.[2] 1.5.2~1.12.2는 legacy 버전이 따로 존재한다. 1.13 이상은 latest. Sponge는 API 7까지 지원하며, sponge 버전 역시 따로 존재한다.[3] 재미 한국인으로, Java외에도 웹 프론트엔드, 백엔드, DB등 다양한 언어를 활용할 수 있는 듯 하다.[4] 현재 개인 사정으로 모두 중단[5] 준비중[6] 예: IF, ENDIF[7] 중괄호 안에 .으로 구분된 문자열[8] 심지어 클래스 캐스팅도 자동으로 처리해준다.[9] 물론 Skript도 직접 코드를 작성하도록 해주는 애드온이 존재하지만 기본 플로우를 코드로 하지는 않는다.[10] 특정 상황에서의 특정 값을 불러오는 기능을 하는 것이다. 가령 VT에서 <playername>은 트리거를 실행시킨 플레이어의 이름이 불러와지듯이, 트리거 리액터에서도 $playername 과 같은 것이 있다.[11] 원래는 두가지였지만 최근에 임시전역변수 기능이 추가되었다.