Lua는 게임에서 스크립팅 언어로 어떻게 작동합니까?


67

루아가 정확히 무엇인지, C ++로 프로그래밍 된 게임이 그것을 어떻게 사용하는지에 대해 조금 흐릿합니다. 나는 그것이 어떻게 컴파일되고 실행되는지에 대해 주로 묻고있다.

예를 들어 Lua 스크립트를 사용하는 C ++로 작성된 프로그램을 사용하는 경우 : Lua의 코드는 C ++로 작성된 기본 프로그램의 함수를 호출하고 컴파일되고 C ++의 메모리 힙에 추가되기를 기다리는 컴파일되지 않은 클래스로 작동합니다. 프로그램?

아니면 Linux에서 주 프로그램과 완전히 별 개인 프로그램을 실행하는 bash 스크립트처럼 작동합니까?

답변:


90

스크립팅은 개념적으로 다른 프로그램 (호스트) 내에서 프로그램 (스크립트)을 실행하는 프로그래밍 추상화입니다. 대부분의 경우 스크립트를 작성하는 언어는 호스트가 작성되는 언어와 다르지만 프로그램 내부 프로그램 추상화는 스크립팅으로 간주 될 수 있습니다.

개념적으로 스크립팅을 활성화하는 일반적인 단계는 다음과 같습니다 (호스트에 pseudo-c를 사용하고 스크립트에 pseudo-lua를 사용합니다. 정확한 단계는 아니지만 스크립팅을 활성화하는 일반적인 흐름과 비슷합니다)

  1. 호스트 프로그램에서 가상 머신을 작성하십시오.

    VM m_vm = createVM();
  2. 함수를 작성하여 VM에 노출하십시오.

    void scriptPrintMessage(VM vm)
    {
        const char* message = getParameter(vm, 0); // first parameter
        printf(message);
    }
    
    //...
    
    createSymbol(m_vm, "print", scriptPrintMessage);
    

    함수를 노출 한 이름 ( print)이 함수 자체의 내부 이름 ( scriptPrintMessage) 과 일치하지 않아도됩니다.

  3. 함수를 사용하는 스크립트 코드를 실행하십시오.

    const char* scriptCode = "print(\"Hello world!\")"; // Could also be loaded from a file though
    doText(m_vm, scriptCode);
    

그것이 전부입니다. 그런 다음 프로그램은 다음과 같은 방식으로 진행됩니다.

  1. 당신은 전화 doText(). 그런 다음 제어가 가상 머신으로 전송되어 내부 텍스트를 실행합니다 scriptCode.

  2. 스크립트 코드는 이전에 내 보낸 심볼을 찾습니다 print. 그런 다음 제어를 기능으로 전달합니다 scriptPrintMessage().

  3. scriptPrintMessage()완료, 제어 가상 컴퓨터로 다시 전송합니다.

  4. 모든 텍스트 scriptCode가 실행되면 doText()을 마치고 제어는 다음 줄에 프로그램으로 다시 전송됩니다 doText().

따라서 일반적으로 다른 프로그램 내에서 프로그램을 실행하면됩니다. 이론적으로 말하면 스크립트 없이는 할 수없는 것이 없지만이 추상화를 통해 흥미로운 일을 쉽게 할 수 있습니다. 그들 중 일부는 다음과 같습니다.

  • 우려의 분리 : C / C ++로 게임 엔진을 작성한 다음 루아와 같은 스크립트 언어로 실제 게임을 작성하는 것이 일반적인 패턴입니다. 게임 코드는 엔진 자체와 완전히 독립적으로 개발할 수 있습니다.

  • 유연성 : 스크립팅 언어는 일반적으로 해석되므로 스크립트를 변경해도 전체 프로젝트를 다시 빌드 할 필요는 없습니다. 프로그램을 다시 시작하지 않아도 스크립트를 변경하고 결과를 확인할 수 있습니다.

  • 안정성 및 보안 : 스크립트가 가상 머신 내에서 실행 중이므로 올바르게 수행하면 버그가있는 스크립트가 호스트 프로그램을 중단시키지 않습니다. 사용자가 자신의 스크립트를 게임에 쓰도록 허용 할 때 특히 중요합니다. 원하는만큼 독립적 인 가상 머신을 생성 할 수 있습니다. (나는 한 번에 각각의 루아 가상 머신에서 실행되는 MMO 서버를 만들었습니다)

  • 언어 기능 : 선택한 호스트 및 스크립트 언어에 따라 스크립팅 언어를 사용할 때 각 언어가 제공하는 최상의 기능을 활용할 수 있습니다. 특히 루아의 코 루틴은 C 또는 C ++에서 구현하기가 매우 어려운 매우 흥미로운 기능입니다.

