나무모에 미러 (일반/밝은 화면)
최근 수정 시각 : 2024-12-18 22:21:12

Roblox Studio/스크립트


파일:상위 문서 아이콘.svg   상위 문서: Roblox Studio
파일:Roblox 로고.svg파일:Roblox 로고 화이트.svg
게임 목록 | 이벤트 | 2차 창작 | 유료 서비스
Roblox Corporation
평가 (긍정적) | 문제점 및 비판 | 논란 및 사건 사고 | Roblox Studio스크립트 유료 모델


1. 개요2. 기본 문법
2.1. 변수2.2. 연산자2.3. 조건문2.4. 반복문2.5. 함수2.6. 테이블2.7. 주석
3. 기본 스타일
3.1. 스크립트3.2. 네이밍3.3. 코드3.4. 라이브러리3.5. 프레임워크
4. 스크립트 종류
4.1. 로컬 스크립트4.2. 서버 스크립트4.3. 모듈 스크립트
5. 자료형
5.1. BrickColor5.2. CFrame
5.2.1. 속성5.2.2. 메서드
5.3. Vector35.4. UDim2
5.4.1. 메서드5.4.2. 속성
5.5. TweenInfo
5.5.1. 속성
6. 라이브러리
6.1. bit326.2. buffer6.3. coroutine6.4. debug6.5. math
6.5.1. 함수6.5.2. 속성
6.6. os
6.6.1. 함수
6.7. string
6.7.1. 함수
6.8. table
6.8.1. 함수6.8.2. 속성
6.9. task
6.9.1. 함수
6.10. utf8
7. 글로벌
7.1. 함수7.2. 속성
8. 서비스
8.1. Debris8.2. MarketplaceService8.3. RunService8.4. TweenService8.5. BadgeService
9. 클래스 목록
9.1. BasePart
9.1.1. 속성9.1.2. 이벤트9.1.3. 메서드9.1.4. 기타
9.2. Instance
9.2.1. 속성9.2.2. 이벤트9.2.3. 메서드
9.3. Players9.4. RemoteEvent
9.4.1. 속성9.4.2. 이벤트9.4.3. 메서드9.4.4. 기타
9.5. ProximityPrompt
9.5.1. 속성9.5.2. 메서드9.5.3. 이벤트
10. 팁
10.1. Luau 관련10.2. 최적화 관련10.3. 보안 관련10.4. 개발 관련

1. 개요

로블록스 스튜디오의 스크립트에 대해 설명하는 문서다. 로블록스 스튜디오 스크립트의 사용 언어는 Lua의 파생 언어인 Luau[1]이다.

2. 기본 문법

로블록스 스튜디오 스크립트가 사용하는 언어인 Luau 가 Lua의 파생형인 만큼 대부분의 문법이 Lua와 일치한다. 하지만 Lua에는 없는 문법이 다수 존재한다.

2.1. 변수

변수는 어떠한 데이터를 담는 공간이다. 일반적으로 변수 생성은 local 로 가능하다.[2]
#!syntax lua
local a = 123 -- number형
local b = "Hello World!" -- string형
local c = true -- boolean형
위 코드처럼 변수는 다양한 자료형들을 담을 수 있다.
변수의 출력은 일반적으로 print 를 사용한다.
#!syntax lua
local a = 1
print(a) -- 1 출력
local b = "Hello World!"
print(b) -- Hello World! 출력
변수끼리의 연산도 가능하다. 단, boolean같이 서로 연산이 불가능한 자료형도 있다.
#!syntax lua
local a = 1
local b = 2
local c = a + b
local d = (b / a - b * a)^a + b

print(c) -- 3
print(d) -- 2
local 을 사용하지 않고 생성한 변수는 스크립트 내 아무 범위에서나 사용이 가능하다. 즉 전역 변수가 된다. 반대로 local을 사용하여 생성된 변수는 전역 스코프에서 선언하면 전역 변수가 되는 것이고 지역 스코프 내에서 선언하면 지역 변수가 된다. 개념만으로는 이해가 어려우니 아래 예제 코드를 살펴보자.
#!syntax lua
a = 1 -- 전역 변수, 어디에서나 사용이 가능하다.
local b = 2 -- 이 또한 전역 변수, 어디에서나 사용이 가능하다.

do
    local c = 3 -- 지역 변수, do 스코프 내에서만 사용이 가능하다.
end
하지만 local 없이 변수를 선언하는 건 삼가야 한다. local 없이 선언한 변수는 아무 메소드 안에서 언급해도 스크립트 모든 곳에서 사용 할 수 있지만 local 과 함께 선언한 변수가 local 없이 선언한 변수보다 더 빠르고, 해커들이 바이트코드 상태에서 찾기 더 힘들기 때문이다.[3]

2.2. 연산자

2.3. 조건문

스크립팅을 하다보면 필연적으로 사용해야 하는 부분이 있다. 바로 조건문이다. 아래는 조건문이 활용될 수 있는 간단한 예이다.[8]
스크립트는 이러한 조건들을 다루기 위해 조건문을 사용한다. 조건문은 앞서 나열한 연산자들을 사용한다. 다음은 간단한 조건문을 사용한 예제 코드이다.
#!syntax lua
if true then
    print("첫번째 조건 통과") -- 실행된다.
end

if 1 == 2 then
    print("두번째 조건 통과") -- 실행되지 않는다.
end

if not 1 >= 3 and true then
    print("세번째 조건 통과") -- 실행된다.
end
이처럼 조건문은 기본적으로 'if 조건 then 조건 통과시 실행될 코드 end' 로 구성된다. 이러한 조건문엔 추가로 else, elseif 를 덧붙일 수 있는데, 아래 예제 코드를 통해 살펴보자.
#!syntax lua
if false then
    print("첫번째 조건 통과") -- 실행되지 않는다.
elseif false or 1 == 2 then
    print("두번째 조건 통과") -- 실행되지 않는다.
else
    print("세번째 조건 통과") -- 실행된다.
end
elseif 와 else 는 if 조건문이 통과되지 않았을시 실행되는 추가 조건문들이다. elseif 는 처음 if 조건문이 통과되지 않았을시 그 다음 if의 역할을 한다. else 는 if 와 elseif 조건들이 모두 통과되지 않았을시 무조건 실행되는 예외처리 역할을 한다.[9] elseif 는 if 다음에 연속적으로 붙을 수 있는 반면, else 는 마지막 조건으로만 사용이 가능하다.
추가로 간이 조건문도 사용이 가능하다. 아래 예제 코드들을 통해 사용방법을 익혀보자.
#!syntax lua
-- 구버전
local a = true and 1 -- 1이 저장된다.
local b = false or 2 -- 2가 저장된다.
-- 최신 버전
local a = if true then 1 -- 1이 저장된다.
local b = if false then nil else 2 -- 2가 저장된다.
간단한 간이 조건문은 구버전을 사용해도 문제없지만, 복잡한 간이 조건문은 최신 버전을 사용하는 게 좋다. 그러나 간이 조건문을 과도하게 사용할시 가독성에 문제가 생길수 있다. 따라서 간이 조건문은 상황에 따라서 정말 필요할 때만 사용하도록 하자.

2.4. 반복문

