Lua in Defold - kuimoani/defold GitHub Wiki

Lua in Defold

๋””ํด๋“œ ์—”์ง„์€ ์Šคํฌ๋ฆฝํŒ…์„ ์œ„ํ•œ Lua ์–ธ์–ด๊ฐ€ ๋‚ด์žฅ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. Lua๋Š” ๊ฐ•๋ ฅํ•˜๊ณ , ๋น ๋ฅด๋ฉฐ ๊ฐ€๋ณ๊ณ  ์‰ฝ๊ฒŒ ์ž„๋ฒ ๋“œ ๋˜๋Š” ๋™์ ์–ธ์–ด์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋น„๋””์˜ค ๊ฒŒ์ž„ ์Šคํฌ๋ฆฝํŒ… ์–ธ์–ด๋กœ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Lua ํ”„๋กœ๊ทธ๋žจ์€ ๊ฐ„๋‹จํ•œ ์ ˆ์ฐจ์ ์ธ ๋ฐฉ์‹์œผ๋กœ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ์–ธ์–ด๋Š” ๋™์ ์œผ๋กœ ํƒ€์ดํ•‘๋˜๋ฉฐ ๋ฐ”์ดํŠธ์ฝ”๋“œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ์— ์˜ํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ฆ๊ฐ€ํ•˜๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ์ž๋™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ๊ธฐ๋Šฅ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋งค๋‰ด์–ผ์€ Defold์—์„œ Lua๋กœ ์ž‘์—…ํ•  ๋•Œ ๋ฌด์—‡์ด ํ•„์š”ํ•œ์ง€ ๊ณ ๋ คํ•˜๋ฉฐ Lua ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ธฐ๋ณธ์„ ๋น ๋ฅด๊ฒŒ ์†Œ๊ฐœํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋‹น์‹ ์ด ํŒŒ์ด์ฌ, ํŽ„, ๋ฃจ๋น„, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ™์€ ๋‹ค๋ฅธ ๋™์  ์–ธ์–ด์— ๊ฒฝํ—˜์ด ์žˆ๋‹ค๋ฉด, ๋‹น์‹ ์€ ์ข€ ๋” ๋นจ๋ฆฌ ์ดํ•ดํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์ด ๋งŒ์•ฝ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์™„์ „ํžˆ ์ฒ˜์Œ ์‹œ์ž‘ํ•œ๋‹ค๋ฉด ์ดˆ์‹ฌ์ž๋ฅผ ์œ„ํ•œ Lua ์ฑ…์ด ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒ์ง€๋Š” ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Lua versions

์šฐ๋ฆฌ๋Š” Defold๊ฐ€ ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ๊ฐ™์€ ๋™์ž‘์„ ํ•˜๋Š”๋ฐ ์ด›์ ์„ ๋งž์ถ”๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ˜„์žฌ Lua ๋ฒ„์ „๊ฐ„์— ์•ฝ๊ฐ„์˜ ๋ถˆ์ผ์น˜๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. HTML5์™€ iOS 64 ๋น„ํŠธ ํ”Œ๋žซํผ์˜ ๊ฒฝ์šฐ ์šฐ๋ฆฌ๋Š” Lua 5.1์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ ๋‹ค๋ฅธ ํ”Œ๋žซํผ์—์„œ๋Š” LuaJIT์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. LuaJIT์€ 5.1 ๊ธฐ๋ฐ˜์ด๊ธด ํ•˜์ง€๋งŒ ๋ช‡๊ฐ€์ง€ ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ์ด ๋” ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

**๊ฒŒ์ž„์ด ๋ชจ๋“  ํ”Œ๋žซํผ์—์„œ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ํ•˜๋ ค๋ฉด Lua 5.1์— ๋งž์ถฐ ๊ฐœ๋ฐœํ•˜๋Š”๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค. **

Lua books and resources

  • Programming in Lua (first edition) Later editions are available in print.
  • Lua 5.1 reference manual
  • Beginning Lua Programming (Wrox, 2007)
  • Game Development with Lua (Charles River Media, 2005)

Syntax

ํ”„๋กœ๊ทธ๋žจ ๋ฌธ๋ฒ•์€ ๊ฐ„๋‹จํ•˜๊ณ  ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ช…๋ น๋ฌธ์€ ๊ฐ ๋ผ์ธ๋งˆ๋‹ค ํ•˜๋‚˜์”ฉ ์“ฐ์—ฌ์ง€๋ฉฐ ๋ช…๋ น๋ฌธ์˜ ๋์„ ํ‘œ์‹œํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์„ ํƒ์ ์œผ๋กœ ์„ธ๋ฏธ์ฝœ๋ก ;์œผ๋กœ ๋ช…๋ น๋ฌธ์„ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๋ธ”๋ก์€ ํ‚ค์›Œ๋“œ๋กœ ๊ตฌ๋ถ„๋˜๋ฉฐ end ํ‚ค์›Œ๋“œ๋กœ ๋์„ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์„์€ ๋ธ”๋ก์ด๋‚˜ ๊ฐ ์ค„์˜ ๋์— ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

--[[
์ด๋ ‡๊ฒŒ ์—ฌ๋Ÿฌ์ค„๋กœ ์ฃผ์„์„ 
์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
--]]

a = 10
b = 20 ; c = 30 -- ํ•œ ์ค„์—์„œ ๋ช…๋ น์–ด ๋‘ ๊ฐœ ์“ฐ๊ธฐ

if my_variable == 3 then
	call_some_function(true) -- ํ•œ ์ค„ ์ฃผ์„ ์“ฐ๊ธฐ
else
	call_another_function(false)
end

Variables and data types

Lua๋Š” ๋™์ ์œผ๋กœ ์ž๋ฃŒํ˜•์ด ์ •ํ•ด์ง€๋Š”๋ฐ ์‹ค์ œ ๊ฐ’์€ ์ž๋ฃŒํ˜•์ด ์žˆ์ง€๋งŒ ๋ณ€์ˆ˜๋Š” ์—†๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰ ๋‹ค๋ฅธ ์ •์  ํƒ€์ž…์–ธ์–ด์™€ ๋‹ฌ๋ฆฌ ์›ํ•˜๋Š”๋Œ€๋กœ ๋ณ€์ˆ˜์— ์•„๋ฌด ๊ฐ’์ด๋‚˜ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lua์—๋Š” 8๊ฐ€์ง€ ๊ธฐ๋ณธ ์ž๋ฃŒํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

nil

์ด ์ž๋ฃŒํ˜•์€ nil๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ ํ• ๋‹น๋˜์ง€ ์•Š์€ ๋ณ€์ˆ˜์™€ ๊ฐ™์ด ์˜๋ฏธ์žˆ๋Š” ๊ฐ’์ด ์—†์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

print(my_var) -- "my_var"๋ณ€์ˆ˜์— ์•„์ง ๊ฐ’์ด ์ง€์ •๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด "nil"์ด ์ถœ๋ ฅ๋ฉ๋‹ˆ๋‹ค.

boolean

๋ถˆ๋ฆฐ์€ true๋‚˜ false๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. false๋‚˜ nil์ธ ์กฐ๊ฑด์€ false๊ฐ’์ด ๋˜๋ฉฐ, ๋‹ค๋ฅธ ๋ชจ๋“  ๊ฐ’์€ true๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

flag = true
if flag then
    print("flag๋Š” true์ด๋‹ค.")
else
    print("flag๋Š” false์ด๋‹ค.")
end

if my_var then
    print("my_var๋Š” nil๋„ false๋„ ์•„๋‹ˆ๋‹ค!")
end

if not my_var then
    print("my_var๋Š” nil์ด๊ฑฐ๋‚˜ false์ด๋‹ค!")
end

number

์ˆซ์žํ˜•์€ ๋‚ด๋ถ€์ ์œผ๋กœ 64๋น„ํŠธ ์ •์ˆ˜(integer) ๋˜๋Š” 64๋น„ํŠธ ๋ถ€๋™ ์†Œ์ˆซ์ (float)์œผ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. Lua๋Š” ํ•„์š”์— ๋”ฐ๋ผ ์ž๋™์ ์œผ๋กœ ์ด๋Ÿฌํ•œ ํ‘œํ˜„์„ ๋ณ€ํ™˜ํ•˜๋ฏ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฑฑ์ •ํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

print(10) --> prints '10'
print(10.0) --> '10'
print(10.000000000001) --> '10.000000000001'

a = 5 -- integer
b = 7/3 -- float
print(a - b) --> '2.6666666666667'

string

