Chain2D
서버 스크립트의 뿌리. `Chain2D` 자체에 게임 코드를 거는 자리는 두 곳입니다 — 채널이 사람을 받기 전에 한 번, 그리고 매 틱 한 번. 사람과 메시지에 거는 자리는 `Chain2D.Players` 와 `Chain2D.Network` 에 따로 있습니다. 이 둘은 한 번만 등록할 수 있고, 콜백 뒤에 붙은 인자는 조용히 버려지지 않고 거부됩니다.
Chain2D.onStart
Chain2D.onStart(callback: () -> ())| callback | () -> () | 시작할 때 한 번, 인자 없이 불립니다. 함수가 아니면 거부됩니다. |
채널이 사람을 받기 전에 한 번 불립니다. 이 콜백이 끝나야 런타임이 준비를 알리므로, 여기서 기다리는 동안에는 아무도 들어오지 못합니다. 여기서 난 오류는 삼켜지지 않습니다 — 준비를 알리지 않고 런타임이 그대로 멈춥니다. 두 번 등록하면 `Chain2D.onStart is already registered` 로 거부됩니다. 콜백 하나 말고는 아무것도 받지 않고, 뒤에 붙은 인자는 세어서 `Chain2D.onStart expects one function` 으로 거부합니다 — 조용히 버리면 창작자는 그 인자가 전달되었다고 믿게 되고, `Chain2D:onStart(fn)` 처럼 콜론으로 부른 것도 (`Chain2D` 가 첫 인자로 들어가) 같은 자리에서 같은 말로 걸립니다.
언제`main.luau` 를 읽는 동안에만. 등록 창은 `main.luau` 가 끝나는 순간 닫히고 곧바로 시작 콜백이 불리므로, 그 뒤에 부르면 `Chain2D.onStart must be registered while main.luau is loading` 으로 거부됩니다.
Chain2D.onStart(function()
Chain2D.Maps.load("town")
print("world server started")
end)Chain2D.onTick
Chain2D.onTick(callback: (deltaSeconds: number) -> ())| callback | (deltaSeconds: number) -> () | 매 틱 불립니다. `deltaSeconds` 는 늘 `0.05` 입니다 — 실제로 걸린 시간이 아니라 틱 간격 그 자체입니다. |
0.05초마다, 초당 20번 불립니다. 시뮬레이션의 박자가 아닙니다 — 움직임은 60Hz 로 판정되고 게임 코드는 20Hz 로 돕니다. 게임플레이에 그 이상은 필요 없고, 점프에 33ms 격자는 느껴지기 때문입니다. 채널이 늦어 틱을 놓치면 놓친 만큼 몰아서 부르지 않고 버립니다. 여기서 오래 걸리는 일을 하면 모두의 게임이 그만큼 늦습니다 — `task.wait` 도 마찬가지입니다. 이 콜백이 끝나야 시뮬레이션이 다음 걸음을 뗍니다. 콜백에서 난 오류는 채널을 멈춥니다. 두 번 등록하면 `Chain2D.onTick is already registered` 로 거부되고, 콜백 뒤에 붙은 인자는 `onStart` 와 같은 이유로 `Chain2D.onTick expects one function` 으로 거부됩니다. 등록 시점에는 제한이 없습니다 — `onStart` 와 달리 이것은 네이티브에 닿지 않고 프레임워크가 콜백을 들고 있을 뿐이라, `main.luau` 가 끝난 뒤에 등록해도 받아들여집니다.
local seconds = 0
Chain2D.onTick(function(deltaSeconds)
seconds += deltaSeconds
if seconds >= 1 then
seconds -= 1
Chain2D.Network.broadcast("count", { bodies = Chain2D.Map.bodyCount() })
end
end)Chain2D.runtimeVersion
Chain2D.runtimeVersion: string이 런타임의 판 번호. 지금은 `"0.1.0"` 입니다.
Chain2D.runtimeEngine
Chain2D.runtimeEngine: string스크립트를 돌리는 엔진의 이름과 판. 지금은 `"Lute 1.0.0"` 입니다.