아래 코드를 살펴보자.
#!syntax lua
print(1)
print(2)
print(3)
print(4)
print(5)
print(6)
print(7)
print(8)
print(9)
그저 1 2 3 4 5 6 7 8 9 를 출력하는 코드인데 무려 9줄이나 소요했다. 이러한 반복되는 코드를 효율적으로 줄이기 위해서 반복문이 존재한다. Luau에서 반복문은 크게 3가지로 나뉜다. 먼저 while 반복문을 알아보자. while 반복문은 'while 조건 do 실행할 코드 end' 형태로 이루어져있다. 메커니즘은 꽤나 간단하다. 그저 조건이 false 가 될 때까지 실행할 코드를 반복한다. 아래 예제 코드는 위 9줄의 코드를 while 반복문으로 간편하게 줄인것이다.
#!syntax lua
local num = 1
while num < 9 do
    print(num)
    num += 1
end
while 반복문은 조건이 false 가 될 때까지 무한히 반복하기 때문에 실행되는 코드가 중간에 정지 없이 과도하게 오랫동안 반복해서 실행된다면 성능에 치명적인 손상을 입힐수 있다. 그러므로 while 반복문을 사용할 때는 항상 실행되는 코드가 1초 또는 그 이상동안 반복될 수 있는지 체크해야 한다. 만약 그렇다면 task.wait(n초) 를 넣어 반복되는 코드마다 조금씩 간격을 놓자. task.wait(n초) 를 조건에 넣을 수도 있는데, 이는 false 가 되는 조건을 아예 없애는 것이기 때문에 실행될 코드가 무한하게 반복된다.

이제 repeat 반복문을 알아보자. repeat 반복문은 while 반복문과 상당히 비슷한데, 'repeat 실행할 코드 until 조건' 으로 이루어져 있다. repeat 반복문이 while 반복문과 다른점은 조건이 true 가 될 때까지 반복된다는 것이다. 이번엔 repeat 반복문으로 위 9줄의 코드를 간편하게 줄여보자.
#!syntax lua
local num = 1
repeat
    print(num)
    num += 1
until num > 9
repeat 또한 while 과 같이 1초 또는 그 이상동안 반복될시 중간정지 없이 쓰인다면 성능에 치명적인 손상을 입힐수 있으니 task.wait() 을 넣는 걸 추천한다. 이러한 repeat 은 일반적으로 while 과 전혀 다르게 쓰인다. while 반복문이 주로 코드를 무한하게 반복하려고 쓰인다면, repeat 반복문은 주로 조건이 존재할 때까지 기다리는 용도로 쓰인다.

마지막으로 for 반복문을 알아보자. for 반복문은 'for 변수 = 시작수, 끝수, 증가수 do 실행할 코드 end' 로 이루어져있다. for 반복문이 위의 두 반복문과 다른점은 for 스코프 내에서 변수를 선언하고 실행할 코드에서 직접 사용할 수 있다는 것이다.[10] 그리고 실행할 코드가 끝날시 증가수를 변수에 더하고 다시 코드를 실행한다. 만약 변수가 끝수에 도달하면 반복문이 종료된다. 이번엔 for 반복문을 이용하여 위 9줄의 코드를 간편하게 줄여보자.[11]
#!syntax lua
for num = 1, 9, 1 do
    print(num)
end
for 반복문도 마찬가지로 과도하게 실행될것으로 예상된다면 실행될 코드내에 task.wait(n초)를 넣는 것이 현명하다. for 반복문은 다른 형태로도 사용이 가능한데, 이는 차후에 설명할 배열과 관련있는 부분이므로 현재로선 생략한다.

2.5. 함수

함수란 특정 작업을 수행하는 코드의 집합체이다. 함수를 사용하면 코드의 재사용성, 가독성 및 유지보수성을 높일 수 있다. 또한 함수를 이벤트에 연결해 콜백으로 지정할 수도 있다. 다음은 매우 기초적인 함수를 나타낸 코드이다.
#!syntax lua
function a()
    print("a")
end
이렇듯 함수의 구조는 'function 이름() 실행할 코드 end' 로 이루어진다. 함수는 매개변수라는 특정한 변수를 받을 수 있다. 매개변수란 함수가 호출될 때 전달되는 값으로 매개변수를 통해 함수의 실행 결과에 변화를 줄 수 있다. 그렇다면 함수의 호출은 어떤 식으로 행해질까? 함수의 호출은 '함수의 이름(매개변수들[12])' 로 가능하다. 다음 예시 코드를 보며 이해해보자.
#!syntax lua
function printName(name) -- 여기서 name 은 출력할 이름을 결정짓는 매개변수이다.
    print(`Hello {name}!`)
end

printName("Roblox Studio") -- Roblox Studio 라는 매개변수와 함께 함수를 호출한다.
또한 함수는 값을 리턴할 수 있다. 여기서 리턴이란 값을 반환한다는 것이다. 지금까지의 함수 a와 printName 은 리턴값이 nil 이었다. 만약 함수가 값을 반환하게 된다면(값을 리턴하게 된다면) 함수의 호출 부분에서 함수가 반환한 값을 받을 수가 있다. 받는 방법은 간단하다. 변수같은 데이터를 저장할 수 있는 공간을 두고 그 안에 함수의 리턴값이 들어오게 하는 것이다. 또는 다른 함수 안에 함수 호출 부분을 집어넣어서 다른 함수의 매개변수로 바로 넘겨버릴 수도 있다. 다음 예제 코드를 통해 더 자세히 알아보자.
#!syntax lua
function returnGreetingText(name)
    return `Hello {name}!` -- string(문자열)을 반환한다.
end

local robloxGreetingText = returnGreetingText("Roblox") -- 변수안에 함수의 리턴값을 저장한다.
print(robloxGreetingText) -- 리턴값이 담긴 변수를 출력한다.

print(returnGreetingText("Roblox")) -- 함수의 리턴값을 바로 print 함수의 매개변수로 넘긴다.
Luau 프로그래밍을 처음 접해보는 사람이라면 후자가 더 짧고 편리하다고 느낄수 있지만 변수의 재사용성과 코드의 가독성을 고려한다면 전자를 선택하는 것이 현명한 판단이라고 볼 수 있다.

글 초반에 함수를 이벤트에 연결해 콜백으로 만드는 것이 가능하다고 언급하였는데, 이 또한 원리는 매우 간단하다. 함수를 만들거나 무명함수[13]를 사용해 이벤트의 연결 메서드 매개변수로 넘겨주는 것이다. 그리하여 이벤트는 넘겨준 함수를 이벤트가 트리거될 때마다 발생하는 콜백으로 이용하는 것이다. 함수와 이벤트를 많이 접해보지 않은 사람에겐 미숙할 수 있지만, 현재로선 그저 함수가 이벤트에 사용된다 라는 것만 알아두어도 된다.

지금까지의 예제 코드들은 모두 local 을 붙이지 않고 함수를 선언해왔지만 사실 이런식으로 함수를 선언하는 것은 옳지 않다.[14][15] local을 붙인 함수가 붙이지 않은 함수와 성능에 차이가 나기 때문이다.

2.6. 테이블

변수가 한 개의 데이터만을 담는 공간이라면 테이블은 여러개의 데이터들을 담는 공간이다. 테이블은 {}로 만들수 있으며 그 안에 nil 이 아닌 여러개의 자료형들을 담을 수 있다. 테이블은 두가지 종류로 나뉘는데, 바로 배열(Array) 과 딕셔너리(Dictionary) 이다. 먼저 배열에 대하여 알아보자.

