내가 만든 언어의 개발환경을
Visual Studio Code로 빠르고 쉽게 구축하기
이승재 & 강성훈
넥슨코리아 데브캣스튜디오
Part A 발표자: 이승재
카바티나 스토리
데스크탑 히어로즈
마비노기 2
마비노기 듀얼
실버바인 서버엔진 2
@0xcafea1fa
직전 시간 발표에 이어지는 내용입니다
도메인 언어
“어떤 애플리케이션 프로그램을 제어하거나
환경설정하기 위한 단순한 언어든,
규칙이나 절차를 명시하기 위한 더 복잡한 언어든,
우리는 여러분의 프로젝트를 문제 도메인에 가까운 곳으로
옮길 방법들을 궁리해봐야 한다고 생각한다.
더 높은 추상화 수준에서 작업함으로써
사소한 구현의 세부사항들을 무시하고
도메인의 문제들을 푸는 일에만 정신을 집중할 수 있다.”
- 실용주의 프로그래머 12절 <도메인 언어>
텍스트 기반 도메인 언어
비주얼 스크립팅과 비교해서,
• 작동하는 첫 버전을 빠르게 만들 수 있다.
• 변경을 추적하기 쉽다.
• 대규모 리팩토링을 하기 쉽다.
• 검색이 가능하다.
[시작]
전투중이면 -> 가만서있는다=0.5, [전투중]
!다돌아왔으면 -> 제자리로돌아간다, [돌아가기]
무조건 -> 배회한다=$배회주기
[전투중]
!전투중이면 -> 제자리로돌아간다, [돌아가기]
스킬사용해본다( $스킬_평타 ) -> 시전성공
무조건 -> 가만서있는다=0.1
[돌아가기]
전투중이면 -> 가만서있는다=0.5, [전투중]
다돌아왔으면 -> 가만서있는다=0.5, [시작]
무조건 -> 제자리로돌아간다
FSM카 바 티 나 스 토 리
A I 스 크 립 트
조건식 행동 상태 트랜지션
몬스터 종류마다 달라지는 상수값
상수값을 참고하는 조건식
HFSM
상태 트랜지션
실행 중 일시 정지
변수
초기화
마 비 노 기 2
A I 스 크 립 트
NDC13 - M2 AI코드 개발 생산성 향상 사례 http://lee-seungjae.github.io/CodeHotloadingAndInHouseScriptLanguage.html
Lua데 스 크 탑 히 어 로 즈
던 전 스 크 립 트
복잡한 기능을 가진 부품
일정 시간 지연
트리거 설치
한글 식별자
모두 끝날 때까지 기다림
NDC11 - 온라인 게임 처음부터 끝까지 동적언어로 만들기 http://lee-seungjae.github.io/BuildingOnlineGameEntirelyWithDynamicLanguage.html
어떻게 만드나?
• 구문 분석 = 텍스트의 구조를 파악하기
• 실행 = 동작하게 하기
어떻게 만드나? – 구문 분석
• 라인 중심 형식의 언어로 만든다
• 되부름 하향 구문 분석기(recursive descent parser)를 작성한다
• 파서 생성기를 사용한다
어떻게 만드나? – 실행
• 구문 분석 결과를 트리로 구성해놓고 평가
• 다른 언어로 트랜스파일(번역)
• 바이트코드로 컴파일한 다음 실행
• JIT
※ 바인딩(호스트언어와상호작용)을 어떻게 만들지 고려할 것
구문 분석, 실행
• 선택지가 많다
• 참고자료도 많다
• 학부 때 컴파일러 수업 들었다
일단 이거면 동작하는 초기 구현을 만들 수 있다
Lua같은 언어의 틀 안에서 만들어도 됨
시간이 흐르고…
도메인 언어는 상상 이상으로 강력하다
• 도메인 언어를 사용해서 만든 프로그램이 설계자의 상상을 뛰어넘는 크기로 자라난다
• 기능도 계속 덧붙이게 된다
개발환경에 대한 불만이 쌓인다
• 디버깅이 안되잖아
• 자동완성 됐으면 좋겠는데
• 정의로 바로 가기 안됨?
• 리네임은?
개발환경을 만드는 비용을 예측하기 어렵다
• 텍스트 에디터를 바닥부터 만들 수는 없잖아;;;
• 비용을 예측하기 어려운 설계는 채택하기 꺼려진다
열악한 레거시 개발환경에 그냥 적응해서 살고 있지는 않나?
도메인 언어를 사용하면 좋을 상황을 놓치고 있지는 않나?
Visual Studio Code
• 가볍다, 공짜다
• Visual Studio에 익숙하면 빠르게 적응할 수 있다
• 언어별 확장 만들기가 대단히 쉽다!
이야기할 내용
• 최근에 루아 디버거와 카일루아 언어 지원을 붙여본 경험을 공유합니다
– 비용이 대략 어느 정도인지
– 어떤 걸 주의해서 시행착오를 줄일 수 있을지
디버거 확장 개발하기
Part A
The VS Code Debug Protocol (CDP)
• 디버그 어댑터를 만들어야 한다
– 디버거와 VS Code 사이를 중개한다.
– VS Code에 의해 실행되는 콘솔 프로그램.
– 별도 프로세스로 동작하기 때문에 아무 언어로나 만들어도 된다.
– VS Code와는 stdin/stdout으로 통신함.
The VS Code Debug Protocol (CDP)
https://code.visualstudio.com/docs/extensionAPI/api-debugging
The VS Code Debug Protocol (CDP)
• 요청/응답 메시지 (16)
– Initialize,launch,attach,disconnect,configurationDone
– pause,next,continue,stepIn,stepOut
– stackTrace,scopes,variables,threads
– setBreakpoints
– evaluate
• 이벤트 메시지 (2)
– output
– stopped
잠깐, 디버거를 어떻게 만들지?
• 다른 프로세스의 실행을 제어하고 내부를 들여다볼 수 있어야 한다.
– Windows 디버깅 API는 기계어를 위한 것이다.
– Non-JIT 가상머신을 디버깅하기에는너무 저수준이다.
• 발상의 전환
– 프로세스가 자신을 디버깅할 수 있는 인터페이스를 제공하면 된다.
– TCP 소켓이 가장 만만하다.
즉, 이렇게 만들면 된다
• 디버그 어댑터
– VS Code와 CDP로 통신한다.
– 디버그 대상과 TCP로 통신한다.
– 디버그 대상을 실행하기도 한다.
• 디버그 대상
– TCP를 통해 디버깅 명령을 받는다.
Lua Debugger by devCAT
• 데모
• VS Code 확장 검색창에 devcat을 입력하세요!
디버거 만들기: Lua의 경우
• debug 라이브러리가 있다.
– 이것 자체로 디버거는 아니지만,
– 디버거를 만드는데 충분한 기본 요소들을 제공한다.
디버거 만들기: Lua의 경우
• luasocket을 통해 디버깅 요청을 받고 처리해주는 라이브러리를 Lua만으로 짤 수 있다.
– MobDebug/Zerobrane이먼저 구현함.
– luasocket만 있으면 어떤 환경에도 붙일 수 있다.
Lua Debugger by devCAT
• vscode-debuggee.lua를 require하고 start() 불러주면 디버그 어댑터에 연결된다.
VS Code DebugAdapter.exe Lua
vscode-debuggee.lua
실행
CDP
실행
자체 프로토콜
Lua Debugger by devCAT
• enterDebugLoop()
– continue 명령이 오기 전까지는 계속 디버그 명령어를 처리한다.
– 에러를 만났을 때 이것을 부르면 됨.
• poll()
– 쌓인 디버그 명령어가 있으면 처리하고, 없으면 즉시 리턴한다.
– 로직 코드에서 때때로 불러줘야 함.
– 실행 중에 브레이크포인트 설정하는 데 필요.
얼마나 걸렸나?
• 총 5주
– 루아 VM 패치해서 속도 저하 없는 브레이크포인트 구현하는 데 약 1주
• devcat-studio/lua-5.1.5-op_halt
– Visual Studio Code로 디버깅되게 하는 데 약 3주
– Gideros Player 원격제어에 약 1주
팁 1: 프로토콜 문서를 참고하자
• 존재하는 줄 몰라서 처음에 시간을 낭비했음.
– https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/parts/debug/common/debugProtocol.d.ts
팁 2: 기존 디버거 확장을 클론해서 시작하자
• devcat-studio/VSCodeLuaDebug 추천
– Microsoft/vscode-mono-debug 에서 클론했음.
• 프로토콜 파악하고 구현하는 시간을 크게 아낄 수 있음.
팁 3: 실행기에 디버깅 기능을 포함해도 된다
• Lua는 매우 범용적이고 최소주의적으로 설계된 언어.
– 디버거 없고 디버그 API만 제공.
– 소켓도 기본 기능이 아니고 확장임.
• 한정된 용도의 도메인 언어를 만들면서 굳이 Lua의 설계를 따라갈 필요는 없다.
팁 4: CDP를 디버그 대상이 이해해도 된다
• 디버그 어댑터가 메시지를 번역할 필요 없이 전달하기만 하면 됨.
– Lua Debugger는 초기화/실행 관련 메시지만 인식하고 나머지를 전부 전달하게 했음
• 범용성은 떨어지지만 빨리 만들 수 있다.

