나머지 대부분의 Stingray 리소스 유형처럼 게임이 실행 중일 때 Lua 스크립트를 수정 및 다시 컴파일하고, 즉시 게임을 다시 로드할 수 있습니다. 이는 새로운 변경 사항에 대한 디버깅 및 테스트를 진행하는 동안 반복 시간을 단축해주는 강력한 메커니즘입니다. Stingray 자산의 실시간 다시 로드의 배경에 대한 일반적인 내용은 리소스 다시 로드를 참조하십시오.
이 페이지에서는 Lua 스크립트를 다시 컴파일하고 다시 로드하는 방법, Lua 스크립트를 게임에 다시 로드할 때 적용되는 특별 고려 사항 몇 가지를 자세히 설명합니다.
스크립트를 변경한 다음 프로젝트 폴더에 저장합니다.
스크립트는 저장 시 즉시 다시 컴파일되지 않습니다. 스크립트를 강제로 다시 컴파일해야 합니다. Stingray Editor에서 F5 키를 누르거나 기본 메뉴에서 Edit > Level Testing > Refresh를 선택합니다. 이렇게 하면 컴파일된 데이터 폴더를 스크립트의 새 버전으로 업데이트합니다.
상태 막대를 통해 refresh 콘솔 명령을 발행하여 게임에서 스크립트를 다시 로드하도록 합니다. 상태 막대에서 명령 보내기를 참조하십시오.
리소스 다시 로드도 참조하십시오.
엔진이 Lua 파일을 다시 로드하면, 전체 파일을 다시 실행합니다. 이렇게 하면 모든 정의를 다시 해석하고, 모든 변수와 함수를 다시 정의하게 됩니다. 예기치 않은 부작용이 발생하는 경우도 있습니다.
먼저 알아야 할 점은 스크립트에서 정의한 함수가 Lua 환경을 새 코드에 일치시키기 위해 런타임 시 다시 정의되더라도, 반드시 호출될 필요는 없다는 것입니다.
예를 들어 부팅 스크립트에서 전역적 init() 함수를 다시 쓰는 경우, 이러한 변경 사항은 현재 게임 상태에는 영향을 미치지 않습니다. init() 함수는 게임이 시작되었을 당시, 이전 컨텐츠와 함께 호출되었기 때문입니다. 그러므로 이전에 수행된 모든 정의는 여전히 적용되고 있으며, 새 구현에서 수행한 모든 작업은 적용되지 않습니다.
다른 종류의 오브젝트 초기화에도 동일한 고려 사항이 적용됩니다. 예를 들어 생성 시점에 특정한 특성을 보유한 유닛을 초기화한다고 가정해 보겠습니다. 그런 다음 해당 유닛을 생성하는 함수를 변경하여 이러한 특성들을 변경하고 스크립트를 다시 로드합니다. 그러면 다시 로드 후 생성되는 새 유닛에는 이러한 변경 사항이 적용되어 있을지라도, 이미 생성되어 있는 유닛에는 적용되지 않습니다(새 유닛이 생성될 때 새로운 코드가 올바르게 호출되었다고 가정하는 경우).
새 테이블 변수를 생성할 때 Lua는 참조를 사용하여 변수가 테이블을 지정하도록 합니다. 두 번째 변수를 첫 번째와 동일하게 설정하는 경우, 두 번째 변수는 동일한 참조를 저장합니다. 이후 새로운 테이블을 지정하도록 첫 번째 변수를 다시 정의하면 두 번째 변수는 계속 원래 테이블을 지정합니다.
예를 들어 프로젝트에서 Appkit을 사용하고 있다고 가정하면 다음 코드를 포함한 project.lua 스크립트가 있어야 합니다.
Project = {} function Project.update(dt) print("hello.") end
게임이 시작되면 Appkit의 SimpleProject.extension_project 변수는 다음과 같이 Project 테이블에 참조를 저장합니다.
if Project then SimpleProject.extension_project = Project end
Project.update() 함수로 출력된 문자열을 변경하고 project.lua 스크립트 파일을 다시 로드한다고 가정해 보겠습니다. 프레임마다 로그에 새 문자열이 출력되기를 기대하지만, 게임은 계속 이전 문자열을 출력합니다.
이 동작의 원인은 게임이 다음 행을 다시 실행할 때와 관련이 있습니다.
Project = {}
효과는 새 테이블 참조를 생성하고 이를 전역 Project 변수에 저장하는 것입니다. 새로운 테이블은 새 문자열의 update() 구현이 할당됩니다. 그러나 SimpleProject.extension_project 변수는 여전히 이전에 전역 Project 변수에 적용된 이전 테이블을 지정합니다.
이 문제를 방지하려면 전역 테이블을 정의할 때 이 공식을 사용하는 것이 좋습니다.
Project = Project or {}
이 공식을 사용하면 스크립트를 다시 로드하거나 해당 행이 다시 실행될 때 Project 변수가 이미 존재하므로 새 테이블이 생성되지 않습니다. 대신 나머지 파일의 모든 함수와 구성원 정의가 기존 테이블에 적용됩니다. 그러므로 매 프레임에서 SimpleProject는 update() 함수에 의해 출력된 문자열을 변경하는 것을 계산에 넣게 됩니다.
다른 종류의 테이블이 아닌 값으로 스크립트를 캐시한 경우, 캐시된 이러한 값은 변수를 초기화한 코드가 다시 실행되지 않는 이상 업데이트되지 않습니다.
예를 들어 다음과 같은 코드가 있다고 가정해 보겠습니다.
Project = Project or {} function Project.update(dt) print("hello.") end
이전 섹션에서 설명한 대로, Project 테이블을 지정하는 변수를 어딘가에 저장하고 각 프레임에서 update() 함수를 호출하면, 해당 호출은 다시 로드 후 항상 Project.update() 함수의 새로운 버전을 사용합니다. 그러나 Project.update() 함수를 직접 지정하는 변수를 저장하면 해당 변수는 다시 로드 후에도 계속 이전 함수 정의를 사용합니다.
이는 문자열, 숫자와 같이 다른 Lua 변수 유형에도 동일하게 적용됩니다.