배열은 순서가 정해진 데이터들의 리스트이다. 이는 플레이어 목록같이 데이터들의 집합을 저장하기에 용이하다. 배열을 구축하려면 중괄호({}) 안에 차례대로 원하는 데이터 값들을 넣으면 된다. 다음은 기본적인 배열의 형태이다.
#!syntax lua
local array = { "Hello World!", 123, false, workspace.Camera }
배열에서 원하는 데이터 값을 읽는 방법은 배열에 대괄호([]) 를 치고 데이터가 들어간 순서(index) 를 넣으면 된다. 이때 데이터의 순서는 1부터 시작해서 2, 3, 4... 로 증가한다.[16] 다음은 전에 만든 배열의 값들을 읽는 코드이다.
#!syntax lua
local string = array[1] -- Hello World!
local number = array[2] -- 123
local boolean = array[3] -- false
local instance = array[4] -- workspace.Camera
값을 읽는법을 배웠으니 이제는 값을 쓰는법을 배울 차례다. 배열에서 값을 쓰는법은 배열에 대괄호를 치고 데이터가 들어갈 순서를 넣고 =(대입 연산자) 을 통해 새로운 값을 넣거나 기존 값을 교체할 수 있다. 다음은 기존 array 에 데이터를 쓰는 코드이다.
#!syntax lua
array[2] = 12345 -- 2번째 순서의 값이 12345로 대체됨.
array[5] = true -- 5번째 순서의 값이 새로 생겨남.
이러한 배열은 내장 라이브러리 table 을 통해 더 다양하게 활용할 수 있다. 다음은 table 라이브러리를 사용한 예제 코드이다.
#!syntax lua
table.insert(array, "New Value") -- New Value 값을 (마지막 순서 + 1)에 집어넣는다.
-- => { "Hello World", 123, false, workspace.Camera, "New Value" }
table.remove(array, 1) -- 첫번째 순서의 값을 제거하고 뒤의 값들을 앞으로 집어넣는다.
-- => { 123, false, workspace.Camera, "New Value" }
또한 배열은 #(기타 연산자) 을 통해 몇개의 데이터들이 저장되어 있는지 확인할 수 있고 print 를 통해 출력할 수도 있다.

이제 딕셔너리에 관하여 알아보자. 딕셔너리란 배열의 확장형으로 키(key)-값(value) 형식으로 되어 있다. 이때 키와 값에는 여러 자료형들이 들어갈 수 있다. 딕셔너리를 구축하려면 중괄호({}) 안에 원하는 키를 넣고 =(대입 연산자) 를 값과 연결시켜야 한다. 다음 코드는 기본적인 딕셔너리의 형태이다.
#!syntax lua
local dictionary = {
    name = "apple", -- 여기서 키는 name, 값은 apple 이다.
    color = "red", -- 키가 단순 문자(영어 기준)가 아니라면 대괄호([]) 와 함께 넣어야 한다.
    enchanted = false -- 마지막 값에는 콤마(,) 를 넣지 않아도 된다.
}
이제 딕셔너리를 읽는법을 알아보자. 딕셔너리를 읽는법은 배열을 읽는법과 유사한데, 딕셔너리에 대괄호([]) 를 치고 키 값을 넣으면 된다. 다음은 전 코드의 딕셔너리의 값들을 읽는 코드이다.
#!syntax lua
local name = dictionary["name"] -- apple
local color = dictionary["color"] -- red
local isEnchanted = dictionary["enchanted"] -- false
읽는법을 배웠으니 이젠 쓰는법을 배워보자. 딕셔너리를 쓰는법도 배열을 쓰는법과 유사한데, 딕셔너리에 대괄호([]) 를 치고 키 값을 넣고 =(대입 연산자) 를 통해 원하는 값을 넣으면 된다. 원하는 값의 키가 기존에 있다면 기존에 있던 값이 교체되고 기존에 없다면 새로운 키와 값이 생성된다. 다음은 딕셔너리의 값들을 쓰는 코드이다.
#!syntax lua
dictionary["enchanted"] = true -- enchanted 키의 값을 true 로 변경.
dictionary["golden"] = true -- golden 이라는 새로운 키를 true 값과 함께 생성.
또한 딕셔너리에서 원하는 값을 제거하려면 쓰는법과 동일하게 대괄호와 제거하려는 값의 키 값, = 을 넣고 nil 을 대입해주면 된다. nil을 넣음으로서 값이 nil로 교체되고 가비지 컬렉터(gc) 가 수거해가는 원리.

2.7. 주석

-- 이것은 단일 주석이다.
}}}--[[
이것은 여러줄 주석이다.
]]
}}}--[=[
이것은 여러줄 주석의 변형이다.
]=]
}}}-- TODO: 이것은 TODO 주석이다.
}}}

3. 기본 스타일

본 스타일 가이드는 기본적으로 로블록스의 공식 Lua 스타일 가이드를 따르며 제대로된 스타일 체계가 잡혀있지 않은 스크립터들에게 도움을 주기 위함을 밝힌다.

3.1. 스크립트

3.2. 네이밍

{{{#!folding [ 네이밍 스타일 예제 ]
#!syntax lua
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local SUBSCRIPTION_ID = "EXP-0"

local function checkSubscriptionHistory(player: Player)
	local subscriptionHistory = {}

	local success, err = pcall(function()
		subscriptionHistory = MarketplaceService:GetUserSubscriptionPaymentHistoryAsync(player, SUBSCRIPTION_ID)
	end)

	if not success then
		warn(`Error while checking subscription history: {err}`)
		return
	end

	if next(subscriptionHistory) then
		print(`Player {player.Name} has subscribed to {SUBSCRIPTION_ID} before:`)

		for entryNum, paymentEntry in subscriptionHistory do
			local paymentStatus = tostring(paymentEntry.PaymentStatus)
			local cycleStartTime = paymentEntry.CycleStartTime:FormatLocalTime("LLL", "en-us")
			local cycleEndTime = paymentEntry.CycleEndTime:FormatLocalTime("LLL", "en-us")
			print(`{entryNum}: {paymentStatus} ({cycleStartTime} - {cycleEndTime})`)
		end
	else
		print(`Player {player.Name} has never subscribed to {SUBSCRIPTION_ID} before.`)
	end
end

for _, player in ipairs(Players:GetPlayers()) do
	checkSubscriptionHistory(player)
end

Players.PlayerAdded:Connect(checkSubscriptionHistory)
}}}
[ 네이밍 스타일 예제 2 ]
#!syntax lua
local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local teleporter = script.Parent
local showModal = true

local TELEPORT_POSITION = Vector3.new(1200, 200, 60)

local function teleportPlayer(player)
  player:RequestStreamAroundAsync(TELEPORT_POSITION)

  local character = player.Character
  if character and character.Parent then
    local currentPivot = character:GetPivot()
    character:PivotTo(currentPivot * CFrame.new(TELEPORT_POSITION))
  end
end

teleporter.Touched:Connect(function(otherPart)
  local player = Players:GetPlayerFromCharacter(otherPart.Parent)
  if not player then return end

  if not player:GetAttribute("CharacterPartsTouching") then
    player:SetAttribute("CharacterPartsTouching", 0)
  end
  player:SetAttribute("CharacterPartsTouching", player:GetAttribute("CharacterPartsTouching") + 1)

  if player.MembershipType == Enum.MembershipType.Premium then
    teleportPlayer(player)
  else
    if not showModal then return end
    showModal = false
    task.delay(5, function()
      showModal = true
    end)
    MarketplaceService:PromptPremiumPurchase(player)
  end
end)

teleporter.TouchEnded:Connect(function(otherPart)
  local player = Players:GetPlayerFromCharacter(otherPart.Parent)
  if player and player:GetAttribute("CharacterPartsTouching") then
    player:SetAttribute("CharacterPartsTouching", player:GetAttribute("CharacterPartsTouching") - 1)
  end
end)

