0. 최적화를 왜 해야 하나
당장 맵 제작을 멈추고 F3 + 2를 눌러 틱레이트를 확인해보셈!
(1) 틱레이트가 무엇인가
마인크래프트의 기본 틱 속도는 1초에 20틱임. 즉, 1틱이 50ms라는 거지
마인크래프트는 매 틱마다 다음 틱(50ms 후)의 상태를 예측하기 위해 시스템적으로 연산을 하게 되는데
이 연산 소요 시간이 50ms를 넘으면 안 된다
틱레이트가 50ms를 넘으면 정상적인 게임 작동이 불가능해짐
일단, 타이머가 의도대로 작동하지 않을 것임
게임 속도가 일정하지 않고 시스템의 연산 속도에 의존하게 되니
타이머의 1초가 현실의 1초가 되지도 않으며 일정하지도 않음
또한, 플레이어 등의 이동이 모두 부자연스러워지고 끊겨 보일 수도 있음
(2) 목표로 해야 할 수치
50ms는 마지노선일 뿐이며
평소에는 30 ~ 40선 밑으로 유지해주는 것이 좋음
만약 마붕이의 컴퓨터의 사양이 좋은 편이라면
컴퓨터 사양이 조금 안 좋은 유저들을 배려해 평소에는 10ms 밑으로,
맵 플레이 도중 틱레이트가 최대로 튀는 순간에도 30ms 밑으로 유지하는 것을 목표로 해줘라
(커맨드를 효율적으로 짠 웬만한 소규모 맵이면 대부분 5ms도 잘 안 나올 거임)
1. 커맨드 초보가 많이 하는 실수
(1) 명령어의 개수 =? 연산 횟수
이 부분은 커맨드 초보라면 가장 많이 모르고 넘어가는 실수인데,
하나의 명령어에도 여러 개의 맥락이 존재한다는 거임
다르게 말하면 명령어를 한번만 딱 입력하더라도
어떤 명령어인지에 따라 시스템적으로 하는 연산이 여러 개가 될 수도 있다는 뜻이지
예를 들어 다음과 같은 명령어를 실행했다고 보자
execute as @e run say hi
맵에 플레이어 1명, 마커 20개, 블록 디스플레이가 4개 존재한다고 가정해보자
그럼 모든 개체를 뜻하는 @e는 25개의 개체가 되겠지?
이 25개의 개체들이 say hi라는 명령어를 실행한다는 거임
즉, 이 명령어 하나에 실행되는 연산 횟수는 25번임
(2) 연산 횟수가 기하급수적으로 늘어날 수도 있는 표현
"execute as @e ..."를 하는 순간 연산 횟수가 n배가 되는 걸 봤지?
특히 조심해야 할 게 at @e와 같은 실수임
< at + 여러 개체 >를 하면 해당 실행자가 그 여러 개체들의 위치에서 모두 명령어를 실행하는 셈이 된다
즉, 같은 사람이 동시에 여러 위치를 옮겨다니면서 명령어를 실행했다고 보면 된다
그렇다면 execute as @e at @e run ...와 같은 명령어를 쓰면 어떻게 될까..?
25개의 개체가 각각 모두 25개의 위치에서 동시에 명령어를 실행하게 된다
즉, 1번 개체도 25번, 2번 개체도 25번, ... 25번 개체도 25개의 위치에서 25번의 명령어를 실행하니
총 연산 횟수는 25 * 25 = 625가 되지
즉, 이 명령어 하나에 실행되는 연산 횟수는 625번임. (n^2)
30개의 개체가 있었으면 900번을,
40개의 개체가 있었으면 무려 1600번의 연산을 해야 함!!
그러니까 < as + 여러 개체 > 구조 다음에 < at + 여러 개체 >가 뒤따르는 구조는 굉장히 경계해야겠지
(3) @s를 적극 사용하자!
모든 플레이어가 자기 자신 아래에 있는 블록을 감지할 때와 같은 상황에서는 < as @a at @s >와 같은 구조를 사용하도록 하자
execute as @a at @s < 블록 감지 > run < 실행할 명령어 >
@s는 명령어의 실행자를 나타내는 표현으로 @s 자체는 단일 개체임
@s는 as로 실행자가 지정이 됐을 때 빛을 발하는 존재임
단, 모든 플레이어 위로 불똥을 튀는 연출을 할 때와 같은 상황에서는 execute as @a at @s로 명령어를 시작하기보다는 execute at @a로 실행자의 변경 없이 바로 실행 위치만 지정해서
시스템이 해야 할 연산의 복잡도를 살짝 줄여줄 수는 있음 (물론 as @a at @s 해도 큰 차이는 없음)
execute at @a run <연출 명령어>
(4) 그렇다고 at @s를 습관적으로 남용하면 안 된다
스코어보드 계산이나 데이터 수정을 할 때는 실행 위치가 필요 없으니 at @s는 빼주자
예를 들어 모든 플레이어가 자기 자신의 a의 점수를 자기 자신의 b의 점수만큼 더할 때와 같은 상황에서는
다음과 같이 명령어를 작성해줄 수 있음
execute as @a run scoreboard players operation @s a += @s b
물론 as @a 없이 명령어를 작성할 수 있으면 굳이 as @a 구문으로 연산을 불필요하게 늘리지 말자
모든 플레이어의 a의 점수를 1만큼 올릴 때와 같은 상황에서는 다음과 같이 작성해줘라
scoreboard players add @a a 1
#이건 진짜 최적화 망함 (실행 결과 또한 달라질 수도 있음)
execute as @a run scoreboard players add @a a 1
#나쁘지 않지만 더 개선 가능
execute as @a run scoreboard players add @s a 1
2. 방대한 규모의 맵을 만들 때
맵의 규모가 방대해지면 방대해질수록 최적화 작업이 절실해짐
(1) 불필요한 커맨드는 꺼둘 것
예를 들어, 다른 마을로 넘어갈 때는 이전 마을에서 작동했던 연출 커맨드를 끄고
꺼져 있었던 넘어간 마을의 연출 커맨드를 켜줘라
예를 들어, 5초마다 어떤 마을에서 밀이 1개씩 생산된다고 가정해보자
그 마을에 있을 때만 밀이 생산되는 모습을 보여주고
유저가 그 마을에 없을 때는 그냥 몇 틱이 흘렀는지 카운팅만 해주자
그리고 그 카운팅 된 틱을 기준으로 그 마을에 입장하는 순간에만 한꺼번에 연산을 해서 생산된 밀을 보여주는 거임!
#항상 작동하는 커맨드
scoreboard players add <밀 생산 사이클>
#해당 마을에 있을 때만 발동되는 커맨드
execute if <해당 마을에 있음> if <밀 생산 사이클 도달> run function <생산된 밀 개수 계산 & 관련 연출 커맨드>
(2) 데이터팩을 적극 활용하자
데이터팩을 사용하면 명령어 관리가 편함
일단 실수로 커맨드 블록을 깨부술 일도 없지
맵이 잘못해서 깨져도 아예 파일 자체가 통재로 날아간 것이 아닌 이상
명령어를 적어놓은 메모장 같은 것만 남아있다면 다시 맵을 파서 팩은 적용만 하면 되지
그 외 추가적인 장점에 대해서는 더이상 설명하기는 귀찮으니 아래 게시물을 참고하기를...
(할 말은 많지만 하지 않겠다)
https://gall.dcinside.com/minecraft/80680
20.09.5.23 무현이스킨을 않끼면 벤입니다
gall.dcinside.com
(3) 극한의 최적화가 필요할 경우 커맨드 블록을 쓰긴 해야 함
비유 아닌 비유를 하자면 "바로 옆에서 가져오는 것"이 된다
물론 데이터팩의 압도적인 장점이 있으니 반복적으로 실행되는 부분이 아닌
순간적으로 실행되는 부분은 데이터팩으로 처리하고 나머지는 function을 쓰지 말고,
포도와 상추 블록으로 쭉 이어붙이는 것이 더 빠름
물론 플탐이 50~100시간씩 걸리거나 엄청나게 복잡한 시스템을 적용한 초초초초초대규모 맵이 아니고서야
이 정도로 최적화를 해야 하는 상황이 올 일은 없음
그러니 안심하고 데이터팩을 쓰셈
3. 최적화는 갓맵의 필수 조건
맞음
다른 갓맵 조건들이 궁금하다면 다음 게시글을 확인해줘라!
https://gall.dcinside.com/minecraft/179665

지난번에 한 수능 파쿠르 시즌 3를 기억하는지?나름 퀄리티도 챙기고 재밌게 만든다고 이것저것 기믹도 넣어보면서 만든 건데생각보다 마플이 생방송에서 너무 말 없이 해가지고 쎄한 느낌을 받았었음어떻게 재밌었다고는 말했지만
gall.dcinside.com
댓글 0