그러나 스크립트는 완벽하지 않습니다. 스크립팅을 사용하면 몇 가지 일반적인 단점이 있습니다.

  • 디버깅은 매우 어려워집니다. 일반적으로 일반적인 IDE에 포함 된 디버거는 스크립트 내의 코드를 디버깅하도록 설계되지 않았습니다. 이로 인해 콘솔 추적 디버깅이 원하는 것보다 훨씬 일반적입니다.

    lua와 같은 일부 스크립팅 언어에는 디버깅 기능이있어 Eclipse와 같은 일부 IDE에서 활용할 수 있습니다. 이 작업을 수행하는 것은 매우 어렵습니다. 솔직히 스크립트 디버깅과 기본 디버깅을 본 적이 없습니다.

    그건 그렇고, Unity 개발자 가이 문제에 대한 관심이 매우 부족하다는 것은 게임 엔진에 대한 나의 비판이며, 더 이상 그것을 사용하지 않지만 주저하지 않습니다.

  • IDE 통합 : IDE가 프로그램에서 어떤 기능을 내보내는 지 알지 못할 가능성이 높으므로 IntelliSense 등과 같은 기능이 스크립트에서 작동하지 않을 수 있습니다.

  • 성능 : 일반적으로 해석되는 프로그램이므로 아키텍처가 실제 하드웨어와 다를 수있는 추상 가상 머신을 의미하므로 스크립트는 일반적으로 원시 코드보다 실행 속도가 느립니다. luaJIT 및 V8과 같은 일부 VM은 실제로 잘 작동합니다. 스크립트를 너무 많이 사용하면 눈에 띄게 나타날 수 있습니다.

    일반적으로 컨텍스트 변경 (호스트-스크립트 및 스크립트-호스트)은 비용이 많이 들기 때문에 성능 문제가있는 경우이를 최소화 할 수 있습니다.

스크립트 사용 방법은 전적으로 귀하에게 달려 있습니다. 매우 얇은 게임 엔진으로 스크립팅 언어로 전체 게임을 만드는 것처럼 설정을로드하는 것만 큼 간단한 것에 사용되는 스크립트를 보았습니다. 한때 루아와 JavaScript (V8을 통해) 스크립팅이 혼합 된 매우 이국적인 게임 엔진을 보았습니다.

스크립팅은 도구 일뿐입니다. 멋진 게임을 만드는 방법은 전적으로 귀하에게 달려 있습니다.


나는 이것에 익숙하지 않지만 Unity를 사용합니다. 유니티에 대해 언급 했으니 좀 더 자세히 설명해 주시겠습니까? 다른 것을 사용해야합니까?
Tokamocha

1
나는 printf당신의 예제에서 사용하지 않을 것 입니다 (또는 최소한의 사용 printf("%s", message);)
ratchet freak

1
@ratchetfreak : 메시지 끝에 괄호가 붙은 세미콜론이 나에게 윙크합니다.
Panda Pajama

1
이 사이트에서 오랫동안 본 최고의 답변 중 하나입니다. 그것은 모든 공감대를받을 가치가 있습니다. 아주 잘 했어요
Steven Stadnicki

