문서 게임플레이 확장

JASS 채널

맵 제작자가 쓸 수 있는 JASS 함수 1291개를 이제 게임 밖에서 이름으로 바로 호출할 수 있습니다. 유닛 생성, 속성 변경, 특수 효과, 패널, 대화 상자, 사운드, 카메라, 전장의 안개…… Farsight 콘솔, 명령줄, HTTP, Python 네 가지 방법으로 쓸 수 있습니다.

맵 제작자가 맵 스크립트에서 쓸 수 있는 JASS native 1291개를 이제 모두 게임 밖에서 이름으로 바로 호출할 수 있습니다. 유닛 생성, 속성 변경, 특수 효과 그리기, 패널과 대화 상자 띄우기, 사운드 재생, 카메라 이동, 안개 변경…… 게임을 한층 더 커스터마이즈하는 데 쓰세요 — RPG 보조, AI 동료, 직접 만든 미니 게임, 디버깅 도구.

사용법적합한 경우진입점
Farsight “JASS 콘솔” 페이지직접 시험해 보기, 보면서 고치기왼쪽 사이드바 “시스템 → JASS 콘솔”: 스크립트를 쓰고 실행을 누름. 오른쪽에서 분류별로 함수를 찾고, 클릭하면 스크립트에 삽입
명령줄직접 시험해 보기, 또는 스크립트 파일로 만들어 반복 실행python -m openwar3 jass --inst 20(대화형), -e "코드", my_script.j, --list 키워드
HTTP어떤 언어로 만든 외부 프로그램이든POST /api/instances/{n}/jass 등(아래 참고). Farsight 백엔드는 로컬에서만 수신 대기
Python스킴, 동료, 도구 작성g.jass.함수이름(...). 자주 쓰는 화면·상호작용 기능은 openwar3.visual에 묶여 있음

경계는 세 가지이며, 모두 메커니즘상 정해진 것입니다.

  • 싱글플레이 게임(이 컴퓨터에서 컴퓨터 상대)에서만 월드를 바꿀 수 있습니다. 이 컴퓨터가 일방적으로 오브젝트를 만들거나 유닛을 바꾸면 멀티플레이 게임에서 다른 플레이어와 동기화가 깨집니다 — 멀티플레이 게임에서는 읽기 전용 함수(Get*, Is*, Count*……)만 허용합니다.
  • 이 컴퓨터의 자체 도구 전용입니다. 플레이어 신분으로 연결(Game(player=N))했거나 공정 모드에서 호출하면 거부됩니다.
  • 싱글플레이 또는 LAN에서 직접 만든 게임에서만 사용하세요.

멀티플레이 게임에서 화면에 무언가를 더하려면 캔버스를 쓰세요. 런타임이 직접 그리며 게임 상태를 바꾸지 않습니다.

스크립트 작성법