Players.PlayerMembershipChanged:Connect(function(player)
  warn("User membership changed; new membership is " .. tostring(player.MembershipType))

  if player.MembershipType == Enum.MembershipType.Premium and player:GetAttribute("CharacterPartsTouching") > 0 then
    teleportPlayer(player)
  end
end)
[23]

3.3. 코드

3.4. 라이브러리

스크립팅을 할 때 대다수의 사람이 겪는 불편한 문제는 바로 비슷한 내용의 코드를 반복해서 짜야 한다는 것이다. 똑같은 내용이 아니라 비슷한 내용의 코드여서 복사 붙여넣기도 할 수 없고, 그렇다고 비슷한 내용의 코드를 또 짜기에는 너무 비효율적이라 난감한 상황에 놓인다. 이럴때 유용하게 쓸 수 있는 것이 라이브러리인데, 라이브러리는 반복되는 작업을 줄여줄뿐만 아니라, 우리가 설계하지 못하는 유용하고 고급적인 코드를 가져와 게임에 마치 아이템처럼 장착할 수 있다. 이러한 라이브러리는 스크립팅에서 매우 필수적인 요소인데, 많은 사람들이 잘못된 라이브러리를 선택하고 있어 이 문단을 만든다. 다음은 분야별 올바른 라이브러리의 목록이다.

3.5. 프레임워크

프레임워크란 스크립트의 전체적인 틀을 정해진 형식으로 짤 수 있게 하고 부가적인 기능들을 제공하는 하나의 뼈대이다. 게임에 프레임워크를 쓰는 것은 필수적이지는 않지만 큰 규모의 게임일수록 프레임워크의 필요성이 높아지는 것은 사실이다. 프레임워크는 타인이 만든것을 가져올수도 있고 자신이 만들수도 있다. 이는 상황에 따라서 갈리는데, 특정한 프레임워크[37]를 만들 때는 타인이 만든것을 사용하는 것보다 자신이 직접 만들어 쓰는 게 더 독특성 있고 효율적일 수도 있다. 하지만 스크립트의 틀을 잡기 위해 사용할 프레임워크는 실력있는 스크립터가 오랫동안 심혈을 기울여 만든 좋은 프레임워크를 쓰는 게 옳다. 다음은 대표적이고 현재로서 가장 뛰어난 프레임워크들을 나열한 것이다.

4. 스크립트 종류

4.1. 로컬 스크립트

파일:LocalScript.png
로컬 스크립트 [LocalScript]

[로컬]
서버측이 아닌 클라이언트, 개인 컴퓨터에서 구동 되는 스크립트다. 로컬 스크립트에서 변동된 값은 대부분 해당 클라이언트에게만 적용 된다. 그러나 예외가 있다. 서버에 복제되는 항목인 재생중인 애니메이션 트랙이나 자신이 소유중인 고정되지 않은 파트[40]의 값 변경 등에 대해선 그 변경이 다른 클라이언트에도 그대로 복제된다.

이러한 특성 때문에 서버의 연산이 불필요한 항목[41]은 로컬 스크립트에서 연산하게 하는 것이 현명하다.

로컬 스크립트는 개인 컴퓨터의 자원을 소모하기 때문에 복잡한 연산을 하면 컴퓨터에 렉이 걸려 FPS가 떨어진다. 그러므로 불필요한 연산은 로컬 스크립트에서 구동하게 하되 최대한 최적화를 해서 FPS가 떨어지지 않도록 하는 것도 중요하다. 사실 FPS가 떨어질 정도면 일부러 렉이 걸리도록 스크립트를 짜지 않는 이상 웬만하면 기기의 성능 이슈인 경우가 많다.

로컬 스크립트는 당연히도 클라이언트 측에서 작동되는 스크립트 이므로 클라이언트와 관련된 개체 밑에서만 작동을 한다.[42]

또한 로컬스크립트에서만 작동되는 서비스나 이벤트들이 있는데, 플레이어의 입력을 감지하는 UserInputService와 함수가 프레임 마다 실행될 수 있게 하는 RenderStepped 이벤트 등이 있다.

4.2. 서버 스크립트

파일:Roblox/서버스크립트.png
서버 스크립트 [Server Script]

[서버]
서버측에서 구동되는 스크립트이다. 서버측 스크립트는 클라이언트측 스크립트와 다르게 복제되는 항목[44]의 값 변경시 그 값이 모든 클라이언트에게도 복제되어 변경된다. 그러나 이러한 변경 및 연산은 서버의 자원을 소모하고, 너무 많은 자원을 소모하게 되면 궁극적으로 이 높아지고 렉이 걸리기 때문에 중요하지 않은 연산이나 값 변경 등은 클라이언트에게 맡겨야 한다.

4.3. 모듈 스크립트

파일:Roblox/모듈스크립트.png
모듈 스크립트 [Module Script]

반복적인 코드들을 정리하고 재사용할 수 있게 하는 특별한 류의 스크립트이다.
모듈 스크립트는 기본적으로 테이블 형태로 되어 있어 자동적으로 실행되지 않는다.
또한 서버와 로컬 공용으로 쓰이며 호환되지는 않는다.

다음은 모듈 스크립트의 기본 사용예제이다.

[ 모듈 스크립트 사용 예시 ]
#!syntax lua
--모듈 스크립트
local module = {}

module.a = 1

function module.b()
    print("b")
end

function module:c()
    print("c")
end

return module -- 모듈 스크립트는 값을 반환해야 함.

--서버 or 로컬 스크립트

local module = require(모듈_경로) -- 모듈 볼러오기

print(module.a) -- 1 출력
module.b() -- b 출력
module:c() -- c 출력

5. 자료형

로블록스에는 수많은 자료형들이 있지만 그 많은 자료형 중 몇몇만 자주 사용된다.

5.1. BrickColor

로블록스에서 기본으로 제공하는 색깔은 다음과 같다.
[ 펼치기 · 접기 ]
* White 흰색
  • Grey 회색
  • Light yellow : 연노랑
  • Brick yellow : 브릭 옐로우
  • Light green(Mint) : 연초록(민트)
  • Light reddish violet : 연붉은 보라색
  • Pastel bule : 파스텔 블루
  • Light orange brown : 밝은 브라운 오랜지
  • Nougat : 누가(견과류)
  • Bright red : 밝은 빨강
  • Med. reddish violet : 중간정도로 붉은 보라색
  • Bright bule : 밝은 파랑
  • Bright yellow : 밝은 노랑
  • Earth orange : 지구 오랜지
  • Black : 검정
  • Dark grey : 짙은 회색
  • Dark green : 짙은 초록
  • Medium green : 중간 초록
  • Lig. Yellowich orange : 밝은 노랏빛 오랜지
  • Brignt green : 밝은 초록
  • Dark orange : 짙은 주황
  • Light bluish violet : 밝은 청자색
이외 여러 색이 있다.

5.2. CFrame

5.2.1. 속성

5.2.2. 메서드

5.3. Vector3

5.4. UDim2

5.4.1. 메서드

5.4.2. 속성

5.5. TweenInfo

5.5.1. 속성

6. 라이브러리

6.1. bit32

6.2. buffer

6.3. coroutine

local a = 1
local b =1

local PlusA = coroutine.creat(function()
while true do
a += 1
end
end)

local PlusB = coroutine.creat(function()
while true do
b += 1
end
end)
coroutine.resume(PlusA)
coroutine.resume(PlusB)
}}} -> a와 b 둘다 1식 증가한다.
local a = 1
local b =1

local function PlusA()
while true do
a += 1
end
end