1
게임에서 Lua의 포스터 자식은 World of Warcraft이며, 대부분의 UI는 Lua로 작성되며 대부분 UI로 플레이어가 대체 할 수 있습니다. 당신이 언급하지 않은 것에 놀랐습니다.
Michael Hampton

7

일반적으로 일부 기본 함수를 Lua에 바인딩하거나 노출합니다 ( 수동으로 수행 할 수는 있지만 유틸리티 라이브러리 를 사용하는 경우가 종종 있음 ). 게임에서 해당 Lua 코드를 실행할 때 Lua 코드가 네이티브 C ++ 코드를 호출 할 수 있습니다. 이런 의미에서 Lua 코드가 기본 코드를 호출한다고 가정한다는 것은 사실입니다 (Lua에는 자체 표준 기능 라이브러리가 있지만 모든 것을 위해 기본 코드를 호출 할 필요 는 없습니다 ).

Lua 코드 자체는 Lua 런타임에 의해 해석되는데, 이는 사용자 프로그램에서 라이브러리 (일반적으로)로 링크하는 C 코드입니다. Lua 홈페이지 에서 Lua 작동 방식에 대해 자세히 알아볼 수 있습니다 . 특히 C ++는 실제로 동적으로 거의 컴파일되지 않기 때문에 특히 C ++ 클래스를 생각할 때 Lua는 "컴파일되지 않은 클래스"가 아닙니다. 그러나 게임이 실행되는 Lua 스크립트와 Lua 스크립트로 생성 된 개체는 게임의 시스템 메모리 풀에서 공간을 소비합니다.


5

Lua와 같은 스크립팅 언어는 여러 가지 방법으로 사용될 수 있습니다. 말했듯이 Lua를 사용하여 기본 프로그램에서 함수를 호출 할 수 있지만 원하는 경우 C ++ 측에서 Lua 함수를 호출 할 수도 있습니다. 일반적으로 선택한 스크립팅 언어에 유연성을 제공하는 인터페이스를 구축하여 일련의 시나리오에서 스크립팅 언어를 사용할 수 있습니다. Lua와 같은 스크립팅 언어의 가장 큰 장점은 컴파일되지 않고 해석되므로 Lua 스크립트를 즉석에서 수정할 수 있으므로 게임이 컴파일 될 때까지 기다릴 필요가 없으므로 컴파일 할 때만 기다릴 필요가 없다는 것입니다. 당신의 취향에 맞지 않습니다.

Lua 명령은 C ++ 프로그램이 실행하려고 할 때만 호출됩니다. 따라서 코드는 호출 될 때만 해석됩니다. Lua를 기본 프로그램과 별도로 실행되는 bash 스크립트로 생각할 수 있습니다.

일반적으로 스크립트 언어를 사용하여 업데이트하거나 더 아래로 반복하려는 항목에 스크립트 언어를 사용하려고합니다. 많은 회사에서 GUI에 사용하여 인터페이스에 많은 사용자 정의 기능을 제공하는 것을 보았습니다. 그들이 Lua 인터페이스를 어떻게 만들 었는지 알면 GUI를 직접 수정할 수도 있습니다. 그러나 AI 로직, 무기 정보, 캐릭터 대화 등과 같이 Lua를 사용할 수있는 다른 방법이 많이 있습니다.


3

Lua를 포함한 대부분의 스크립팅 언어 는 기본적으로 스크립트 명령어를 "실제"CPU 명령어 또는 함수 호출에 매핑하는 시스템 인 VM (가상 머신 )에서 작동합니다. Lua VM은 일반적으로 기본 응용 프로그램과 동일한 프로세스에서 실행됩니다. 이것은 그것을 사용하는 게임에 특히 해당됩니다. Lua API는 스크립트 파일을로드하고 컴파일하기 위해 기본 애플리케이션에서 호출하는 여러 기능을 제공합니다. 예를 들어 luaL_dofile()주어진 스크립트를 Lua 바이트 코드 로 컴파일 한 다음 실행합니다. 그런 다음이 바이트 코드는 API 내에서 실행되는 VM에 의해 기본 시스템 명령어 및 함수 호출로 매핑됩니다.

