사용자:Senouis/위키스크립트 규격 제안
위키스크립트 설계 v.0.0.1 by Senouis
미디어위키 문법은 기본적으로 HTML만 대체한다. 따라서 프로그래밍 언어가 아니며, 위키 문법 만으로는 죽었다 깨어나도 실시간 렌더링이 안 된다.
그러나 CSS로 상태 머신(State Machine)을 구현하면 프로그래밍 언어로 만들 수 있으며, 따라서 적절한 변환을 거쳐 위키 문법과 유사한 형태의 스크립팅이 가능하다.
다만, CSS 상태 머신은 페이지 레이아웃을 해칠 가능성이 크다. 가능하면 HTML canvas 요소(Element)를 사용해야 한다.
이에 따라 미디어위키 문법을 살짝 변형하여 완벽한 프로그래밍이 가능한 위키스크립트를 제안한다.
사용법
게임에 {{위키스크립트|(위키스크립트 문서 이름)}}을 삽입한다. 즉 틀을 삽입하면 소도구 등으로 스크립트가 정의된 다른 문서를 파싱한다.
위키스크립트 기본 구조
<noinclude>[[분류:위키스크립트 문서]]</noinclude>를 부착한 문서를 정의하고, 각 문서마다 다음 순서대로 이름을 가진 단락을 정의한다.
0번째 단락
시작(1번째)
- '시작' 문단은 스크립트의 초기값 정의를 다룬다.
프레임(2번째)
- Javascript의 requestAnimatedFrame( )을 사용하여 매 프레임마다 이 문단의 내용을 실행
렌더링(3번째)
- 이 단락은 사실 없어도 되긴 하나('프레임' 단락에서 필요한 일을 할 수 있음), 리버
이벤트-키보드
이벤트-마우스
이벤트-조이스틱
이벤트-충돌
이벤트-사운드
이벤트-읽고쓰기
이벤트-네트워크
커스텀-이벤트
기본 연산 및 API
호출법
- 리버티게임에서 제공하는 기본 게임 제작용 위키스크립트 기능은 {{특수:위키스크립트#(API 이름)|(파라미터 1)|(파라미터 2)|...}} 형태로 호출한다.
- 기본 API 및 연산 호출이 없는 빈 줄은 무시한다.
변수 정의
- #var와 #vardefine은 JSON 형태로 값을 저장한다(대소문자 구분 있는 변수 명칭을 키로 삼음).
- #struct는 리버티게임에 작성된 JSON 문서를 불러와 구조체(structure) 데이터로 삼는다.
- {{특수:위키스크립트#struct|(JSON 문서 이름)|구조체 키}}
조건문, 반복문(흐름 제어)
- #if, #ifexpr, #ifexist, #switch 지원: 리버티게임:특수 함수에 따름
- 미디어위키 문법에 없는 반복문은 각각 #while(일반 반복문)과 #for(이터레이션)라는 이름을 가지며, 파라미터에 반복 처리할 문구를 삽입한다.
- {{특수:위키스크립트#while|(루프 유지 조건)|(루프 내용)}}
- {{특수:위키스크립트#for|인덱스 이름|인덱스 시작 값|인덱스 끝 값|(루프 내용)}}
- #for의 인덱스 이름은 루프 내용 안에서 전역 변수보다 높은 우선순위를 가진다. 따라서 겹칠 수 없다.
- 자바스크립트로 구현할 때에는 스택을 이용하여 시작할 때 컨텍스트 push 후 조건에 따라 끝나기 전까지 로컬 컨텍스트 파싱을 유지하다 끝나면 pop
기본 API
- 기본 API 이름은 기본적으로 위에서 언급하지 않은 리버티게임:특수 함수 내 키워드를 따른다.
- 소도구의 기능을 다음과 같이 래핑한다.
- CGI 값 변경: #offset-read, #offset-write
- #offset-read
- #offset-write
- DB: LocalStorage API
- #db-read
- #db-write
- #db-checksum
- DB2: 리버티게임 전용 LocalStorage API
- 미디어위키:Gadget-DB2.js의 기능을 끌어옴
- File: IndexedDB API
- #file-open
- #file-read
- #file-write
- #file-close
- CGI 값 변경: #offset-read, #offset-write
- 형변환(casting)
- #string2JSON
- #JSON2string
- #int2string
- #string2int
- #trunc
- Vibrate(진동)
- 미디어위키:Gadget-Vibrate.js의 기능을 끌어옴
- #vibrate
- TTS(음성 읽어주기)
- 미디어위키:Gadget-TTS.js의 기능을 끌어옴
- #tts
- 키보드 이벤트 래핑
- 마우스 이벤트 래핑
- 게임패드 이벤트 래핑
- Sound API 래핑
- 그 외 사이트 연동 목적 mw.Api 래핑 및 프론트엔드 네트워킹 구현을 위한 WebSocket 래핑
- #mwapi-***
- #websocket-***
기타
- invoke 파서(Scribunto 루아 모듈 호출자)의 이름은 추후 모듈 호출 기능을 위해 예약한다.
커스텀 스크립트 호출법(모듈화)
- '분류:위키스크립트 라이브러리'가 있으면
- 순수한 라이브러리를 만들어야 하면 '시작' 단락부터 '이벤트-네트워크' 단락을 만들되 각 단락을 비우면 된다.
- 사용자가 직접 만든 API는 {{특수:위키스크립트/(사용자 위키스크립트 문서 디렉토리)|(파라미터 1)|(파라미터 2)|...}} 형태로 호출한다.
- 성능 향상을 위해 메모이제이션을 사용한다(이전에 호출한 사용자 위키스크립트 문서의 파싱 결과를 기억)
구현 방향
- 소도구 측 스크립트(프론트엔드)
- 먼저, '위키스크립트' 틀의 파라미터에 삽입된 문서에 '분류:위키스크립트 문서'가 0번째 단락(문서 맨 위부터 '시작' 문단 이전)에 붙어 있는지 확인한다. mw.Api.getCategories(title)로 가져온 배열에 '위키스크립트 문서'가 있는지 확인하면 끝.
- '위키스크립트 오브젝트' 분류와 '위키스크립트 라이브러리' 분류도 확인한다.
- 그 다음index.php?title=(문서 이름)&action=raw§ions=(스크립트 문서 단락 번호)를 사용하여 문서 내용을 가져온다.
- 1번째 문단부터 한 줄씩 파싱하며 스크립트를 실행한다.
- {{특수:위키스크립트
- 구조체/클래스는 별도 정의된 JSON 문서를 가져오는 방식으로 구현
- 실행 컨텍스트는 배열을 1회성 순회하되, tick은 request
- 실행 바이너리의 자료구조는 다음과 같은 JSON 포맷을 사용
- 먼저, '위키스크립트' 틀의 파라미터에 삽입된 문서에 '분류:위키스크립트 문서'가 0번째 단락(문서 맨 위부터 '시작' 문단 이전)에 붙어 있는지 확인한다. mw.Api.getCategories(title)로 가져온 배열에 '위키스크립트 문서'가 있는지 확인하면 끝.
{
"module": {
"main": ...(메인 문서 raw data),
"두게임/렌더링라이브러리": ...(라이브러리 raw data),
...
},
"structure": { "한게임/DataStructure.json": { (JSON 객체) },
...
},
"variables": { "var1": 0, "var2": "예시", ... },
"current-context": {
"start": [ ... , ... , ..., ... ],
"tick": [ [] , [], [] , ... ],
"event-keyboard": [ ... , {}, ..., ... ],
...
}
}
- 오브젝트/라이브러리 로드 시 '시작' 문단은 즉시 실행, '프레임' 문단과 '이벤트' 문단들은 순회 큐에 추가
- PHP 확장 기능 측(백엔드)
- {{특수:위키스크립트#...}} 구문을 웹 페이지로 직접 볼 경우 해당 구문은 아무 것도 출력하지 않는다.