๋ฌธ์ž์—ด์€ ๋„๋ฌธ์ž(\0)๋ฅผ ํฌํ•จํ•˜๋Š” 8๋น„ํŠธ๊ฐ’์„ ๊ฐ€์ง€๋Š” ๋ถˆ๋ณ€์˜ ๋ฐ”์ดํŠธ ์‹œํ€€์Šค(immutable sequences of bytes)์ž…๋‹ˆ๋‹ค. Lua๋Š” ๋ฌธ์ž์—ด์˜ ๋‚ด์šฉ์— ๋Œ€ํ•ด ์•„๋ฌด๋Ÿฐ ์ถ”์ •์„ ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์–ด๋– ํ•œ ๋ฐ์ดํ„ฐ๋“  ์ €์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด์˜ ์ •์˜๋Š” ์Œ๋”ฐ์˜ดํ‘œ(")๋‚˜ ์‹ฑ๊ธ€๋”ฐ์˜ดํ‘œ(')๋กœ ์“ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Lua๋Š” ๋Ÿฐํƒ€์ž„์— ์ˆซ์ž์™€ ๋ฌธ์ž์—ด์„ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๋ฌธ์ž์—ด์€ .. ์—ฐ์‚ฐ์ž์— ์˜ํ•ด ๋ฌธ์ž์—ด ๋ผ๋ฆฌ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ž์—ด์€ C์–ธ์–ด ์Šคํƒ€์ผ์˜ ์ด์Šค์ผ€์ดํ”„ ์‹œํ€€์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค :

\a bell
\b back space
\f form feed
\n newline
\r carriage return
\t horizontal tab
\v vertical tab
\\ backslash
" double quote
' single quote
\[ left square bracket
\] right square bracket
\ddd 10์ง„์ˆ˜๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ ์—ฌ๊ธฐ์„œ ddd๋Š” ์ตœ๋Œ€ 3์ž๋ฆฌ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
my_string = "hello"
another_string = 'world'
print(my_string .. another_string) --> "helloworld"

print("10.2" + 1) --> 11.2
print(my_string + 1) -- ์—๋Ÿฌ, "hello"๋ฅผ ์ˆซ์ž๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†์Œ
print(my_string .. 1) --> "hello1"

print("one\nstring") --> one
                                 --> string

print("\097bc") --> "abc"

multi_line_string = [[
์—ฌ๋Ÿฌ์ค„๋กœ ๊ตฌ์„ฑ๋œ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ชจ๋‘ ๋ฌธ์ž์—ด
๋ณ€์ˆ˜์— ์ €์žฅ๋˜๋ฉฐ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.
]]

function

ํ•จ์ˆ˜๋Š” Lua์—์„œ ์ตœ์ƒ์œ„ ๊ฐ’์ž…๋‹ˆ๋‹ค. ์ฆ‰ ํ•จ์ˆ˜์— ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๊ฑฐ๋‚˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜์— ํ• ๋‹น๋œ ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ฐธ์กฐ(reference)๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋ณ€์ˆ˜๋ฅผ ์ต๋ช…ํ•จ์ˆ˜์— ํ• ๋‹น ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ Lua๋Š” ํŽธ์˜์ƒ (function name(param1, param2) โ€ฆ? end) ์™€ ๊ฐ™์€ ๋ฌธ๋ฒ•์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

-- 'my_plus'์— ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๊ธฐ
my_plus = function(p, q)
    return p + q
end

print(my_plus(4, 5)) --> 9

-- ๋ณ€์ˆ˜ 'my_mult'์— ํ•จ์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๋Š” ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•
function my_mult(p, q)
    return p * q
end

print(my_mult(4, 5)) --> 20

-- ํ•จ์ˆ˜๋ฅผ 'func' ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ๊ฐ€์ ธ์˜ด
function operate(func, p, q)
    return func(p, q) -- 'p'์™€ 'q' ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณต๋œ ํ•จ์ˆ˜๋กœ ํ˜ธ์ถœ
end

print(operate(my_plus, 4, 5)) --> 9
print(operate(my_mult, 4, 5)) --> 20

-- adder ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•จ
function create_adder(n)
    return function(a)
        return a + n
    end
end

adder = create_adder(2)
print(adder(3)) --> 5
print(adder(10)) --> 12

table

ํ…Œ์ด๋ธ”์€ Lua์˜ ์œ ์ผํ•œ ๊ตฌ์กฐ์  ๋ฐ์ดํ„ฐ ํƒ€์ž…์ž…๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋ฆฌ์ŠคํŠธ, ๋ฐฐ์—ด, ์‹œํ€€์Šค, ์‹ฌ๋ณผํ…Œ์ด๋ธ”, ์„ธํŠธ, ๋ ˆ์ฝ”๋“œ, ๊ทธ๋ž˜ํ”„, ํŠธ๋ฆฌ ๋“ฑ์„ ํ‘œํ˜„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜๋Š” ๊ด€๊ณ„ํ˜• ๋ฐฐ์—ด ๊ฐ์ฒด(associative array object)์ž…๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์€ ํ•ญ์ƒ ์ต๋ช…์ด๋ฉฐ ํ…Œ์ด๋ธ”์„ ํ• ๋‹นํ•˜๋Š” ๋ณ€์ˆ˜๋Š” ํ…Œ์ด๋ธ” ์ž์ฒด๊ฐ’์€ ํฌํ•จํ•  ์ˆ˜ ์—†์ง€๋งŒ ์ฐธ์กฐ๊ฐ’์€ ํฌํ•จ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์„ ์‹œํ€€์Šค๋กœ(์ˆœ์„œ๋Œ€๋กœ) ์ดˆ๊ธฐํ™” ํ•  ๋•Œ, ์ฒซ ๋ฒˆ์งธ ์ธ๋ฑ์Šค ๋ฒˆํ˜ธ๋Š” 0์ด ์•„๋‹ˆ๋ผ 1์ž…๋‹ˆ๋‹ค.

-- ํ…Œ์ด๋ธ”์„ ์‹œํ€€์Šค๋กœ ์ดˆ๊ธฐํ™”
weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday",
            "Thursday", "Friday", "Saturday"}
print(weekdays[1]) --> "Sunday"
print(weekdays[5]) --> "Thursday"

-- ์‹œํ€€์Šค ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ํ…Œ์ด๋ธ”์„ ๋ ˆ์ฝ”๋“œ๋กœ ์ดˆ๊ธฐํ™”
moons = { Earth = { "Moon" }, Uranus = { "Puck", "Miranda", "Ariel", "Umbriel", "Titania", "Oberon" } }
print(moons.Uranus[3]) --> "Ariel"

-- ํ…Œ์ด๋ธ”์„ ๋นˆ ์ƒ์„ฑ์ž{} ๋กœ ๋งŒ๋“ค๊ธฐ
a = 1
t = {}
t[1] = "first"
t[a + 1] = "second"
t.x = 1 -- same as t["x"] = 1

-- ํ…Œ์ด๋ธ”์˜ ํ‚ค, ๊ฐ’์„ ์Œ์œผ๋กœ ๋ฐ˜๋ณตํ•˜๊ธฐ
for key, value in pairs(t) do
    print(key, value)
end
--> 1   first
--> 2   second
--> x   1

u = t -- u๋Š” ์ด์ œ t์™€ ๊ฐ™์€ ํ…Œ์ด๋ธ”์„ ์ฐธ์กฐํ•จ
u[1] = "changed"

for key, value in pairs(t) do -- ์—ฌ์ „ํžˆ t๋กœ ๋ฐ˜๋ณต์ค‘!
    print(key, value)
end
--> 1   changed
--> 2   second
--> x   1

userdata

์œ ์ €๋ฐ์ดํ„ฐ๋Š” ์ž„์˜์˜ C ๋ฐ์ดํ„ฐ๋ฅผ Lua ๋ณ€์ˆ˜์— ์ €์žฅ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณต๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Defold๋Š” Hash๊ฐ’(hash), URL ๊ฐ์ฒด(url), ์ˆ˜ํ•™ ๊ฐ์ฒด(vertor3, vector4, matrix4, quaternion), ๊ฒŒ์ž„ ๊ฐ์ฒด, GUI๋…ธ๋“œ(node), ๋ Œ๋” ์„œ์ˆ ์ž(predicate), ๋ Œ๋” ํƒ€๊ฒŸ (render_target), ๋ Œ๋” ์ƒ์ˆ˜ ๋ฒ„ํผ(constant_buffer)์„ ์ €์žฅํ•˜๋Š”๋ฐ ์œ ์ €๋ฐ์ดํ„ฐ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

thread

์Šค๋ ˆ๋“œ๋Š” ๋…๋ฆฝ์ ์ธ ์‹คํ–‰ ์Šค๋ ˆ๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋ฉฐ ์ฝ”๋ฃจํ‹ด(coroutines)์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๊ฒƒ์€ ์•„๋ž˜๋ฅผ ์ฐธ๊ณ  ๋ฐ”๋ž๋‹ˆ๋‹ค.

Operators

Arithmetic operators(์‚ฐ์ˆ  ์—ฐ์‚ฐ์ž)