C ++와 같은 모국어를 스크립팅 언어와 연결하는 프로세스를 바인딩 이라고 합니다. Lua의 경우 API는 기본 함수를 스크립트 코드에 노출하는 데 도움이되는 함수를 제공합니다. 예를 들어 C ++ 함수를 정의 say_hello()하고이 함수를 Lua 스크립트에서 호출 가능하게 만들 수 있습니다. Lua API는 C ++ 코드를 통해 변수 및 테이블을 작성하여 스크립트가 실행될 때 표시되는 메소드를 제공합니다. 이러한 기능을 결합하면 전체 C ++ 클래스를 Lua에 노출 할 수 있습니다. Lua API를 사용하면 Lua 변수를 수정하고 네이티브 C ++ 코드에서 Lua 함수를 호출 할 수도 있습니다.

대부분의 스크립팅 언어가 스크립트 코드를 기본 코드와 쉽게 바인딩 할 수 있도록 API를 제공합니다. 대부분은 바이트 코드로 컴파일되어 VM에서 실행되지만 일부는 라인 단위로 해석 될 수 있습니다.

이것이 귀하의 질문을 명확히하는 데 도움이되기를 바랍니다.


3

아무도 이것을 언급하지 않았으므로 관심있는 사람들을 위해 여기에 추가 할 것입니다. Game Scripting Mastery 라는 주제에 관한 책이 있습니다 . 이것은 꽤 오래 전에 쓰여진 환상적인 글이지만 오늘날에도 완전히 관련이 있습니다.

이 책은 스크립팅 언어가 기본 코드에 어떻게 적용되는지 보여줄뿐만 아니라 고유 한 스크립팅 언어를 구현하는 방법도 알려줍니다. 99 %의 사용자에게는 이것이 과잉이지만 실제로 구현하는 것보다 (아주 기본적인 형태로도) 무언가를 이해하는 더 좋은 방법은 없습니다.

게임 엔진을 직접 작성하거나 렌더 엔진으로 만 작업하려는 경우이 텍스트는 스크립트 언어를 엔진 / 게임에 가장 잘 통합 할 수있는 방법을 이해하는 데 매우 중요합니다.

그리고 자신 만의 스크립팅 언어를 만들고 싶다면 이것이 내가 아는 한 가장 좋은 곳 중 하나입니다.


2

첫째, 스크립팅 언어는 일반적으로 컴파일되지 않습니다 . 그것은 일반적으로 그것들을 스크립팅 언어로 정의하는 것의 큰 부분입니다. 그들은 종종 대신에 "통역"된다. 이것이 기본적으로 의미하는 것은 다른 언어 (한 있다는 것입니다 되어 줄 단위, 실시간으로 텍스트로 읽기, 작업을 수행하지보다 더 자주, 컴파일이).

이 언어와 다른 언어의 차이점은 스크립팅 언어가 더 단순한 경향이 있다는 것입니다 (일반적으로 "높은 수준"이라고 함). 그러나 컴파일러는 코딩의 "인간 요소"와 함께 발생하는 많은 문제를 최적화하는 경향이 있으므로 결과적으로 이진 파일이 더 작고 읽기 쉬운 경향이 있습니다. 또한 컴파일 된 프로그램과 함께 실행중인 코드 를 읽기 위해 실행해야하는 다른 프로그램의 오버 헤드가 줄어 듭니다 .

지금, 당신은 생각할지도 모릅니다. "글쎄요. 좀 더 쉬워졌지만 왜 누군가가 약간의 사용 편의성을 위해 그 성능을 포기할까요?"

이 가정에 홀로 있지는 않지만 스크립트 언어를 사용하여 수행하는 작업에 따라 수행 편의성이 성능을 희생 할 가치가 있습니다.