이승재, 강성훈, 내가 만든 언어의 개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 #1, NDC2017

  • 1.
    내가 만든 언어의개발환경을 Visual Studio Code로 빠르고 쉽게 구축하기 이승재 & 강성훈 넥슨코리아 데브캣스튜디오
  • 2.
    Part A 발표자:이승재 카바티나 스토리 데스크탑 히어로즈 마비노기 2 마비노기 듀얼 실버바인 서버엔진 2 @0xcafea1fa
  • 3.
    직전 시간 발표에이어지는 내용입니다
  • 4.
    도메인 언어 “어떤 애플리케이션프로그램을 제어하거나 환경설정하기 위한 단순한 언어든, 규칙이나 절차를 명시하기 위한 더 복잡한 언어든, 우리는 여러분의 프로젝트를 문제 도메인에 가까운 곳으로 옮길 방법들을 궁리해봐야 한다고 생각한다. 더 높은 추상화 수준에서 작업함으로써 사소한 구현의 세부사항들을 무시하고 도메인의 문제들을 푸는 일에만 정신을 집중할 수 있다.” - 실용주의 프로그래머 12절 <도메인 언어>
  • 5.
    텍스트 기반 도메인언어 비주얼 스크립팅과 비교해서, • 작동하는 첫 버전을 빠르게 만들 수 있다. • 변경을 추적하기 쉽다. • 대규모 리팩토링을 하기 쉽다. • 검색이 가능하다.
  • 6.
    [시작] 전투중이면 -> 가만서있는다=0.5,[전투중] !다돌아왔으면 -> 제자리로돌아간다, [돌아가기] 무조건 -> 배회한다=$배회주기 [전투중] !전투중이면 -> 제자리로돌아간다, [돌아가기] 스킬사용해본다( $스킬_평타 ) -> 시전성공 무조건 -> 가만서있는다=0.1 [돌아가기] 전투중이면 -> 가만서있는다=0.5, [전투중] 다돌아왔으면 -> 가만서있는다=0.5, [시작] 무조건 -> 제자리로돌아간다 FSM카 바 티 나 스 토 리 A I 스 크 립 트 조건식 행동 상태 트랜지션 몬스터 종류마다 달라지는 상수값 상수값을 참고하는 조건식
  • 7.
    HFSM 상태 트랜지션 실행 중일시 정지 변수 초기화 마 비 노 기 2 A I 스 크 립 트 NDC13 - M2 AI코드 개발 생산성 향상 사례 http://lee-seungjae.github.io/CodeHotloadingAndInHouseScriptLanguage.html
  • 8.
    Lua데 스 크탑 히 어 로 즈 던 전 스 크 립 트 복잡한 기능을 가진 부품 일정 시간 지연 트리거 설치 한글 식별자 모두 끝날 때까지 기다림 NDC11 - 온라인 게임 처음부터 끝까지 동적언어로 만들기 http://lee-seungjae.github.io/BuildingOnlineGameEntirelyWithDynamicLanguage.html
  • 9.
    어떻게 만드나? • 구문분석 = 텍스트의 구조를 파악하기 • 실행 = 동작하게 하기
  • 10.
    어떻게 만드나? –구문 분석 • 라인 중심 형식의 언어로 만든다 • 되부름 하향 구문 분석기(recursive descent parser)를 작성한다 • 파서 생성기를 사용한다
  • 11.
    어떻게 만드나? –실행 • 구문 분석 결과를 트리로 구성해놓고 평가 • 다른 언어로 트랜스파일(번역) • 바이트코드로 컴파일한 다음 실행 • JIT ※ 바인딩(호스트언어와상호작용)을 어떻게 만들지 고려할 것
  • 12.
    구문 분석, 실행 •선택지가 많다 • 참고자료도 많다 • 학부 때 컴파일러 수업 들었다 일단 이거면 동작하는 초기 구현을 만들 수 있다 Lua같은 언어의 틀 안에서 만들어도 됨
  • 13.
  • 14.
    도메인 언어는 상상이상으로 강력하다 • 도메인 언어를 사용해서 만든 프로그램이 설계자의 상상을 뛰어넘는 크기로 자라난다 • 기능도 계속 덧붙이게 된다
  • 15.
    개발환경에 대한 불만이쌓인다 • 디버깅이 안되잖아 • 자동완성 됐으면 좋겠는데 • 정의로 바로 가기 안됨? • 리네임은?
  • 16.
    개발환경을 만드는 비용을예측하기 어렵다 • 텍스트 에디터를 바닥부터 만들 수는 없잖아;;; • 비용을 예측하기 어려운 설계는 채택하기 꺼려진다 열악한 레거시 개발환경에 그냥 적응해서 살고 있지는 않나? 도메인 언어를 사용하면 좋을 상황을 놓치고 있지는 않나?
  • 17.
    Visual Studio Code •가볍다, 공짜다 • Visual Studio에 익숙하면 빠르게 적응할 수 있다 • 언어별 확장 만들기가 대단히 쉽다!
  • 18.
    이야기할 내용 • 최근에루아 디버거와 카일루아 언어 지원을 붙여본 경험을 공유합니다 – 비용이 대략 어느 정도인지 – 어떤 걸 주의해서 시행착오를 줄일 수 있을지
  • 19.
  • 20.
    The VS CodeDebug Protocol (CDP) • 디버그 어댑터를 만들어야 한다 – 디버거와 VS Code 사이를 중개한다. – VS Code에 의해 실행되는 콘솔 프로그램. – 별도 프로세스로 동작하기 때문에 아무 언어로나 만들어도 된다. – VS Code와는 stdin/stdout으로 통신함.
  • 21.
    The VS CodeDebug Protocol (CDP) https://code.visualstudio.com/docs/extensionAPI/api-debugging
  • 22.
    The VS CodeDebug Protocol (CDP) • 요청/응답 메시지 (16) – Initialize,launch,attach,disconnect,configurationDone – pause,next,continue,stepIn,stepOut – stackTrace,scopes,variables,threads – setBreakpoints – evaluate • 이벤트 메시지 (2) – output – stopped
  • 23.
    잠깐, 디버거를 어떻게만들지? • 다른 프로세스의 실행을 제어하고 내부를 들여다볼 수 있어야 한다. – Windows 디버깅 API는 기계어를 위한 것이다. – Non-JIT 가상머신을 디버깅하기에는너무 저수준이다. • 발상의 전환 – 프로세스가 자신을 디버깅할 수 있는 인터페이스를 제공하면 된다. – TCP 소켓이 가장 만만하다.
  • 24.
    즉, 이렇게 만들면된다 • 디버그 어댑터 – VS Code와 CDP로 통신한다. – 디버그 대상과 TCP로 통신한다. – 디버그 대상을 실행하기도 한다. • 디버그 대상 – TCP를 통해 디버깅 명령을 받는다.
  • 25.
    Lua Debugger bydevCAT • 데모 • VS Code 확장 검색창에 devcat을 입력하세요!
  • 26.
    디버거 만들기: Lua의경우 • debug 라이브러리가 있다. – 이것 자체로 디버거는 아니지만, – 디버거를 만드는데 충분한 기본 요소들을 제공한다.
  • 27.
    디버거 만들기: Lua의경우 • luasocket을 통해 디버깅 요청을 받고 처리해주는 라이브러리를 Lua만으로 짤 수 있다. – MobDebug/Zerobrane이먼저 구현함. – luasocket만 있으면 어떤 환경에도 붙일 수 있다.
  • 28.
    Lua Debugger bydevCAT • vscode-debuggee.lua를 require하고 start() 불러주면 디버그 어댑터에 연결된다. VS Code DebugAdapter.exe Lua vscode-debuggee.lua 실행 CDP 실행 자체 프로토콜
  • 29.
    Lua Debugger bydevCAT • enterDebugLoop() – continue 명령이 오기 전까지는 계속 디버그 명령어를 처리한다. – 에러를 만났을 때 이것을 부르면 됨. • poll() – 쌓인 디버그 명령어가 있으면 처리하고, 없으면 즉시 리턴한다. – 로직 코드에서 때때로 불러줘야 함. – 실행 중에 브레이크포인트 설정하는 데 필요.
  • 30.
    얼마나 걸렸나? • 총5주 – 루아 VM 패치해서 속도 저하 없는 브레이크포인트 구현하는 데 약 1주 • devcat-studio/lua-5.1.5-op_halt – Visual Studio Code로 디버깅되게 하는 데 약 3주 – Gideros Player 원격제어에 약 1주
  • 31.
    팁 1: 프로토콜문서를 참고하자 • 존재하는 줄 몰라서 처음에 시간을 낭비했음. – https://github.com/Microsoft/vscode/blob/master/src/vs/workbench/parts/debug/common/debugProtocol.d.ts
  • 32.
    팁 2: 기존디버거 확장을 클론해서 시작하자 • devcat-studio/VSCodeLuaDebug 추천 – Microsoft/vscode-mono-debug 에서 클론했음. • 프로토콜 파악하고 구현하는 시간을 크게 아낄 수 있음.
  • 33.
    팁 3: 실행기에디버깅 기능을 포함해도 된다 • Lua는 매우 범용적이고 최소주의적으로 설계된 언어. – 디버거 없고 디버그 API만 제공. – 소켓도 기본 기능이 아니고 확장임. • 한정된 용도의 도메인 언어를 만들면서 굳이 Lua의 설계를 따라갈 필요는 없다.
  • 34.
    팁 4: CDP를디버그 대상이 이해해도 된다 • 디버그 어댑터가 메시지를 번역할 필요 없이 전달하기만 하면 됨. – Lua Debugger는 초기화/실행 관련 메시지만 인식하고 나머지를 전부 전달하게 했음 • 범용성은 떨어지지만 빨리 만들 수 있다.