local function PlusB()
while true do
b += 1
end
end
PlusA()
PlusB()
}}} -> a만 1식 증가한다 -> PlusA()를 무한히 실행하기 때문에 이 다음 명령어인 PlusB()를 실행 못한다.
}}}

6.4. debug

6.5. math

6.5.1. 함수

6.5.2. 속성

6.6. os

os는 UTC에 맞춰 흘러가는 시간 시스템이다.

6.6.1. 함수

}}}

6.7. string

6.7.1. 함수[54]

#!syntax lua
local Message = "%s %s개를 %s원 주고 구매했다."
local Output = string.format(Message, "과자", 6, 80000)

print(Output) → 과자 6개를 80000원 주고 구매했다.

}}}

6.8. table

6.8.1. 함수

6.8.2. 속성

6.9. task

6.9.1. 함수

6.10. utf8

7. 글로벌

로블록스 내 어느 코드에서나 쓸 수 있는 함수 또는 속성들로, 로블록스 스튜디오의 코드는 Lua 기반이기에 Lua 내 대부분의 글로벌 또한 들어간다.

7.1. 함수

7.2. 속성

8. 서비스

8.1. Debris

스크립트를 직접적으로 정지하지 않고 스케줄된 개체 삭제를 수행할 수 있게 하는 서비스.task.wait(number)
Instance:Destroy()
}}} 그러나 이 코드에선 task.wait() 를 사용함으로서 스레드를 정지하게 한다. 즉 정지한 동안은 아무런 동작도 할 수 없다는 것이다. 추가적으로 코드를 실행해야 하는 경우에는 불가피하게 이 메커니즘은 사용할 수 없게 된다. 따라서 아래 코드처럼 새로운 스레드를 만들어 코드를 실행하게 하면 본 스레드에서는 정지를 피할 수 있다.
#!syntax lua
task.delay(number, function()
    Instance:Destroy()
end)
하지만 이 방법에도 치명적인 단점이 있다. 실행되고 있는 스레드의 부모 스크립트가 삭제될시 그 스레드도 삭제된다는 것이다. 간단한 예시를 들자면, 닿으면 3초뒤에 닿은 플레이어가 죽는 검 코드를 짜고 있다고 가정해보자, 만약 위 코드를 사용할시 모종의 이유로 스크립트가 삭제당하면[61] 위 스레드는 전부 무효화된다. 따라서 이때 Debris 서비스가 진가를 발휘할 수 있다.
#!syntax lua
Debris:AddItem(Instance, number)
위 코드 한줄이면 새 스레드를 생성하지도 않고, 개체 삭제를 스케줄할 수 있다. 추가로 이 메소드는 최대 수용 한도가 1000개 라는 것을 명심해두자.

8.2. MarketplaceService

8.3. RunService

8.4. TweenService

local tweenInfo = TweenInfo.new(3, Enum.EasingStyle.Linear, Enum.EasingDirection.In, 0, false, 0)
local part = workspace.Part
local goal = { Position = Vector3.new(0, 50, 0) }
local tween = TweenService:Create(part, tweenInfo, goal)

tween:Play()
}}}}}}* Tween:Play() : Tween을 재생한다.* Tween:Cancel() : Tween을 취소한다.* Tween:Pause() : Tween을 일시중지한다.* Tween.Completed :

8.5. BadgeService

9. 클래스 목록