์ˆ˜ํ•™ ์—ฐ์‚ฐ์ž +, -, *, /, ๋‹จํ•ญ- (๋ถ€์ •), ์ง€์ˆ˜ ^

a = -1
print(a * 2 + 3 / 4^5) --> -1.9970703125

Relational/comparison operators(๊ด€๊ณ„/๋น„๊ต ์—ฐ์‚ฐ์ž)

< (~๋ณด๋‹ค ์ž‘์€), > (~๋ณด๋‹ค ํฐ), <= (~๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™์€), >= (~๋ณด๋‹ค ํฌ๊ฑฐ๋‚˜ ๊ฐ™์€), == (๊ฐ™์€), ~= (๊ฐ™์ง€ ์•Š์€). ์ด ์—ฐ์‚ฐ์ž๋“ค์€ ํ•ญ์ƒ true๋‚˜ false๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ์ž๋ฃŒํ˜•์˜ ๊ฐ’์€ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผ๋ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์ž๋ฃŒํ˜•์ด ๊ฐ™์„ ๊ฒฝ์šฐ, ์ž๋ฃŒํ˜•์— ๋งž๊ฒŒ ๋น„๊ต๋ฉ๋‹ˆ๋‹ค. Lua๋Š” ํ…Œ์ด๋ธ”, ์œ ์ €๋ฐ์ดํ„ฐ, ํ•จ์ˆ˜๋Š” ์ฐธ์กฐ(reference)์— ์˜ํ•ด ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋‘ ๊ฐ’์ด ๊ฐ™์€ ๊ฒƒ์œผ๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

a = 5
b = 6

if a <= b then
    print("a๋Š” b๋ณด๋‹ค ์ž‘๊ฑฐ๋‚˜ ๊ฐ™๋‹ค.")
end

๋…ผ๋ฆฌ ์—ฐ์‚ฐ์ž: and, or, not. and์—ฐ์‚ฐ์ž๋Š” false์ผ ๊ฒฝ์šฐ ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. or์—ฐ์‚ฐ์ž๋Š” false๊ฐ€ ์•„๋‹ ๊ฒฝ์šฐ ์ฒซ๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋‘๋ฒˆ์งธ ์ธ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

print(true or false) --> true
print(true and false) --> false
print(not false) --> true

if a == 5 and b == 6 then
    print("a๋Š” 5์ด๊ณ  b๋Š” 6์ด๋‹ค.")
end

Concatenation (์—ฐ๊ฒฐ)

๋ฌธ์ž์—ด์€ ..์—ฐ์‚ฐ์ž๋กœ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ˆซ์žํ˜•์„ ์—ฐ๊ฒฐํ•˜๋ฉด ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.

print("donkey" .. "kong") --> "donkeykong"
print(1 .. 2) --> "12"

Length

๋‹จํ•ญ ๊ธธ์ด ์—ฐ์‚ฐ์ž์ธ #์€ ๋ฌธ์ž์—ด์˜ ๊ธธ์ด๋ฅผ ๋ฐ”์ดํŠธ ์ˆ˜๋กœ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ํ…Œ์ด๋ธ”์˜ ๊ธธ์ด๋Š” ์‹œํ€€์Šค์˜ ๊ฐฏ์ˆ˜๋กœ ๊ณ„์‚ฐ๋˜๋ฉฐ, ์ธ๋ฑ์Šค ๋ฒˆํ˜ธ๋Š” 0์ด ์•„๋‹ˆ๋ผ 1๋ถ€ํ„ฐ ์ƒ‰์ธ๋ฉ๋‹ˆ๋‹ค. ์ฃผ์˜: ๋งŒ์•ฝ ๋งˆ์ง€๋ง‰ ์‹œํ€€์Šค๊ฐ€ nil๊ฐ’์ด๋ผ๋ฉด ์„ ํ–‰ ์‹œํ€€์Šค์˜ ์ธ๋ฑ์Šค๊ฐ€ ๊ธธ์ด๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