콘솔, 명령줄, HTTP는 같은 스크립트를 씁니다. 한 줄에 한 문장이며, JASS를 그대로 붙여 넣을 수도 있고(call / set / local, true / false / null, 'Hpal' 4자 코드, // 주석) Python 식으로 쓸 수도 있습니다.

set h = hero()                                   // 내장: 아군 주 영웅
local texttag t = CreateTextTag()
call SetTextTagText(t, "|cffffcc00+128 치명타!|r", 0.024)
call SetTextTagPosUnit(t, h, 60)
call SetTextTagVelocity(t, 0, 0.03)
call SetTextTagPermanent(t, false)
call SetTextTagLifespan(t, 4)
call SetTextTagVisibility(t, true)
call PingMinimapEx(h.x, h.y + 300, 3, 255, 0, 0, false)
set u = CreateUnit(Player(0), 'hfoo', h.x + 200, h.y, 270)
print("생성함", u, "영웅 레벨", GetHeroLevel(h))
  • 변수는 계속 기억됩니다: 같은 인스턴스, 같은 게임 안에서는 이번 블록에서 set한 변수를 다음 블록에서 이어서 쓸 수 있습니다. 게임이 바뀌면 자동으로 비워지며, 수동으로 비울 수도 있습니다.
  • 내장 함수: hero() 아군 주 영웅, me() 로컬 플레이어, unit('hfoo') 유닛 하나 찾기, unit_at(x, y), wait(초), print(...). 유닛에서는 .x, .y, .hp, .hp_max, .mana, .type, .owner, .level을 읽을 수 있고, 사칙연산과 비교를 지원합니다.
  • if, loop, function은 지원하지 않습니다 — 로직을 쓰려면 Python의 g.jass(평범한 함수 호출입니다)를 쓰거나 스킴으로 만드세요.
  • 오류가 나면 몇 번째 줄에서 왜 났는지 알려 줍니다(그런 함수가 없음, 인자 개수가 틀림, 정의되지 않은 변수……). 오류 이전의 문장은 이미 적용되어 있습니다.

인자와 반환값:

시그니처전달할 값설명
정수숫자. 'Hpal' 4자 코드는 자동 변환
실수숫자런타임이 엔진이 요구하는 형식으로 변환
불리언true / false
문자열"..."중국어 등 비ASCII 문자와 게임 색상 코드 지원. 게임이 보관하는 문자열(떠다니는 텍스트, 패널, 버튼, 채팅 명령)은 모두 그 자리에서 복사해 두므로 안전
핸들변수에 담긴 핸들, 또는 유닛(hero() 같은 것은 자동으로 핸들로 변환)
함수(code)null만 가능밖에서는 JASS 함수를 넘길 수 없음. TimerStart(t, 60, false, null) 같은 것은 가능
문자열 반환—엔진이 반환하는 것은 문자열 테이블 번호라서 텍스트를 읽어 올 수 없음. 유닛 이름은 g.map_data.name_of 사용

분류

함수는 이름으로 분류되어 있으며, 콘솔 오른쪽과 --list 모두 이 분류를 따릅니다.

분류개수예
화면 효과80떠다니는 텍스트, 번개 연결선, 특수 효과, 지면 이미지, 지면 표식, 유닛 색 변경 / 크기 조절 / 애니메이션 재생
UI 패널146멀티보드, 리더보드, 타이머 창, 대화 상자, 퀘스트, 화면 텍스트, 미니맵 핑, 초상화 대사, 전체 화면 필터
카메라44카메라 필드, 팬 이동, 카메라 흔들기
사운드·음악50사운드 생성과 재생, 음악 재생
안개·시야25가시 영역, 안개 켜기/끄기
아이템 / 영웅 / 유닛63 / 32 / 161아이템 생성, 영웅 레벨 설정, 소유자 변경, 스킬 추가
플레이어 / 동맹 / 자원71동맹 설정, 금·목재 변경
트리거 / 이벤트 / 타이머62트리거 생성, 이벤트 등록, 타이머
지형 / 날씨 / 파괴 가능 오브젝트45날씨 효과, 지형 변경, 파괴 가능 오브젝트 생성
게임 진행57게임 속도, 일시정지, 낮밤 시각
기타……유닛 그룹과 영역, 저장소, 컴퓨터 AI 스크립트, 형 변환과 수학, 이벤트 응답……

2026-09-24에 하나씩 실제 게임에서 호출해 효과를 눈으로 확인한 것은 94개입니다. 나머지도 같은 경로를 거치지만, 하나하나 효과를 확인하지는 않았습니다.

“이벤트 응답” 계열 함수(GetTriggerUnit, GetClickedButton……)는 트리거가 실행되는 그 순간에만 값이 있어서, 밖에서 호출하면 0이나 빈 값을 받습니다. “일어났는지 여부”를 알고 싶다면 아래의 이벤트 카운트를 쓰세요.

HTTP

Farsight 백엔드(기본 127.0.0.1:8866, 로컬에서만 수신 대기):

GET  /api/jass/natives?q=TextTag&cat=visual
POST /api/instances/20/jass        {"code": "set h = hero()\ncall PingMinimapEx(h.x, h.y, 3, 255, 0, 0, false)"}
     -> {"ok": true, "rows": [...], "printed": [...], "vars": {...}}
     -> 오류: {"ok": false, "error": "第 2 行:...", "line": 2}      ("第 2 行" = 2번째 줄)
POST /api/instances/20/jass/call   {"name": "SetUnitScale", "args": [{"unit": 599669636}, 1.4, 1.4, 1.4]}
POST /api/instances/20/jass/reset  기억된 변수 지우기

유닛 인자는 {"unit": 주소}로 쓰며, 주소는 스냅샷에 있는 유닛의 addr입니다. 실측 요청 1회에 60 ~ 90 ms.

Python: g.jass와 openwar3.visual

j = g.jass
t = j.CreateTextTag()
j.SetTextTagText(t, "안녕", 0.024)     # 인자 규칙은 스크립트와 같음. 스냅샷의 유닛, 아이템 객체를 그대로 넘겨도 됨
j.signature("CreateImage")             # 시그니처 조회

openwar3.visual.Visual(g)는 실측으로 확인한 자주 쓰는 화면 효과를 한 줄에 하나씩 쓸 수 있게 묶어 둔 것입니다(틱마다 v.tick()을 한 번 호출하면 만료된 것은 지우고, 유닛을 따라가는 선과 원은 옮겨 줌. v.clear()는 전부 삭제).

메서드효과
float_text(텍스트, 유닛 또는 지점, ...)떠다니는 텍스트: 피해 숫자, 머리 위 알림. 비ASCII 문자와 색상 모두 가능
link(a, b, kind)두 유닛 사이의 선, 유닛을 따라감: 견인 / 영혼 연결 / 생명력 흡수 / 치유의 물결
effect(모델, 유닛 또는 지점, ...)특수 효과 모델: 머리 위, 발밑, 또는 한 번 재생(폭발, 빛기둥)
ring(유닛 또는 지점, 반지름, color)지면의 범위 원: 스킬 범위, 위험 지역, 집결 지점. 유닛을 따라가게 할 수 있음
ping(지점, color)미니맵 핑
board(제목, 줄...)오른쪽 위 멀티보드(아이콘 포함). 칸 단위로 수정 가능
countdown(제목, 초)오른쪽 위 타이머 창. 게임이 알아서 초를 셈
scene(이름, 대사, portrait)초상화 대사: 하단 초상화가 말하는 유닛으로 바뀌고, 화면에 “이름: 대사” 자막이 나옴
screen_tint(color, alpha)전체 화면 필터(기본값은 가장자리가 붉게 물듦: 체력 경고)
sound(경로) / reveal(지점, 반지름, 초) / look(유닛, ...)사운드 재생 / 안개 일부 걷기 / 유닛 색 변경, 확대, 애니메이션 재생, 번쩍임

상호작용: JASS 함수를 쓰지 않고도 플레이어가 한 일 알아내기

JASS에서 플레이어에게 반응하려면 트리거 함수를 써야 하는데, 밖에서는 함수를 넘겨줄 수 없습니다. 해법은 이렇습니다. 조건도 동작도 없는 빈 트리거를 만들어 이벤트만 등록하고, 그 트리거가 몇 번 실행됐는지 셉니다. 실측 결과 빈 트리거도 실행 횟수가 그대로 집계됩니다.

메서드용도
chat_commands(["-follow", "-stay"]) → .poll()플레이어가 채팅창에 입력한 명령(정확히 일치, 또는 앞부분 일치)
menu(제목, [버튼...]) → .clicked()화면 가운데 버튼 메뉴에서 어느 것을 눌렀는지
hotkeys(("left", "right", "up", "down", "esc")) → .poll()방향키, Esc가 몇 번 눌렸는지
on("TriggerRegister...Event", 인자...) → .poll()임의의 JASS 이벤트가 몇 번 발생했는지: 유닛 사망, 영역 진입, 피해, 타이머……

한계는 “몇 번 일어났는지”만 알 뿐 “누가, 무슨 글자를 입력했는지”는 모른다는 것입니다. 누구인지 구분하려면 대상마다 카운터를 따로 만드세요. AI 동료의 채팅 명령도 이렇게 연결했습니다.

주의

  • 만든 것은 직접 지워야 합니다: 떠다니는 텍스트, 연결선, 이미지, 패널, 트리거…… 지우지 않으면 계속 남습니다(Visual.clear()는 자신이 만든 것을 지웁니다). 게임에는 떠다니는 텍스트를 동시에 최대 약 100개까지 둘 수 있습니다.
  • BJ 함수는 native가 아닙니다: CreateTextTagUnitBJ 같은 함수는 맵 스크립트에서 native를 조합해 만든 것이라 여기에는 없습니다 — 그 구현을 보고 native를 호출하세요.
  • 어떤 상수는 먼저 변환해야 합니다: 예를 들어 ConvertPlayerColor(1), ConvertFogState(4)(값은 common.j 참고).
  • 호출 1회에 약 13 ms(핸들 변환 포함). 프로토콜 계층은 W3P 연산 코드 70 ~ 72이며, W3P 프로토콜을 참고하세요.