[모든 클래스 펼치기 · 접기 ]
* Accessory : 플레이어의 장신구
  • AccessoryDescription
  • Accoutrement
  • Actor
  • AdGui
  • AdPortal
  • AdService
  • AdvancedDragger
  • AirController
  • AlignOrientation
  • AlignPosition
  • AnalyticsService
  • AngularVelocity
  • Animation : 에니메이션
  • AnimationClip
  • AnimationClipProvider
  • AnimationController
  • AnimationFromVideoCreatorService
  • AnimationRigData
  • AnimationTrack
  • Animator : 에니메이션을 재생시키는 개체
  • ArcHandles
  • AssetDeliveryProxy
  • AssetPatchSettings
  • AssetService
  • Atmosphere
  • Attachment
  • AudioAnalyzer
  • AudioChorus
  • AudioCompressor
  • AudioDeviceInput
  • AudioDeviceOutput
  • AudioDistortion
  • AudioEcho
  • AudioEmitter
  • AudioEqualizer
  • AudioFader
  • AudioFlanger
  • AudioListener
  • AudioPages
  • AudioPitchShifter
  • AudioPlayer
  • AudioReverb
  • AudioSearchParams
  • AvatarCreationService
  • AvatarEditorService
  • Backpack : 플레이어 인밴토리
  • BackpackItem
  • BadgeService
  • BallSocketConstraint
  • BasePart
  • BasePlayerGui
  • BaseRemoteEvent
  • BaseScript
  • BaseWrap
  • Beam
  • BevelMesh
  • BillboardGui
  • BinaryStringValue
  • BindableEvent
  • BindableFunction[최적화별로]
  • BlockMesh
  • BloomEffect
  • BlurEffect
  • BodyAngularVelocity
  • BodyColors : 플레이어의 몸 색깔
  • BodyForce : 개체를 workspace를 기준으로 움직이는 힘[구버전]
  • BodyGyro : 개체를 돌리는 돌림힘[구버전]
  • BodyMover : BodyForce, BodyGyro 등의 상위 개체[구버전]
  • BodyPartDescription
  • BodyPosition : 개체를 어디를 기준으로 힘을 가할지 정할 수 있는 힘
  • BodyThrust
  • BodyVelocity : 개체에 일정한 속도로 가하는 힘
  • Bone
  • BoolValue
  • BoxHandleAdornment
  • BrickColorValue
  • BrowserService
  • BubbleChatConfiguration
  • BubbleChatMessageProperties
  • BuoyancySensor
  • CacheableContentProvider
  • Camera
  • CanvasGroup
  • CaptureService
  • CatalogPages
  • CFrameValue
  • ChangeHistoryService
  • CharacterAppearance
  • CharacterMesh
  • Chat
  • ChatInputBarConfiguration
  • ChatWindowConfiguration
  • ChorusSoundEffect
  • ClickDetector
  • ClientReplicator
  • ClimbController
  • Clothing
  • Clouds
  • ClusterPacketCache
  • CollectionService
  • Color3Value
  • ColorCorrectionEffect
  • CommandService
  • CompressorSoundEffect
  • ConeHandleAdornment
  • Configuration
  • ConfigureServerService
  • Constraint
  • ContentProvider
  • ContextActionService
  • Controller
  • ControllerBase
  • ControllerManager
  • ControllerPartSensor
  • ControllerSensor
  • ControllerService
  • CookiesService
  • CoreGui
  • CoreScriptDebuggingManagerHelper
  • CornerWedgePart
  • CurveAnimation
  • CustomEvent
  • CustomEventReceiver
  • CylinderHandleAdornment
  • CylinderMesh
  • CylindricalConstraint
  • DataModel
  • DataModelMesh
  • DataModelSession
  • DataStore
  • DataStoreGetOptions
  • DataStoreIncrementOptions
  • DataStoreInfo
  • DataStoreKey
  • DataStoreKeyInfo
  • DataStoreKeyPages
  • DataStoreListingPages
  • DataStoreObjectVersionInfo
  • DataStoreOptions
  • DataStorePages
  • DataStoreService
  • DataStoreSetOptions
  • DataStoreVersionPages
  • Debris
  • DebugSettings
  • Decal
  • DepthOfFieldEffect
  • Dialog
  • DialogChoice
  • DistortionSoundEffect
  • DockWidgetPluginGui
  • DoubleConstrainedValue
  • DraftsService
  • DragDetector
  • Dragger
  • DraggerService
  • DynamicRotate
  • EchoSoundEffect
  • EditableImage
  • EditableMesh
  • EmotesPages
  • EqualizerSoundEffect
  • EulerRotationCurve
  • ExperienceInviteOptions
  • ExperienceNotificationService
  • Explosion : 폭발
  • FaceControls
  • FaceInstance
  • Feature
  • File
  • FileMesh
  • Fire : 불
  • Flag
  • FlagStand
  • FlagStandService
  • FlangeSoundEffect
  • FloatCurve
  • FloorWire
  • Folder : 폴더
  • ForceField
  • FormFactorPart
  • Frame
  • FriendPages
  • FriendService
  • FunctionalTest
  • GamepadService
  • GamePassService
  • GameSettings
  • GenericSettings
  • Geometry
  • GeometryService
  • GetTextBoundsParams
  • GlobalDataStore
  • GlobalSettings
  • Glue
  • GoogleAnalyticsConfiguration
  • GroundController
  • GroupService
  • GuiBase
  • GuiBase2d
  • GuiBase3d
  • GuiButton
  • GuidRegistryService
  • GuiLabel
  • GuiMain
  • GuiObject
  • GuiService
  • HandleAdornment
  • Handles
  • HandlesBase
  • HapticService
  • Hat
  • HeightmapImporterService
  • HiddenSurfaceRemovalAsset
  • Highlight
  • HingeConstraint
  • Hint
  • Hole
  • Hopper
  • HopperBin
  • HSRDataContentProvider
  • HttpRbxApiService
  • HttpService
  • Humanoid
  • HumanoidController
  • HumanoidDescription
  • IKControl
  • ILegacyStudioBridge
  • ImageButton
  • ImageHandleAdornment
  • ImageLabel
  • IncrementalPatchBuilder
  • InputObject
  • InsertService
  • Instance
  • InstanceAdornment
  • IntConstrainedValue
  • IntersectOperation
  • IntValue : 정수값
  • InventoryPages
  • JointInstance
  • JointsService
  • KeyboardService
  • Keyframe
  • KeyframeMarker
  • KeyframeSequence
  • KeyframeSequenceProvider
  • LanguageService
  • LayerCollector
  • Light
  • Lighting : 일반 빛
  • LinearVelocity
  • LineForce
  • LineHandleAdornment
  • LocalizationService
  • LocalizationTable
  • LocalScript
  • LoginService
  • LogService
  • LuaSettings
  • LuaSourceContainer
  • LuaWebService
  • ManualGlue
  • ManualSurfaceJointInstance
  • ManualWeld
  • MarkerCurve
  • MarketplaceService
  • MaterialService
  • MaterialVariant
  • MemoryStoreHashMap
  • MemoryStoreHashMapPages
  • MemoryStoreQueue
  • MemoryStoreService
  • MemoryStoreSortedMap
  • MemStorageConnection
  • MemStorageService
  • MeshContentProvider
  • MeshPart
  • Message
  • MessagingService
  • Model
  • ModuleScript
  • Motor
  • Motor6D
  • MotorFeature
  • Mouse
  • MouseService
  • MultipleDocumentInterfaceInstance
  • NegateOperation
  • NetworkClient
  • NetworkMarker
  • NetworkPeer
  • NetworkReplicator
  • NetworkServer
  • NetworkSettings
  • NoCollisionConstraint
  • NotificationService
  • NumberPose
  • NumberValue : 실수값
  • ObjectValue
  • OpenCloudApiV1
  • OpenCloudService
  • OrderedDataStore
  • OutfitPages
  • PackageLink
  • PackageService
  • Pages
  • Pants
  • Part
  • PartAdornment
  • ParticleEmitter
  • PartOperation
  • PartOperationAsset
  • PatchBundlerFileWatch
  • PatchMapping
  • Path
  • PathfindingLink
  • PathfindingModifier
  • PathfindingService
  • PermissionsService
  • PhysicsService
  • PhysicsSettings
  • PitchShiftSoundEffect
  • PlacesService
  • Plane
  • PlaneConstraint
  • Platform
  • Player
  • PlayerGui
  • PlayerMouse
  • Players
  • PlayerScripts
  • PlayerViewService
  • Plugin
  • PluginAction
  • PluginCapabilities
  • PluginDebugService
  • PluginDragEvent
  • PluginGui
  • PluginGuiService
  • PluginManagementService
  • PluginManager
  • PluginManagerInterface
  • PluginMenu
  • PluginMouse
  • PluginToolbar
  • PluginToolbarButton
  • PointLight
  • PointsService
  • PolicyService
  • Pose
  • PoseBase
  • PostEffect
  • PrismaticConstraint
  • ProcessInstancePhysicsService
  • ProximityPrompt
  • ProximityPromptService
  • PublishService
  • PVAdornment
  • PVInstance
  • QWidgetPluginGui
  • RayValue
  • ReflectionMetadata
  • ReflectionMetadataCallbacks
  • ReflectionMetadataClass
  • ReflectionMetadataClasses
  • ReflectionMetadataEnum
  • ReflectionMetadataEnumItem
  • ReflectionMetadataEnums
  • ReflectionMetadataEvents
  • ReflectionMetadataFunctions
  • ReflectionMetadataItem
  • ReflectionMetadataMember
  • ReflectionMetadataProperties
  • ReflectionMetadataYieldFunctions
  • RemoteDebuggerServer
  • RemoteEvent : 리모트 이벤트
  • RemoteFunction[최적화별로][보안취약][68] : 리모트 함수
  • RenderingTest
  • RenderSettings
  • ReplicatedFirst
  • ReplicatedStorage
  • ReverbSoundEffect
  • RigidConstraint
  • RocketPropulsion
  • RodConstraint
  • RopeConstraint
  • Rotate
  • RotateP
  • RotateV
  • RotationCurve
  • RunningAverageItemDouble
  • RunningAverageItemInt
  • RunningAverageTimeIntervalItem
  • RunService
  • ScreenGui
  • ScreenshotHud
  • Script
  • ScriptBuilder
  • ScriptContext
  • ScriptDocument
  • ScriptEditorService
  • ScriptService
  • ScrollingFrame
  • Seat : 의자 파트
  • Selection
  • SelectionBox
  • SelectionHighlightManager
  • SelectionLasso
  • SelectionPartLasso
  • SelectionPointLasso
  • SelectionSphere
  • SensorBase
  • ServerReplicator
  • ServerScriptService
  • ServerStorage
  • ServiceProvider
  • ServiceVisibilityService
  • SharedTableRegistry
  • Shirt
  • ShirtGraphic
  • ShorelineUpgraderService
  • SkateboardController
  • SkateboardPlatform
  • Skin
  • Sky : 하늘
  • SlidingBallConstraint
  • Smoke : 연기
  • SmoothVoxelsUpgraderService
  • Snap
  • SocialService
  • SolidModelContentProvider
  • Sound : 소리
  • SoundEffect
  • SoundGroup
  • SoundService
  • Sparkles
  • SpawnerService
  • SpawnLocation
  • SpecialMesh
  • SphereHandleAdornment
  • SpotLight : 원뿔형 빛
  • SpringConstraint
  • StandalonePluginScripts
  • StandardPages
  • StarterCharacterScripts
  • StarterGear
  • StarterGui
  • StarterPack
  • StarterPlayer
  • StarterPlayerScripts
  • StartupMessageService
  • Stats
  • StatsItem
  • Status
  • StopWatchReporter
  • StringValue : 문자열
  • Studio
  • StudioService
  • StudioTheme
  • StyleBase
  • StyleDerive
  • StyleLink
  • StyleRule
  • StyleSheet
  • StylingService
  • SunRaysEffect
  • SurfaceAppearance
  • SurfaceGui
  • SurfaceGuiBase
  • SurfaceLight : 사각뿔형 빛
  • SurfaceSelection
  • SwimController
  • SyncScriptBuilder
  • TaskScheduler
  • Team
  • TeamCreateData
  • TeamCreateService
  • Teams
  • TeleportAsyncResult
  • TeleportOptions
  • TeleportService
  • Terrain
  • TerrainDetail
  • TerrainRegion
  • TestService
  • TextBox
  • TextBoxService
  • TextButton
  • TextChannel
  • TextChatCommand
  • TextChatConfigurations
  • TextChatMessage
  • TextChatMessageProperties
  • TextChatService
  • TextFilterResult
  • TextFilterTranslatedResult
  • TextLabel
  • TextService
  • TextSource
  • Texture
  • TimerService
  • Tool : 툴
  • Torque : 토크
  • TorsionSpringConstraint
  • TotalCountTimeIntervalItem
  • TouchInputService
  • TouchTransmitter
  • Trail
  • Translator
  • TremoloSoundEffect
  • TriangleMeshPart
  • TrussPart
  • Tween
  • TweenBase
  • TweenService
  • UGCValidationService
  • UIAspectRatioConstraint
  • UIBase
  • UIComponent
  • UIConstraint
  • UICorner
  • UIFlexItem
  • UIGradient
  • UIGridLayout
  • UIGridStyleLayout
  • UILayout
  • UIListLayout
  • UIPadding
  • UIPageLayout
  • UIScale
  • UISizeConstraint
  • UIStroke
  • UITableLayout
  • UITextSizeConstraint
  • UnionOperation
  • UniversalConstraint
  • UnreliableRemoteEvent
  • UserGameSettings
  • UserInputService
  • UserNotification
  • UserNotificationPayload
  • UserNotificationPayloadAnalyticsData
  • UserNotificationPayloadJoinExperience
  • UserNotificationPayloadParameterValue
  • UserService
  • UserSettings
  • ValueBase
  • Vector3Curve
  • Vector3Value
  • VectorForce
  • VehicleController
  • VehicleSeat
  • VelocityMotor
  • VideoCaptureService
  • VideoFrame
  • VideoService
  • ViewportFrame
  • VirtualInputManager
  • VirtualUser
  • VisibilityCheckDispatcher
  • VisibilityService
  • Visit
  • VoiceChatService
  • VRService
  • VRStatusService
  • WedgePart
  • Weld : 용접(구버전)
  • WeldConstraint
  • Wire
  • WireframeHandleAdornment
  • Workspace
  • WorldModel
  • WorldRoot
  • WrapLayer
  • WrapTarget