s = "donkey"
print(#s) --> 6

t = { "a", "b", "c", "d" }
print(#t) --> 4

u = { a = 1, b = 2, c = 3 }
print(#u) --> 0

v = { "a", "b", nil }
print(#v) --> 2

Flow control (ํ๋ฆ„์ œ์–ด)

Lua๋Š” ์ผ๋ฐ˜์ ์ธ ํ๋ฆ„์ œ์–ด๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

if then else

์กฐ๊ฑด์„ ํ…Œ์ŠคํŠธํ•  ๋•Œ, ์กฐ๊ฑด์ด true์ด๋ฉด then๊ตฌ๋ฌธ์„ ์‹คํ–‰ํ•˜๊ณ , ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด (์„ ํƒ์ ์œผ๋กœ) else๊ตฌ๋ฌธ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. if๋ฌธ์„ ์ค‘์ฒฉํ•˜๋Š” ๋Œ€์‹  elseif ๊ตฌ๋ฌธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ Lua๊ฐ€ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์€ switch๋ฌธ์„ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค.

a = 5
b = 4

if a < b then
    print("a๋Š” b๋ณด๋‹ค ์ž‘์Šต๋‹ˆ๋‹ค.")
end

if a == '1' then
    print("a๋Š” 1์ด๋‹ค.")
elseif a == '2' then
    print("a๋Š” 2์ด๋‹ค.")
elseif a == '3' then
    print("a๋Š” 3์ด๋‹ค.")
else
    print("์ด๊ฒŒ ๋ญ”์ง€ ๋ชจ๋ฅด๊ฒ ์–ด...")
end

while

์กฐ๊ฑด์ด true์ผ ๋™์•ˆ ๊ตฌ๊ฐ„์„ ๋ฐ˜๋ณต ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday",
            "Thursday", "Friday", "Saturday"}

-- Print each weekday
i = 1
while weekdays[i] do
    print(weekdays[i])
    i = i + 1
end

repeat until

์กฐ๊ฑด์ด true์ผ๋•Œ๊นŒ์ง€ ๊ตฌ๊ฐ„์ด ๋ฐ˜๋ณต๋ฉ๋‹ˆ๋‹ค. ์ด ์กฐ๊ฑด์€ ๊ตฌ๊ฐ„ ๋’ค์— ๊ณ„์‚ฐ๋˜๋ฏ€๋กœ ์ ์–ด๋„ ํ•œ ๋ฒˆ์€ ์‹คํ–‰ ๋ฉ๋‹ˆ๋‹ค.

weekdays = {"Sunday", "Monday", "Tuesday", "Wednesday",
            "Thursday", "Friday", "Saturday"}

-- Print each weekday
i = 0
repeat
    i = i + 1
    print(weekdays[i])
until weekdays[i] == "Saturday"

for

Lua๋Š” for๋ฐ˜๋ณต๋ฌธ์„ ์œ„ํ•ด numeric๊ณผ generic ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค. numeric์€ 2๋‚˜ 3 ๊ฐ™์€ ์ˆซ์ž๊ฐ’์„ ์ทจํ•˜๋Š” ๋ฐ˜๋ฉด, generic์€ iterator ํ•จ์ˆ˜์— ์˜ํ•ด ๋ชจ๋“  ๊ฐ’๋“ค์„ ๋ฐ˜๋ณต์ˆœํ™˜ํ•˜๋ฉฐ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

-- 1์—์„œ 10๊นŒ์ง€ ์ˆซ์ž ์ถœ๋ ฅํ•˜๊ธฐ
for i = 1, 10 do
    print(i)
end

-- 1์—์„œ 10๊นŒ์ง€ 2์”ฉ ๊ฑด๋„ˆ๋›ฐ๋ฉฐ ์ˆซ์ž ์ถœ๋ ฅํ•˜๊ธฐ
for i = 1, 10, 2 do
    print(i)
end

-- 10์—์„œ 1๊นŒ์ง€ ์ถœ๋ ฅํ•˜๊ธฐ
for i=10, 1, -1 do
    print(i)
end

t = { "a", "b", "c", "d" }
-- ์‹œํ€€์Šค๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉฐ ๊ฐ’ ์ถœ๋ ฅํ•˜๊ธฐ
for i, v in ipairs(t) do
    print(v)
end

break and return

break๊ตฌ๋ฌธ์€ for, while, repeat๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ ๋ธ”๋ก ์•ˆ์—์„œ ๋น ์ ธ๋‚˜์˜ฌ ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. return๊ตฌ๋ฌธ์€ ํ•จ์ˆ˜๊ฐ€ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰์„ ๋๋‚ด์•ผ ํ•  ๋•Œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. break์™€ return์€ ๋ธ”๋ก์—์„œ ๋งˆ์ง€๋ง‰ ๋ช…๋ น์–ด๋กœ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

a = 1
while true do
    a = a + 1
    if a >= 100 then
        break
    end
end

function my_add(a, b)
    return a + b
end

print(my_add(10, 12)) --> 22

Locals, globals and lexical scoping

๋ชจ๋“  ๋ณ€์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ global ๋ณ€์ˆ˜์ด๋ฉฐ Lua ๋Ÿฐํƒ€์ž„ ์ปจํ…์ŠคํŠธ์˜ ๋ชจ๋“  ๊ณณ์—์„œ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋‹ˆ๋ฉด ๋ช…ํ™•ํ•˜๊ฒŒ ํ˜„์žฌ ๋ฒ”์œ„์—์„œ๋งŒ ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ๊ฒŒ local ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

Lua๋Š” ์†Œ์Šค ํŒŒ์ผ์— ๋”ฐ๋ผ ๋ถ„๋ฆฌ๋œ ์˜์—ญ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ํ•œ ํŒŒ์ผ์—์„œ ์ตœ์ƒ์œ„ ๋ ˆ๋ฒจ์˜ local๋ณ€์ˆ˜ ์„ ์–ธ์€ Lua ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์˜ local ๋ณ€์ˆ˜์ž„์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ํ•จ์ˆ˜๋Š” ๋˜๋‹ค๋ฅธ ์ค‘์ฒฉ ์˜์—ญ์„ ์ƒ์„ฑํ•˜๋ฉฐ ๊ฐ ์ œ์–ด ๊ตฌ์กฐ ๋ธ”๋ก์€ ์ถ”๊ฐ€์ ์ธ ์˜์—ญ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. do์™€ end ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ช…ํ™•ํ•œ ๋ณ„๋„ ์˜์—ญ์„ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. Lua๋Š” ์–ธ์–ด์ ์ธ ์˜์—ญ(lexical scope)๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฉฐ ์ด๋Š” ๋‘˜๋Ÿฌ์‹ธ์ธ ์˜์—ญ์œผ๋กœ๋ถ€ํ„ฐ local๋ณ€์ˆ˜์— ๋ชจ๋“  ์ ‘๊ทผ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. local๋ณ€์ˆ˜๋Š” ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์„ ์–ธ๋ถ€ํ„ฐ ํ•ด์•ผํ•จ์„ ์•Œ์•„๋‘๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

function my_func(a, b)
    -- 'a'์™€ 'b'๋Š” ์ด ํ•จ์ˆ˜์˜ local๋ณ€์ˆ˜์ด๋ฉฐ ์ด ์˜์—ญ ์•ˆ์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
    do
        local x = 1
    end

    print(x) --> nil. 'x'๋Š” do-end๊ตฌ๋ฌธ ์•ˆ์—์„œ ์„ ์–ธ๋˜์—ˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    print(foo) --> nil. 'foo'๋Š” 'my_func'์ดํ›„์— ์„ ์–ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
    print(foo_global) --> "value 2"
end

local foo = "value 1"
foo_global = "value 2"

print(foo) --> "value 1". 'foo'๋Š” ์„ ์–ธ ์ดํ›„์ด๊ณ  ์ตœ์ƒ์œ„ ์˜์—ญ์— ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์—์„œ localํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋Š” ๊ฒƒ์€(์ผ๋ฐ˜์ ์œผ๋กœ ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.) ์ฝ”๋“œ์˜ ์ˆœ์„œ๋ฅผ ์ฃผ์˜๊นŠ๊ฒŒ ์‚ดํŽด๋ณผ ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ์„œ๋กœ ํ˜ธ์ถœ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ ํ•„์š”ํ•  ๊ฒฝ์šฐ์—” ์ „๋ฐฉ์„ ์–ธ(forward declarations)์ด ํ•„์š”ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

local func2 -- 'func2'๋ฅผ ์ „๋ฐฉ์„ ์–ธํ•จ

local function func1(a)
    print("func1")
    func2(a)
end

function func2(a) -- or func2 = function(a)
    print("func2")
    if a < 10 then
        func1(a + 1)
    end
end

function init(self)
    func1(1)
end

๋งŒ์•ฝ ๋‹ค๋ฅธ ํ•จ์ˆ˜์— ๋‘˜๋Ÿฌ์‹ธ์ธ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด, ์•ˆ์ชฝ ํ•จ์ˆ˜ ์—ญ์‹œ local ๋ณ€์ˆ˜๋“ค์— ๋ชจ๋“  ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ๋‹ค์–‘ํ•œ ์ƒ์„ฑ์ž๋ฅผ ๋งŒ๋“œ๋Š”๋ฐ ๋งค์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

function create_counter(x)
    -- 'x'๋Š” 'create_counter'ํ•จ์ˆ˜์˜ ๋กœ์ปฌ๋ณ€์ˆ˜์ž…๋‹ˆ๋‹ค.
    return function()
        x = x + 1
        return x
    end
end

count1 = create_counter(10)
count2 = create_counter(20)
print(count1()) --> 11
print(count2()) --> 21
print(count1()) --> 12

Variable shadowing

๊ฐ™์€ ์ด๋ฆ„์œผ๋กœ ์žฌ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ๊ทธ๋ฆผ์žํšจ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜๊ฒŒ ๋˜์–ด ์žฌ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

my_global = "global"
print(my_global) -->"global"

local v = "local"
print(v) --> "local"

local function test(v)
    print(v)
end

function init(self)
    v = "apple"
    print(v) --> "apple"
    test("banana") --> "banana"
end

Coroutines

ํ•จ์ˆ˜๋Š” ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ ์‹คํ–‰๋˜๋ฉฐ ์ค‘๊ฐ„์— ๋ฉˆ์ถœ ๋ฐฉ๋ฒ•์ด ์—†์ง€๋งŒ, ์ฝ”๋ฃจํ‹ด์€ ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๊ทธ๊ฒƒ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ y์ขŒํ‘œ๋ฅผ ํŠน์ •ํ•œ ์œ„์น˜๋กœ ์ด๋™์‹œํ‚ค๋ฉฐ ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์• ๋‹ˆ๋ฉ”์ด์…˜ ํšจ๊ณผ๋ฅผ ์ค˜์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค. ์•„๋ž˜์—์„œ ๋ณด๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ update() ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ฝ”๋ฃจํ‹ด์„ ์‚ฌ์šฉํ•˜์—ฌ ์‰ฌ์šด ๋ฐฉ๋ฒ•์œผ๋กœ ๋” ํ™•์žฅ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์ƒํƒœ๊ฐ’์€ ์ฝ”๋ฃจํ‹ด ์•ˆ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

์ฝ”๋ฃจํ‹ด์—์„œ yield๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์ œ์–ด๊ถŒ์ด ํ˜ธ์ถœ์ž์—๊ฒŒ ๋ฐ˜ํ™˜๋˜์ง€๋งŒ ์‹คํ–‰ ์ง€์ ์ด ๊ธฐ์–ต๋˜์–ด ๋‚˜์ค‘์— ๊ณ„์† ์‹คํ–‰๋˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

-- ์ด๊ฒƒ์ด ๋ฐ”๋กœ ์šฐ๋ฆฌ์˜ ์ฝ”๋ฃจํ‹ด!
local function sequence(self)
    coroutine.yield(120)
    coroutine.yield(320)
    coroutine.yield(510)
    coroutine.yield(240)
    return 440 -- ๋งˆ์ง€๋ง‰ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
end

function init(self)
    self.co = coroutine.create(sequence) -- ์ฝ”๋ฃจํ‹ด์„ ์ƒ์„ฑํ•˜์—ฌ 'self.co'๋ฅผ ์Šค๋ ˆ๋“œ ์˜ค๋ธŒ์ ํŠธ๋กœ ๋งŒ๋“ ๋‹ค.
    go.set_position(vmath.vector3(100, 0, 0)) -- ์œ„์น˜ ์ดˆ๊ธฐํ™”ํ•˜๊ธฐ
end

function update(self, dt)
    local status, y_pos = coroutine.resume(self.co, self) -- ์ฝ”๋ฃจํ‹ด์„ ์žฌ์‹คํ–‰ํ•œ๋‹ค.
    if status then
        -- ์ฝ”๋ฃจํ‹ด์ด ์•„์ง ์‚ด์•„ ์žˆ๋‹ค๋ฉด yield๊ฐ€ ์ƒˆ ์œ„์น˜๊ฐ’์„ ๋ฐ˜ํ™˜ํ•  ๊ฒƒ์ด๋‹ค.
        go.set_position(vmath.vector3(100, y_pos, 0))
    end
end

Defold scripts

Defold ์—๋””ํ„ฐ๋Š” Lua ์Šคํฌ๋ฆฝํŒ…์„ ์œ„ํ•ด ๋ฌธ๋ฒ• ์ปฌ๋Ÿฌ๋ง๊ณผ ์ž๋™์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. Defold ํ•จ์ˆ˜ ์ด๋ฆ„์„ ์™„์„ฑ์‹œํ‚ค๊ธฐ ์œ„ํ•ด Ctrl+Space๋ฅผ ๋ˆ„๋ฅด๋ฉด ์ž…๋ ฅ์ค‘์ธ ํ•จ์ˆ˜๋ช…์— ์•Œ๋งž์€ ํ•จ์ˆ˜ ๋ชฉ๋ก์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

Auto completion

Defold์˜ Lua ์Šคํฌ๋ฆฝํŠธ๋Š” 3๊ฐ€์ง€ ํ˜•์‹์œผ๋กœ ๊ตฌ๋ถ„๋˜๋ฉฐ, ๊ฐ๊ฐ ๋‹ค๋ฅธ Defold ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Logic scripts

ํ™•์žฅ์ž๋Š” .script ์ด๋ฉฐ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ์— ์˜ํ•ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ๋กœ์ง ์Šคํฌ๋ฆฝํŠธ๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ œ์–ดํ•˜๊ฑฐ๋‚˜ ๋ ˆ๋ฒจ์„ ๋กœ๋”ฉํ•˜์—ฌ ๊ฒŒ์ž„ ๊ทœ์น™ ๋“ฑ๊ณผ ์—ฎ๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋กœ์ง ์Šคํฌ๋ฆฝํŠธ๋Š” GUI๋‚˜ Render ํ•จ์ˆ˜๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  Defold ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•จ์ˆ˜์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GUI scripts

ํ™•์žฅ์ž๋Š” .guiscript ์ด๋ฉฐ GUI์ปดํฌ๋„ŒํŠธ์— ์˜ํ•ด ์‹คํ–‰๋˜๊ณ  ์ผ๋ฐ˜์ ์œผ๋กœ HUD๋‚˜ ๋ฉ”๋‰ด ๊ฐ™์€ GUI์š”์†Œ๋“ค์„ ํ‘œ์‹œํ•˜๋Š”๋ฐ ์š”๊ตฌ๋˜๋Š” ๋กœ์ง์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. GUI์Šคํฌ๋ฆฝํŠธ๋Š” GUI๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•จ์ˆ˜์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Render scripts

ํ™•์žฅ์ž๋Š” .renderscript ์ด๋ฉฐ ๋ Œ๋”๋ง ํŒŒ์ดํ”„๋ผ์ธ์— ์˜ํ•ด ์‹คํ–‰๋˜๊ณ  ๊ฐ ํ”„๋ ˆ์ž„๋งˆ๋‹ค ๊ฒŒ์ž„์˜ ๋ชจ๋“  ๊ทธ๋ž˜ํ”ฝ์„ ๋ Œ๋”๋งํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ๋กœ์ง์„ ํฌํ•จํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๋ Œ๋” ์Šคํฌ๋ฆฝํŠธ๋Š” Render ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ•จ์ˆ˜์— ์ ‘๊ทผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Script execution and callbacks

Defold๋Š” Lua ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์—”์ง„ ๋ผ์ดํ”„์‚ฌ์ดํด์˜ ์ผ๋ถ€๋กœ ์‹คํ–‰ํ•˜๋ฉฐ ๋ฏธ๋ฆฌ ์ •์˜๋œ ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋“ค์„ ๋…ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์— ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ํ•ด๋‹น ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ์™€ ์ปดํฌ๋„ŒํŠธ์˜ ์ˆ˜๋ช…์ฃผ๊ธฐ์˜ ์ผ๋ถ€๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. ์ด ์Šคํฌ๋ฆฝํŠธ๋Š” ๋กœ๋“œ๋  ๋•Œ ๋ฃจ์•„ ์ปจํ…์ŠคํŠธ์— ์˜ํ•ด ํ‰๊ฐ€๋˜๊ณ , ์—”์ง„์€ ์•„๋ž˜ ํ•จ์ˆ˜๋“ค์„ ์‹คํ–‰ํ•˜๊ณ  ํ˜„์žฌ ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ์˜ ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ๊ฐ’์„ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ "self" ๋ช…๋ น์–ด๋ฅผ ์ด์šฉํ•˜์—ฌ ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. "self"๋Š” Lua์˜ table๊ณผ ๋น„์Šทํ•œ userdata ์˜ค๋ธŒ์ ํŠธ์ด์ง€๋งŒ pairs()๋‚˜ ipairs()๊ฐ™์€ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ์ ‘๊ทผํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

init(self)

์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ดˆ๊ธฐํ™” ๋ ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

function init(self)
    -- ํ˜„์žฌ ์ปดํฌ๋„ŒํŠธ์™€ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ํ•จ๊ป˜ ํ•˜๋Š” ๋ณ€์ˆ˜๋“ค
    self.my_var = "something"
    self.age = 0
end

final(self)

์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‚ญ์ œ๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์Šคํฐ๋œ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ปดํฌ๋„ŒํŠธ์™€ ํ•จ๊ป˜ ์‚ญ์ œ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

function final(self)
    if self.my_var == "something" then
        -- ์ด๊ฒƒ์ €๊ฒƒ ์‚ญ์ œ ์ฒ˜๋ฆฌ
    end
end

update(self, dt)

๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ•œ๋ฒˆ์”ฉ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. dt๋Š” ์ตœ๊ทผ ํ”„๋ ˆ์ž„ ์ดํ›„์˜ delta time์ž…๋‹ˆ๋‹ค.

function update(self, dt)
    self.age = self.age + dt -- ํ๋ฅธ ์‹œ๊ฐ„๋งŒํผ age ๊ฐ’์ด ์ฆ๊ฐ€ํ•จ
end

on_message(self, message_id, message, sender)

msg.post()๋ฅผ ์ด์šฉํ•˜์—ฌ ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๋ฉด, ๊ฒŒ์ž„์—”์ง„์€ ์ˆ˜์‹ ์ž ์ปดํฌ๋„ŒํŠธ์˜ ์ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

on_input(self, action_id, action)

์ธํ’‹ ์„ค์ • ํ›„์— ์ด ์ปดํฌ๋„ŒํŠธ์—์„œ ์ž…๋ ฅ์ด ๊ฐ์ง€๋˜๋ฉด (acquire_input_focus ์ฐธ๊ณ ), ๊ฒŒ์ž„์—”์ง„์€ ์ด ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

on_reload(self)

์ด ํ•จ์ˆ˜๋Š” ์—๋””ํ„ฐ์—์„œ (Edit โ–ธ Reload Resource) ๋ฉ”๋‰ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ํ•ซ๋ฆฌ๋กœ๋“œ ๊ธฐ๋Šฅ์„ ํ†ตํ•ด ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์žฌ ๋กœ๋”ฉ๋  ๋•Œ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ๋Šฅ์€ ๋””๋ฒ„๊น…, ํ…Œ์ŠคํŠธ, ์ตœ์ ํ™”๊ฐ€ ๋ชฉ์ ์ผ ๋•Œ ์œ ์šฉํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค.

function on_reload(self)
    print(self.age) -- ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ์˜ age๊ฐ’์„ ์ถœ๋ ฅํ•˜๊ธฐ
end

Reactive logic(๋ฐ˜์‘ํ˜• ๋กœ์ง)

์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ๋Š” ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋กœ์ง์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋กœ์ง์€ ์ข…์ข… ๋ช‡๊ฐ€์ง€ ์™ธ๋ถ€ ์š”์ธ์— ์˜์กดํ•˜๋Š”๋ฐ, ์˜ˆ๋ฅผ ๋“ค์–ด ์  AI๊ฐ€ ํŠน์ • ๋ฐ˜๊ฒฝ ๋‚ด์— ์žˆ๋Š” ํ”Œ๋ ˆ์ด์–ด์— ๋ฐ˜์‘ ํ•œ๋‹ค๋˜์ง€ ํ”Œ๋ ˆ์ด์–ด ์ƒํ˜ธ์ž‘์šฉ์œผ๋กœ ๋ฌธ์ด ์ž ๊ธฐ๊ณ  ์—ด๋ฆฌ๋Š” ๋ฐ˜์‘ ๋“ฑ์ด ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

update() ํ•จ์ˆ˜๋Š” ์ƒํƒœ๋จธ์‹ (state machine)์„ ์ •์˜ํ•˜๋Š” ๋ณตํ•ฉ์ ์ธ ๊ธฐ๋Šฅ๋“ค์„ ๋งค ํ”„๋ ˆ์ž„ ๋งˆ๋‹ค ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ๋ฉฐ ๋•Œ๋•Œ๋กœ ์ด๊ฒƒ์€ ์ ์ ˆํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋งค๋ฒˆ update() ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์€ ์„ฑ๋Šฅ์ƒ ๋น„์šฉ์ด ๋“œ๋Š” ์ผ์ด๋ฏ€๋กœ ๊ผญ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด ๋ฐ˜์‘ํ˜• ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธธ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์‘๋‹ต์„ ์œ„ํ•ด ๊ฒŒ์ž„ ์›”๋“œ์˜ ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋“ค์„ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์กฐ์‚ฌํ•˜๋Š” ๊ฒƒ ๋ณด๋‹ค ์‘๋‹ต์„ ํŠธ๋ฆฌ๊ฑฐ ํ•˜๋Š” ํŠน์ • ๋ฉ”์„ธ์ง€๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋ฐฉ๋ฒ•์ด ๋”์šฑ ์„ฑ๋Šฅ์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. ๋” ๋‚˜์•„๊ฐ€์„œ, ์ด ๋ฐฉ๋ฒ•์€ ์ข…์ข… ๋กœ์ง ์„ค๊ณ„ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๋„ ํ•˜๋ฏ€๋กœ ๋” ๊น”๋”ํ•˜๊ณ  ์•ˆ์ •์ ์ธ ์„ค๊ณ„ ๋ฐ ๊ตฌํ˜„์„ ์ด๋Œ์–ด ๋‚ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌ์ฒด์ ์ธ ์˜ˆ์ œ๋ฅผ ๋ด…์‹œ๋‹ค. ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์‹œ์ž‘ ๋œ ํ›„ 2์ดˆ ํ›„์— ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด๊ณ , ํŠน์ • ์‘๋‹ต ๋ฉ”์„ธ์ง€๋ฅผ ๊ธฐ๋‹ค๋ฆฌ๊ณ , ํŠน์ • ์‘๋‹ต ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ›์€ ํ›„ 5์ดˆ ํ›„์— ๋˜ ๋‹ค๋ฅธ ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๋‚ด์•ผ ํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ด…์‹œ๋‹ค. ์•„๋ž˜๋Š” ์ด๋ฅผ ๋น„๋ฐ˜์‘ํ˜• ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค.:

function init(self)
        -- ์‹œ๊ฐ„๊ฐ’์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•œ ์นด์šดํ„ฐ ์…‹ํŒ…
        self.counter = 0
        -- ์ƒํƒœ๊ฐ’์„ ์ถ”์ ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฐ’
        self.state = "first"
end

function update(self, dt)
        self.counter = self.counter + dt
        if self.counter >= 2.0 and self.state == "first" then
                -- 2์ดˆ ํ›„์— ๋ฉ”์„ธ์ง€ ๋ณด๋‚ด๊ธฐ
                msg.post("some_object", "some_message")
        end
        if self.counter >= 5.0 and self.state == "second" then
                -- "response" ๋ฉ”์„ธ์ง€๋ฅผ ๋ฐ›์€ ํ›„ 5์ดˆ ํ›„์— ๋ณด๋‚ด๊ธฐ
                msg.post("another_object", "another_message")
                -- state๋ฅผ nil๋กœ ์…‹ํŒ…ํ•ด์„œ ์ด ๋ธ”๋ก์ด ๋˜ ์‹คํ–‰๋˜์ง€ ์•Š๊ฒŒ ํ•จ
                self.state = nil
        end
end

function on_message(self, message_id, message, sender)
        if message_id == hash("response") then
                -- โ€œfirstโ€์ƒํƒœ์˜ ์ฒ˜๋ฆฌ๋“ค์ด ์™„๋ฃŒ๋˜์—ˆ์œผ๋ฏ€๋กœ ๋‹ค์Œ ์ƒํƒœ๋กœ ๋„˜์–ด๊ฐ€์ž
                self.state = "second"
                -- ์นด์šดํ„ฐ ์ดˆ๊ธฐํ™”
                self.counter = 0
        end
end

๊ฝค ๊ฐ„๋‹จํ•œ ์ผ€์ด์Šค์ž„์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๋กœ์ง์ด ์ƒ๋‹นํžˆ ๊ผฌ์ด๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ฝ”๋ฃจํ‹ด์˜ ๋„์›€์„ ๋ฐ›์•„ ๋” ๋‚˜์€ ์ฝ”๋“œ๋ฅผ ์งค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  ์• ๋‹ˆ๋ฉ”์ด์…˜ ์†์„ฑ ๊ธฐ๋Šฅ์ธ ํƒ€์ด๋ฐ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜์‘ํ˜• ๋กœ์ง์„ ๊ตฌํ˜„ํ•ด์•ผ๋งŒ ํ•ฉ๋‹ˆ๋‹ค.

-- ํƒ€์ด๋ฐ์„ ์œ„ํ•œ Dummy ์†์„ฑ๊ฐ’
go.property("dummy", 0)
function init(self)
        -- 2์ดˆ ํ›„์— send_first() ํ˜ธ์ถœ
        go.animate("#", "dummy", go.PLAYBACK_ONCE_FORWARD, 0,
                     go.EASING_LINEAR, 2.0, 0, send_first)
end

function send_first()
        msg.post("some_object", "some_message")
end

function send_second()
        msg.post("another_object", "another_message")
end

function on_message(self, message_id, message, sender)
        if message_id == hash("response") then
                -- 5์ดˆ ํ›„์— send_second() ํ˜ธ์ถœ
                go.animate("#", "dummy", go.PLAYBACK_ONCE_FORWARD, 0,
                            go.EASING_LINEAR, 5.0, 0, send_second)
        end
end

์ด ๋ฐฉ์‹์€ ๊น”๋”ํ•˜๋ฉฐ ๋…ผ๋ฆฌ์ ์ธ ํ๋ฆ„์„ ๋”ฐ๋ผ๊ฐ€๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๋กœ์ง์„ ๋”ฐ๋ผ๊ฐ€๊ธฐ ์–ด๋ ต๊ณ  ๋ฏธ๋ฌ˜ํ•œ ๋ฒ„๊ทธ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด๋ถ€ ์ƒํƒœ ๋ณ€์ˆ˜๋“ค์„ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ์—๋„ ์ข‹์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ update() ํ•จ์ˆ˜๋ฅผ ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜์—ฌ ์ดˆ๋‹น 60ํšŒ์˜ ์Šคํฌ๋ฆฝํŠธ ํ˜ธ์ถœ์„ ์ค„์ด๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

Lua contexts in Defold

์„ ์–ธํ•œ ๋ชจ๋“  ๋ณ€์ˆ˜๋“ค์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ „์—ญ(global)๋ณ€์ˆ˜์ด๋ฏ€๋กœ Lua ๋Ÿฐํƒ€์ž„ ์ปจํ…์ŠคํŠธ์˜ ๋ชจ๋“  ๋ถ€๋ถ„์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Defold์—๋Š” ์ด ์ปจํ…์ŠคํŠธ๋ฅผ ์ œ์–ดํ•˜๋Š” "game.project"์— shared_state ์„ค์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์„ ์„ค์ •ํ•˜๋ฉด ์Šคํฌ๋ฆฝํŠธ, GUI์Šคํฌ๋ฆฝํŠธ, ๋ Œ๋”์Šคํฌ๋ฆฝํŠธ ๋ชจ๋‘๋Š” ๊ฐ™์€ Lua ์ปจํ…์ŠคํŠธ์—์„œ ์‹คํ–‰๋˜๊ณ  global๋ณ€์ˆ˜๋“ค์€ ์–ด๋””์—์„œ๋“  ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ด ์ง‘๋‹ˆ๋‹ค. ์ด ์˜ต์…˜์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฒŒ์ž„ ์—”์ง„์€ ์Šคํฌ๋ฆฝํŠธ๋“ค๊ณผ GUI์Šคํฌ๋ฆฝํŠธ, ๋ Œ๋”์Šคํฌ๋ฆฝํŠธ๋“ค์„ ๊ฐ๊ฐ์˜ ์ปจํ…์ŠคํŠธ์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Contexts

Defold allows you to use the same script file in several separate game object components. Any locally declared variables are shared between components that runs the same script file. Defold๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ ๊ฐ™์€ ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ์ปฌ๋กœ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋“ค์€ ๊ฐ™์€ ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์‹คํ–‰ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ„์— ๊ณต์œ ๋ฉ๋‹ˆ๋‹ค.

-- 'my_global_value'๋Š” ์Šคํฌ๋ฆฝํŠธ, gui์Šคํฌ๋ฆฝํŠธ,๋ Œ๋”์Šคํฌ๋ฆฝํŠธ,๋ชจ๋“ˆ(๋ฃจ์•„ ํŒŒ์ผ)๋“ค ๋ชจ๋‘์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ
my_global_value = "global scope"

-- ์ด ๊ฐ’์€ ์ด ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค๋“ค์—๊ฒŒ ๊ณต์œ ๋จ
local script_value = "script scope"

function init(self, dt)
    -- ์ด ๊ฐ’์€ ์ด ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ ์ธ์Šคํ„ด์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ
    self.foo = "self scope"

    -- ์ด ๊ฐ’์€ ์„ ์–ธ ์ดํ›„์— init()ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ
    local local_foo = "local scope"
    print(local_foo)
end

function update(self, dt)
    print(self.foo)
    print(my_global_value)
    print(script_value)
    print(local_foo) -- local_foo๋Š” init()ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ์กด์žฌํ•˜๋ฏ€๋กœ nil์ด ์ถœ๋ ฅ๋ ๊ฑฐ์ž„
end

Performance considerations(์„ฑ๋Šฅ ๊ณ ๋ ค์‚ฌํ•ญ)

60FPS๋กœ ๋งค๋„๋Ÿฝ๊ฒŒ ๋™์ž‘ํ•ด์•ผ๋งŒ ํ•˜๋Š” ๊ณ ์„ฑ๋Šฅ ๊ฒŒ์ž„์—์„œ๋Š” ์ž๊ทธ๋งˆํ•œ ์‹ค์ˆ˜๋กœ ์œ ์ € ๊ฒฝํ—˜์— ํฌ๊ฒŒ ์•…์˜ํ–ฅ์„ ๋ผ์น  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ๋ช‡๊ฐ€์ง€ ๊ฐ„๋‹จํ•œ ๊ณ ๋ ค์‚ฌํ•ญ์„ ์‚ดํŽด๋ณด๊ณ , ๋ฌธ์ œ๊ฐ€ ์—†์–ด ๋ณด์ด๋Š” ๋“ฏํ•œ ๋ช‡๊ฐ€์ง€ ์‚ฌํ•ญ๋„ ์‚ดํŽด๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.

๊ฐ„๋‹จํ•œ ๊ฒƒ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•ด๋ณด์ž๋ฉด, ๋ถˆํ•„์š”ํ•œ ๋ฐ˜๋ณต๋ฌธ์„ ์“ฐ์ง€ ์•Š๊ณ  ๊ฐ„๋‹จํ•œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๊ฐ€๋”์€ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณตํ•ด์•ผ ํ•˜๊ธฐ๋„ ํ•˜์ง€๋งŒ ์–ด๋А์ •๋„ ํฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š” ๊ฒฝ์šฐ์—” ์ฃผ์˜ํ•  ํ•„์š”๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ์•„๋ž˜ ์˜ˆ์ œ๋ฅผ ๊ฐ ํ”„๋ ˆ์ž„์ด 16๋ฐ€๋ฆฌ์ดˆ(60FPS)์ธ ๊ฒŒ์ž„์—”์ง„, ๋ Œ๋”์Šคํฌ๋ฆฝํŠธ, ๋ฌผ๋ฆฌ ์‹œ๋ฎฌ๋ ˆ์ด์…˜๊ณผ ํ•จ๊ป˜ ์‹คํ–‰ํ•œ๋‹ค๋ฉด ์„ฑ๋Šฅ์„ ์™•์ฐฝ ์žก์•„๋จน๊ฒŒ ๋˜์–ด ๊ฝค ๊ดœ์ฐฎ์€ ๋…ธํŠธ๋ถ์—์„œ๋งˆ์ € ์•ฝ 1๋ฐ€๋ฆฌ์ดˆ ๊ฐ€๋Ÿ‰ ๋” ๊ฑธ๋ฆฌ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

local t = os.clock()
local table = {}
for i=1,2000 do
    table[i] = vmath.vector3(i, i, i)
end
print((os.clock() - t) * 1000)

-- DEBUG:SCRIPT: 1.18

os.clock()์—์„œ ๋ฐ˜ํ™˜ ๋œ ๊ฐ’ (ํ”„๋กœ๊ทธ๋žจ์˜ CPU์‹œ๊ฐ„(์ดˆ))์„ ์‚ฌ์šฉํ•˜์—ฌ ์˜์‹ฌ์Šค๋Ÿฌ์šด ์ฝ”๋“œ๋ฅผ ๋ฒค์น˜ ๋งˆํฌํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

Memory and garbage collection(๋ฉ”๋ชจ๋ฆฌ์™€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜)

Lua์˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ž๋™์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ Lua๋Ÿฐํƒ€์ž„์ด ํ• ๋‹นํ•œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšŒ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ๋งŽ์€ ๊ฐ€๋น„์ง€๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๊ฒƒ์€ ์‹œ๊ฐ„์„ ๊ฝค ์†Œ๋ชจํ•˜๋Š” ์ž‘์—…์ด ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์˜ค๋ธŒ์ ํŠธ์˜ ์ˆ˜๋ฅผ ํ•„์š”ํ•œ ๋งŒํผ๋งŒ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค:

  • local ๋ณ€์ˆ˜๋Š” ์Šค์Šค๋กœ ํ•ด์ œ๋˜๋ฉฐ ๊ฐ€๋น„์ง€๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์˜ˆ: local v = 42)
  • ๊ฐ๊ฐ์˜ ์ƒˆ๋กœ์šด ๊ณ ์œ ํ•œ ๋ฌธ์ž์—ด์€ ์ƒˆ๋กœ์šด ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. local s = "some_string" ๋Š” ์ƒˆ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  s์— ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. local s ๋Š” ๊ฐ€๋น„์ง€๋ฅผ ์ƒ์„ฑํ•˜์ง€๋Š” ์•Š์ง€๋งŒ ๋ฌธ์ž์—ด ์˜ค๋ธŒ์ ํŠธ๋Š” ๊ฐ€๋น„์ง€๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋™์ผํ•œ ๋ฌธ์ž์—ด์„ ์—ฌ๋Ÿฌ๋ฒˆ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋ฉ”๋ชจ๋ฆฌ ๋น„์šฉ์ด ์ถ”๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • { โ€ฆโ€‹ }๋กœ ํ…Œ์ด๋ธ” ์ƒ์„ฑ์ž๊ฐ€ ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ ํ…Œ์ด๋ธ”์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • function ๊ตฌ๋ฌธ์„ ์‹คํ–‰ํ•˜๋ฉด ํด๋กœ์ € ์˜ค๋ธŒ์ ํŠธ(closure object)๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. (์ฆ‰ ์ •์˜๋œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ function() ... end ๊ตฌ๋ฌธ์„ ์‹คํ–‰ํ•จ)
  • function(v, โ€ฆโ€‹) end์™€ ๊ฐ™์ด ์ธ์ž์˜ ์ˆ˜๊ฐ€ ๊ฐ€๋ณ€์ธ ํ•จ์ˆ˜(Vararg functions)๋Š” ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ๋งˆ๋‹ค ์ธ์ž๊ฐ’์„ ๋‹ด๋Š” ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. (Lua 5.2 ์ด์ „ ๋ฒ„์ „ ํ˜น์€ LuaJIT์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ)
  • ํŒŒ์ผ์„ ๋‹ค๋ฃจ๊ฑฐ๋‚˜ ๋ฌธ์ž์—ด์„ ๋‹ค๋ฃจ๋Š” ํ•จ์ˆ˜๋“ค
  • Userdata ์˜ค๋ธŒ์ ํŠธ

์ƒˆ๋กœ์šด ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ์ด๋ฏธ ๋งŒ๋“ค์–ด์ง„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” update() ํ•จ์ˆ˜์˜ ๋๋ถ€๋ถ„์— ๋‚˜ํƒ€๋‚˜๋Š” ์ผ๋ฐ˜์ ์ธ ์‹ค์ˆ˜์— ๋Œ€ํ•œ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค:

-- ์†๋„ ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ
self.velocity = vmath.vector3()

์ข…์ข… vmath.vector3()๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ์ƒˆ๋กœ์šด ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๊นœ๋นกํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค. vector3๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ์–‘์„ ํ•œ ๋ฒˆ ์•Œ์•„ ๋ด…์‹œ๋‹ค:

print(collectgarbage("count") * 1024)       -- 88634
local v = vmath.vector3()
print(collectgarbage("count") * 1024)       -- ์ด 88704. 70๋ฐ”์ดํŠธ๊ฐ€ ํ• ๋‹น๋จ

collectgarbage()ํ•จ์ˆ˜ ์‚ฌ์ด์— ์•ฝ 70๋ฐ”์ดํŠธ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์ง€๋งŒ ์ด๋Š” ์ˆœ์ˆ˜ํ•œ vector3 ์˜ค๋ธŒ์ ํŠธ๋ณด๋‹ค ๋” ๋งŽ์ด ํ• ๋‹น๋˜์—ˆ์Šต๋‹ˆ๋‹ค. collectgarbage()ํ•จ์ˆ˜์˜ ๊ฒฐ๊ณผ๋ฅผ ์ถœ๋ ฅํ•  ๋ฌธ์ž์—ด์„ ๋งŒ๋“œ๋Š”๋ฐ ๊ฐ€๋น„์ง€์˜ ์•ฝ 22๋ฐ”์ดํŠธ๊ฐ€ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

print(collectgarbage("count") * 1024)       -- 88611
print(collectgarbage("count") * 1024)       -- 88633. 22๋ฐ”์ดํŠธ๊ฐ€ ํ• ๋‹น๋จ

๋”ฐ๋ผ์„œ vector3๋Š” 70-22=48 byte์ž…๋‹ˆ๋‹ค. ๋งŽ์€ ์–‘์€ ์•„๋‹ˆ์ง€๋งŒ 60FPS์˜ ๊ฒŒ์ž„์—์„œ ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ์ƒ์„ฑํ•œ๋‹ค๋ฉด ๊ฐ‘์ž๊ธฐ ์ดˆ๋‹น 2.8kb์˜ ๊ฐ€๋น„์ง€๊ฐ€ ์ƒ๊ธฐ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ๋งค ํ”„๋ ˆ์ž„๋งˆ๋‹ค ํ•˜๋‚˜์˜ vector3๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ 360๊ฐœ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ดˆ๋‹น 1MB์”ฉ ์ƒ์„ฑ๋˜๋Š” ๊ฐ€๋น„์ง€๋ฅผ ๋งŒ๋‚˜๊ฒŒ ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ€๋น„์ง€๋Š” ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ๋ˆ„์  ์ฆ๊ฐ€ํ•˜๊ฒŒ ๋˜์–ด Lua ๋Ÿฐํƒ€์ž„์ด ๊ฐ€๋น„์ง€๋ฅผ ์ˆ˜์ง‘ํ•˜๊ฒŒ ๋  ๋•Œ, ํŠนํžˆ ๋ชจ๋ฐ”์ผ ํ”Œ๋žซํผ์—์„œ ๋งค์šฐ ์†Œ์ค‘ํ•œ ์‹œ๊ฐ„๋“ค์„ ์žก์•„๋จน์–ด ๋ฒ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

vector3๊ฐ€ ์ƒ์„ฑ๋˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋™์ผํ•œ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, vector3๋ฅผ ์ดˆ๊ธฐํ™” ํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜์˜ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

-- ์ƒˆ๋กœ์šด ๊ฐ์ฒด๊ฐ€ ์ƒ์„ฑ๋˜๋Š” self.velocity = vmath.vector3() ๋Œ€์‹ ์—
-- ์ด๋ฏธ ์กด์žฌํ•˜๋Š” vector ๊ฐ์ฒด์˜ ๊ฐ’์„ 0์œผ๋กœ ์…‹ํŒ…ํ•˜์ž
self.velocity.x = 0
self.velocity.y = 0
self.velocity.z = 0

์‹œ๊ฐ„์ด ์ค‘์š”ํ•œ ์ผ๋ถ€ ํ”„๋กœ๊ทธ๋žจ์˜ ๊ฒฝ์šฐ๋Š” ๊ธฐ๋ณธ์ ์ธ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘ ๋ฐฉ์‹์ด ์ตœ์ ์˜ ๋ฐฉ๋ฒ•์ด ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๊ฒŒ์ž„์ด ๋ฒ„๋ฒ…์ธ๋‹ค๋ฉด collectgarbage() ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•ด Lua์˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘ ๋ฐฉ์‹์„ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‚ฎ์€ "step" ๊ฐ’์œผ๋กœ ๋งค ํ”„๋ ˆ์ž„ ๋งˆ๋‹ค ์งง์€ ์‹œ๊ฐ„์— ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์‹คํ–‰ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒŒ์ž„์ด๋‚˜ ์•ฑ์ด ์–ผ๋งˆ๋‚˜ ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋จน๊ณ  ์žˆ๋Š”์ง€ ์•Œ๊ธฐ ์œ„ํ•ด ํ˜„์žฌ ๊ฐ€๋น„์ง€์˜ ์–‘์„ ์•„๋ž˜ ๋ฐฉ๋ฒ•์œผ๋กœ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

print(collectgarbage("count") * 1024)

Best practices

์ผ๋ฐ˜์ ์ธ ๊ตฌํ˜„ ๋ฐ ์„ค๊ณ„์˜ ๊ณ ๋ ค์‚ฌํ•ญ์€ ๊ณต์œ ๋œ ๋™์ž‘(Behaviors)์„ ์œ„ํ•œ ์ฝ”๋“œ๋ฅผ ๊ตฌ์กฐํ™” ํ•˜๋Š”๋ฐ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์ ‘๊ทผ ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Behaviors in a module (๋ชจ๋“ˆ์—์„œ ๋™์ž‘์„ ์‚ฌ์šฉํ•˜๊ธฐ)

Module

๋ชจ๋“ˆ์—์„œ์˜ ์บก์Аํ™” ๋œ ๋™์ž‘์€ ๊ฐ๊ธฐ ๋‹ค๋ฅธ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ(GUI์Šคํฌ๋ฆฝํŠธ ํฌํ•จ) ๊ฐ„์— ์‰ฝ๊ฒŒ ์ฝ”๋“œ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค๋‹ˆ๋‹ค. ๋ชจ๋“ˆ์— ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์€ ์—„๊ฒฉํ•˜๊ฒŒ ๊ธฐ๋Šฅ์ ์ธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ์ด ์ผ๋ฐ˜์ ์ธ ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ์ €์žฅ๋œ ์ƒํƒœ ๋˜๋Š” ๋ถ€์ž‘์šฉ์ด ํ•„์ˆ˜์ ์ธ ๊ฒฝ์šฐ(๋˜๋Š” ๊น”๋”ํ•œ ์„ค๊ณ„๋ฅผ ์ด๋„๋Š” ๊ฒฝ์šฐ)๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ชจ๋“ˆ์—์„œ ๋‚ด๋ถ€ ์ƒํƒœ๊ฐ’์„ ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค๋ฉด ์ปดํฌ๋„ŒํŠธ๋“ค์€ Lua์ปจํ…์ŠคํŠธ๋ฅผ ๊ณต์œ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ์•„๋‘๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๊ฒƒ์€ ๋ชจ๋“ˆ์— ๊ด€ํ•œ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ  ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋˜ํ•œ, ๋ชจ๋“ˆ ์ฝ”๋“œ๊ฐ€ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ๋‚ด๋ถ€๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•˜๋”๋ผ๋„ ("self"๊ฐ’์„ ๋ชจ๋“ˆ ํ•จ์ˆ˜์— ์ „๋‹ฌํ•˜๋Š” ๋ฐฉ๋ฒ•์œผ๋กœ) ์ด ๋ฐฉ๋ฒ•์€ ๋„ˆ๋ฌด ๊ฐ•๋ ฅํ•œ ๊ฒฐํ•ฉ(coupling)์ด ๋˜๋ฏ€๋กœ ๊ถŒ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

A helper game object with encapsulated behavior (์บก์Аํ™”๋œ ๋™์ž‘์„ ํ—ฌํผ ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ)

Helper

Lua ๋ชจ๋“ˆ์— ์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ, ์Šคํฌ๋ฆฝํŠธ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์—๋„ ์Šคํฌ๋ฆฝํŠธ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐจ์ด์ ์€ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์— ์ถ”๊ฐ€๋œ๋‹ค๋Š” ๊ฒƒ๊ณผ ์ด๋Ÿด ๊ฒฝ์šฐ ๋ฉ”์„ธ์ง€ ์ „๋‹ฌ์„ ํ†ตํ•ด ์—„๊ฒฉํ•˜๊ฒŒ ํ†ต์‹ ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค.

Grouping game object with helper behavior object inside a collection (๋™์ž‘์„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ—ฌํผ ๊ฒŒ์ž„์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ปฌ๋ ‰์…˜์—์„œ ๊ทธ๋ฃนํ™”ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ)

Collection

์ด ์„ค๊ณ„๋ฐฉ๋ฒ•์—์„œ๋Š” ๋ฏธ๋ฆฌ ์ •์˜๋œ ์ด๋ฆ„์œผ๋กœ(์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ๋Œ€์ƒ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ์˜ ์ด๋ฆ„์„ ์ผ์น˜์‹œ์ผœ์•ผํ•จ) ํ˜น์€ go.property() URL์„ ํ†ตํ•ด ๋‹ค๋ฅธ ๋Œ€์ƒ์˜ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ์ž๋™์œผ๋กœ ์‹คํ–‰ํ•˜๋Š” ๋™์ž‘ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ(behavior game object)๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฐฉ์‹์˜ ์ด์ ์œผ๋กœ๋Š” ๋™์ž‘ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๋Œ€์ƒ ์˜ค๋ธŒ์ ํŠธ(target object)๊ฐ€ ํฌํ•จ๋œ ์ปฌ๋ ‰์…˜์— ๊ทธ๋ƒฅ ๋–จ๊ตฌ๊ธฐ๋งŒ ํ•˜๋ฉด ๋œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ์ฝ”๋“œ๊ฐ€ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค.

๋งŽ์€ ์ˆ˜์˜ ๊ฒŒ์ž„ ์˜ค๋ธŒ์ ํŠธ๋ฅผ ๊ด€๋ฆฌํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๋™์ž‘ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋ณต์ œ๋˜๊ณ  ๊ฐ ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋ชจํ•˜๋ฏ€๋กœ ์ด ์„ค๊ณ„๋Š” ๋ฐ”๋žŒ์ง ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.