기본적으로 : 개발 속도가 프로그램 실행 속도보다 중요한 경우에는 스크립팅 언어를 사용하십시오. 게임 개발에는 이와 같은 상황이 많이 있습니다. 특히 고급 이벤트 처리와 같은 사소한 것들을 다룰 때.

편집 : 루아가 게임 개발에서 인기있는 이유는 그것이 지구상에서 가장 빠른 (가장 빠른 것은 아니지만) 공개적으로 사용 가능한 스크립트 언어 중 하나이기 때문입니다. 그러나이 추가 속도로 인해 일부 편의성이 희생되었습니다. 즉, C 또는 C ++를 직접 사용하는 것보다 여전히 편리합니다.

중요 편집 : 추가 연구 결과 스크립팅 언어의 정의에 대해 더 많은 논란이 있음을 발견했습니다 ( Ousterhout의 이분법 참조 ). 언어를 "스크립팅 언어"로 정의하는 주된 비판은 언어가 해석되거나 컴파일 된 언어의 구문이나 의미에 중요하지 않다는 것입니다.

일반적으로 "스크립팅 언어"로 간주되는 언어는 일반적으로 컴파일되지 않고 전통적으로 해석되지만 "스크립팅 언어"로 정의되는 길고 짧은 것은 실제로 사람들이 언어를 보는 방식과 제작자가 정의한 방식의 조합에 달려 있습니다.

일반적으로, 위의 링크 된 기사에 따라 다음 기준을 충족하는 언어는 스크립트 언어 (오우 스터 하우 트의 이분법에 동의한다고 가정)로 쉽게 간주 될 수 있습니다.

  • 그들은 동적으로 입력됩니다
  • 복잡한 데이터 구조를 거의 제공하지 않습니다.
  • 그 안의 프로그램 (스크립트)이 해석됩니다

또한 언어가 다른 프로그래밍 언어 (일반적으로 스크립팅 언어로 간주 되지 않는 언어) 와 상호 작용하고 작동하도록 설계된 경우 언어가 스크립팅 언어 인 것으로 종종 인정 됩니다.


1
"스크립팅 언어가 컴파일되지 않았습니다"라고 쓴 첫 번째 줄에 동의하지 않습니다. Lua는 실제로 JIT 컴파일러에 의해 실행되기 전에 중간 바이트 코드로 컴파일됩니다. 물론 일부는 한 줄씩 해석되지만 전부는 아닙니다.
glampert

"스크립트 언어"에 대한 귀하의 정의에 동의하지 않습니다. 스크립트 형식이 아닌 컴파일 된 형식으로 (또는 C #의 경우와 같이) 비교적 일반적으로 사용되는 이중 용도 (Lua 또는 C # 등)가있는 언어가 있습니다. 언어가 스크립팅 언어로 사용되는 경우 언어는 해석되고 컴파일되지 않은 언어로 엄격하게 정의됩니다.
Gurgadurgen

공평하게도, 당신의 정의는 Wikipedia와 더 인라인입니다 : "스크립트 언어 또는 스크립트 언어는 스크립트를 지원하는 프로그래밍 언어입니다. (컴파일이 아닌) 해석 할 수있는 특별한 런타임 환경을 위해 작성된 프로그램입니다." 그때 내 의견.
glampert

1
일반 Lua조차도 바이트 코드로 완전히 컴파일되고 JIT 컴파일러는 원시 바이너리를 생성 할 수도 있습니다. 따라서 루아는 해석되지 않습니다.
Oleg V. Volkov

첫 번째 부분은 iffy, 나는 downvote를 유혹하고 있습니다. 그는 궁극적으로 해석되고 @ OlegV.Volkov JIT 컴파일은 컴파일 된 것을 만들지 않는다는 점에서 맞습니다. 컴파일은 Lua가 가진 컴파일 시간에 의해 정의되며, Lua 바이트 코드는 그렇지 않습니다 (JIT 또는 JIT 없음). 우리 용어가 혼동되지 않도록합시다.
Alec Teal
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.