스튜디오에서 생성할 수 있는 거의 모든 클래스가 Instance의 속성을 가진다.

9.1. BasePart

9.1.1. 속성

자주 쓰이는 속성은 다음과 같다.

9.1.2. 이벤트

#!syntax lua
local Cooldown = false --쿨다운 변수 만드는 부분
script.Parent.Touched:Connect(function(hit)
    local Humanoid = hit.Parent:FindFirstChild("Humanoid") -- 변수 만드는 부분
    if Humanoid and not Cooldown then --휴머노이드 개체가 있는지 확인하는 부분 + 쿨다운이 아닌지 확인하는 부분
        Cooldown = true
        Humanoid.Health = 0 --닿은 플레이어의 체력
        task.wait(1) --1초 기다림
        Cooldown = false
    end
end)

}}}local Cooldown = false --쿨다운 변수 만드는 부분
script.Parent.TouchEnded:Connect(function(hit)
local Humanoid = hit.Parent:FindFirstChild("Humanoid") --변수 만드는 부분
if Humanoid and not Cooldown then --휴머노이드 개체가 있는지 확인하는 부분 + 쿨다운이 아닌지 확인하는 부분
Cooldown = true
Humanoid.Health = 0 --닿은 플레이어의 체력
task.wait(1) --1초 기다림
Cooldown = false
end
end)
}}}
}}}

9.1.3. 메서드

PVInstance의 메서드를 사용함

9.1.4. 기타

파트의 미끄러움 정도는 다음과 같이 계산된다.

파트1과 파트2가 서로 닿는 경우에 파트1의 마찰계수를 [math(a)], 파트2의 마찰계수를 [math(b)]라 두고, 파트1의 마찰무게(friction weight)를 [math(a')], 파트2의 마찰무게를 [math(b')]라고 둔다면 총 마찰계수는 다음과 같다.
[math(마찰계수 = \dfrac{aa'+bb'}{a'+b'})]

9.2. Instance

모든 개체들은 Instance 개체의 성질을 가진다.

9.2.1. 속성

자주 쓰이는 속성은 다음과 같다.

9.2.2. 이벤트

9.2.3. 메서드

9.3. Players

9.4. RemoteEvent

9.4.1. 속성

Instance의 속성을 가진다.

9.4.2. 이벤트

9.4.3. 메서드

9.4.4. 기타

9.5. ProximityPrompt

9.5.1. 속성

9.5.2. 메서드

9.5.3. 이벤트

10.

10.1. Luau 관련

10.2. 최적화 관련

local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
player.CharacterRemoving:Connect(function(character)
task.defer(character.Destroy, character)
end)
end)

Players.PlayerRemoving:Connect(function(player)
task.defer(player.Destroy, player)
end)
}}}
local Players = game:GetService("Players")
local playerInfos:{[Player] : any} = {}

Players.PlayerAdded:Connect(function(player)
playerInfos[player] = {} -- 아무 값들
end)
}}}
그런데 이 코드엔 치명적인 결함이 있다. 플레이어가 들어올때 테이블에 새 인덱스가 추가되어 메모리를 소비하는데 이 인덱스가 가진 값이 플레이어가 나갔는데도 사라지지 않고 남아있어 계속해서 메모리를 소비한다. 따라서 다음과 같은 코드를 추가해 플레이어가 나갈때 플레이어 인덱스가 가진 값을 nil로 설정해야 해당 인덱스가 쓰레기 수집된다.
{{{#!syntax lua
Players.PlayerRemoved:Connect(function(player)
playerInfos[player] = nil
end)
}}}

10.3. 보안 관련

10.4. 개발 관련


[1] 로블록스에서 자체 개발한 언어이다.[2] local 없이도 변수 생성이 가능하기는 하다, 그러나 추천하지는 않는다.[3] 이와 비슷한 예로는 _G의 사용이 있다.[4] 정확하게는 단항 부정 연산자[5] 비교 연산자라고 불리기도 한다.[6] 문자와 문자를 연결해준다.[7] 테이블에 들어 있는 데이터의 수를 의미한다.[8] 사실상 아래 예 말고도 조건문은 무궁무진하게 활용된다.[9] 즉 조건을 넣을 수 없다.[10] 물론 변수는 read-only, 읽기전용이다.[11] 3가지의 반복문 중에서 위 코드를 줄이기에는 for 반복문이 가장 용이하다.[12] 매개변수가 존재하지 않아도 된다.[13] 이름없는 함수라고도 알려져 있다.[14] 무명함수는 제외.[15] 예제 코드에 local을 붙이지 않은 건 함수에 처음 접해보는 초심자들의 혼동을 예방하기 위한 약간의 배려라고 볼 수 있다.[16] 대부분의 타 언어와 달리 순서가 1부터 시작하니 주의하자.[17] 그 예로 킬파트를 만드려고 스크립트를 파트 안에 놓는 경우가 있다. 점프맵류 게임을 만들 때 대다수의 초심자 스크립터들이 하는 실수인데, 현명한 방법으로는 ServerScriptService 에 하나의 스크립트를 놓고 여러개의 킬파트를 조작하게 할 수 있다.[18] 대표적으로 ecs가 있다.[19] 단, 딱히 아무런 의미도 가지지 않는 변수는 한 문자로 짓는 것이 가능하다.[20] 그 예로 초심자들이 player 를 plr 로 줄여쓰는 것이 있다. 간혹가다 줄여 쓰는 것이 편리하고 간단해 보여 더 좋다고 주장하는 사람들이 있지만, 아마도 이들은 대부분 프로그래밍을 처음 배워보거나 접한지 얼마 지나지 않은 사람들일것이다. 이미 수많은 공식 문서에서 네이밍할 때 약자를 쓰는 것이 좋지 않다고 언급해왔다.[21] 예로 local tweenInfo = TweenInfo.new() 가 있다.[22] 예로 for _, v do end 가 있다.[23] 출처 : 예제 1, 예제 2[24] 실제로 천상계 스크립터들은 그러한 혜택을 극대화해 사용하여 스크립트들의 대부분이 다른 사람이 만든 라이브러리나 프레임워크가 되기도 한다.[25] 데이터 로스도 종종 일어난다.[26] 유튜브 동영상이나 공식 문서, 데브포럼에 있는 글 등[27] 물론 숙련자 기준이다. 초심자나 중급자에겐 프로미스가 익숙하지 않을 수도 있다.[28] 또한 프로미스 라이브러리를 기반으로 한다.[29] 그러나 어느 정도 체득하면 꽤나 편리하다.[30] 성능은 준수하다.[31] 같은 개발자가 만든 브릿지넷이나 브릿지넷2는 모두 deprecated 되었으니 사용하지 않길 바란다.[32] React Roblox 등[33] 리액트 루아 공식 문서로는 사용 방법을 터득하기도 쉽지 않고 잘못된 사용방법을 쓸 확률이 높다.[34] 그 예로 리액트 루아의 ts 버전을 토대로 개발한 slither이 있다.[35] ui 전용 상태 관리 라이브러리는 로액트-로덕스이다.[36] 그래도 로덕스를 고집하는 사람들도 있다.[37] 예: 총 프레임워크, 자동차 프레임워크 등[38] Knit 내에서는 유틸(Util) 이라 불린다.[로컬] LocalScript에서만 읽기 및 호출이 가능하다.[40] 좋은 예시로 플레이어의 캐릭터. 캐릭터의 파트들은 로블록스 엔진에 의해 자동으로 해당 플레이어가 소유하게 된다. 이러한 캐릭터의 파트들의 물리 연산은 전적으로 클라이언트가 계산하기에 클라이언트 측에서 캐릭터의 파트를 고정할 시 고정된게 그대로 다른 클라이언트에도 복제된다.[41] 파티클, 기후 등[42] 예로 gui, player, character 안에서 작동이 된다.[서버] 서버측 스크립트에서만 읽기 및 호출이 가능하다.[44] 예시로 Workspace나 ReplicatedStorage 안에 들어 있는 모든 항목들.[45] 서비스 및 BasePart와 같은 추상 클래스를 제외한 모든 클래스의 상위 클래스인 Instance 클래스의 생성자를 보유하고 있는 자료형이다.[46] 타 언어의 null 과 같다.[47] gui 상에서 많이 사용된다.[48] CFrame과 함께 위치를 나타내는 단위이다.[49] 예시) script.Parent.CFrame = script.Parent:Lerp(CFrame1, 0.7) --> script.Parent.CFrame과 CFrame1의 Position 간격이 1(100%)이라하면 Position이 0.7(70%) 되는 지점에 온다.[50] 반복 횟수를 0으로 설정하면 1번 움직이고, 음수로 설정하면 무한 반복한다.[51] 다차원 테이블(테이블 안에 있는 테이블)도 가능하며 key-value 형의 딕셔너리(for i, v in 테이블 do)도 가능하다.[주의할점] 루아 스크립트에서는 테이블의 번호를 1번 부터 센다.[53] 테이블의 형식은 {year=년도, month=월, day=일, hour=시, min=분, sec=초}다.[54] 한글은 한글자가 깨진글자 3개로 이루어져 있어 한글로 하면 버그가 생길수도 있다. 예) string.len("안녕하세요") -> ��������������� -> 15출력[55] 찾는글자가 두글자라면 시작지점을 반환해준다. 예) string.find("11223344", "22") -> 3출력[56] 예) string.sub("12345678", 4, 8) -> " "45678"[57] 시작번호나 끝번호에 음수를 넣으면 글자 끝에서 뒤로간다. -1이면 마지막 글자, -2면 마지막 2번째 글자 이런식이다.[58] 디버깅할 때 말고는 별로 쓸모가 없다.[최적화별로] [60] 괄호 안에 아무것도 안넣으면 기본값으로 0.03초를 기다린다.[61] 캐릭터가 죽거나, 스크립트를 자식으로 두고 있던 부모가 삭제되거나 (예: 검 모델)[최적화별로] [구버전] 현재에는 다른 것으로 대체되었다.[구버전] [구버전] [최적화별로] [보안취약] [68] 이는 서버 -> 클라이언트 구조에만 해당됨, 불가피할시 타임아웃을 걸어두는 걸 추천함[Bool] true와 false 값을 가진다.[Bool] [Bool] [Bool] [Color3] RGB 색상코드[Number] 숫자를 값으로 가진다.[Bool] [Vector3] Vector3(좌표)를 값으로 가진다.[Vector3] [Vector3] [Number] [80] Touched 이벤트는 뭔가가 닿여을 때 한 번만 작동하고 만약 어떤 파트가 Touched 를 감지하는 파트 안으로 들어오면 Touched 를 감지 하지 못한다. 예를 들어 Touched 가 감지될 때마다 플레이어의 채력을 5씩 깎는 파트가 있다고 하면, 플레이어가 처음 파트에 닿였을 때는 채력이 깎이지만 데미지 파트 안에서는 아무리 움직여도 데미지를 받지 않는다. 만약 데미지 파트 안에서도 데미지를 받게 만들고 싶다면 무한 반복문을 통해 플레이어의 위치가 파트 안인지 감지해주는 스크립트를 만들어준다.[String] 문자열을 값으로 가진다.[String] [String] [Number] [String] [86] 한글로 치면 만약 ㅇㅇ이 6 이면 ㅇㅇ을 해라. 아니라면 ㅇㅇ을 해라. 아니라면 ㅇㅇ을 해라. 아니라면 ㅇㅇ을 해라. 아니라면 ㅇㅇ을 해라....[유튜브] 유튜브에 적용법이 나온다.[88] --을 사용해 주석을 치고 원하는 내용을 적고 Alt+\를 누르면 된다. 스크립트를 쓰다가 기다리면 자동으로 추천해주기도 한다. Tab으로 추천된 코드를 완성시킬 수 있다.[89] 자세한 건 라이브러리 문단의 네트워킹 부분을 참고.[90] 예시: ServerStorage 내부에 있는 개체 (서버 스크립트 측)[91] 참고로 pcall을 통해서 있을수도 있고 없을수도 있는 개체를 찾는 방법은 WaitForChild보다 더 느리다.[92] 옐롯은 주로 프리모델의 사용법을 알려주기 때문에 스크립트를 배우고 싶다면 노페어의 영상을 보는 것을 추천한다.

분류