본문 바로가기
게임개발/NEXON PROJECT MOD

멋쟁이사자처럼 X 넥슨 MOD Supporters Hackathon 3주차 회고

by tripleup 2022. 7. 1.
728x90
반응형

[MOD 강좌 Chapter 6] 스크립트의 이해


 

기본적인 언어인 Luascript + mod의 추가적인 문법 결합

Create Component
Create EventType
Create ItemType
Create BTNodeType
Create Logic

Create Script

 

Create Script
변수
local number = 1
number = 10
반복문
for count = 1, 10, 1 do
	log(count)
end
합계 구하기
local sum = 0
for count = 1, 10, 1 do
	sum = sum + count
end
log(sum)
조건문
local sum = 0
for count = 1, 10, 1 do
	if count % 2 == 0 then
	sum = sum + count
    end
end

log(sum)

 

Create Logic

로직은 한 게임에서 하나만 존재 -> 별다른 설정 없이 지속적으로 사용

 

Create Component

Component는 생성 후 Entity에 해당컴포넌트를 추가해야 실행 됨 (Entity 별로 실행)

Function : 어떠한 기능들을 모아둔 것


[MOD 강좌 Chapter 7] 네트워크의 이해


MOD는 네트워킹 지원, 멀티플레이 지원 게임

MOD는 서버-클라이언트 모델 사용

 

서버와 클라이언트

클라이언트 : 게임을 플레이하는 유저들의 모바일이나 PC, 또는 해당 기기에사 개별적으로 돌아가는 프로그램

유저의 입력을 처리하거나, 서버가 보내온 정보를 내부적으로 처리하여 유저에게 가시적으로 출력하는 역할을 수행

서버 : 각 클라이언트에서 보내온 요청에 대한 응답을 주기도 하지만, 게임 진행에 대한 주요 기능과 시스템을 서버에 구축함으로써 모든 클라이언트가 동일한 진행 상황이 될 수 있도록 할 수 있음

서버와 클라이언트의 관계

서버 - 클라이언트 모델에서,

클라이언트는 다른 클라이언트와 통신하지 않으며, 오직 서버하고만 정보를 주고받음(단방향)

클라이언트는 유저의 입력을 받고, 입력된 내용에 따라 서버에게 정보를 요청하거나 현재 클라이언트의 상황을 서버에게 알림

특정 클라이언트로부터 정보를 받은 서버클라이언트에게 다시 정보를 보내주거나, 혹은 전송한 내용을 게임 진행 상황에 업데이트시키고, 업데이트된 내용을 다시 모든 클라이언트에게 전송함으로써 게임을 이용하는 모든 유저가 동일한 상황이 될 수 있도록 맞춰줌

서버 - 클라이언트 간 처리 구조는 제작자의 의도에 따라 자유롭게 설계할 수 있지만, 만일 클라이언트에서 모든 로직과 시스템을 구축하고, 서버는 동기화를 위한 통신용으로만 사용하도록 설계한다면 해킹에는 상당히 취약한 구조

 

ex) 캐릭터의 레벨업을 클라이언트에서 처리 후, 서버를 통해 다른 클라이언트에게 알린다고 가정

주요 로직을 클라이언트에서 처리할 때의 예

주요 로직을 개별 클라이언트에서 처리하고 서버는 처리된 결과를 받아 다른 클라이언트에게 전송만 하면 되기 때문에 서버의 부하를 줄일 순 있다. 하지만 유저가 본인의 클라이언트를 해킹한 결과를 서버에게 전송한다면, 다른 유저들도 이용하는 게임이 해킹으로 인해 망가지게 된다.


예를 들어 위의 예시에서 User A가 몬스터를 잡았을 때 경험치 획득량이 많아지도록 클라이언트를 조작한다면, 서버는 조작된 과정에 의한 결과만 받아들이게 되고, 결국 UserA의 플레이어가 순간적으로 빠르게 레벨업되었다는 정보를 모든 클라이언트에게 전달하게 될 것이다.


물론 이를 위해 서버에서 검증 로직을 따로 둘 수도 있겠지만, 그렇게 되면 결국 클라이언트와 서버 둘 다 같은 로직이 두 개 생기는 꼴이라 사실 효율적인 구조라 할 순 없다. 따라서 MOD에서는 게임의 전반적인 로직과 시스템을 서버에서 구현하고, 클라이언트는 유저의 입력을 받아 서버로 전달하거나, 게임 진행 상황을 내려받아 유저에게 전달하는 역할로 구조를 가져가는 것을 추천

 

서버는 게임의 전반적인 흐름을 가져가고, 클라이언트는 유저와 게임의 사이 중계자의 역할을 하는 것입니다.

 

이와 같은 구조로 레벨업 처리 과정을 변경한다면 다음과 같음

서버, 클라이언트에서의 프로퍼티와 함수

메이커에서 작성한 프로그램이 서버와 클라이언트에서 돌아가는 방식

- 제작자가 스크립트에서 선언한 프로퍼티와 함수는 별도의 설정을 하지 않는 한 기본적으로 서버와 클라이언트 두 개의 공간에 각각 독립적으로 생성

- 이름은 같지만 서로 다른 공간에 존재하기 때문에 별도의 프로퍼티 또는 함수라고 생각

기본적으로 함수의 호출과 프로퍼티의 값 참조 및 할당은 같은 공간 내에서만 이루어짐


예를 들어 A라는 프로퍼티에 값B라는 함수에서 할당한다 했을 때, 서버에 있는 함수 B가 호출되면 서버에 있는 프로퍼티 A에 값이 할당되지만, 클라이언트에 있는 프로퍼티 A에는 값이 할당되지 않음
반대의 경우도 마찬가지로 클라이언트의 함수 B를 호출하면 클라이언트에 있는 프로퍼티 A에는 값이 할당되지만, 서버에 있는 프로퍼티 A는 값이 할당되지 않음

함수간 호출에서,

 

A와 B라는 함수를 선언했다 가정했을 때, 클라이언트의 함수 A가 함수 B를 호출하면 클라이언트에 있는 함수 B만 호출되고 서버의 함수 B는 호출되지 않음

서버에서 선언된 것은 서버에서만, 그리고 클라이언트에서 선언한 것은 클라이언트에서만 돌아간다는 것

 

동기화와 실행제어

서버-클라이언트 간 여러 통신 방법 중 MOD에서는  데이터 또는 상태를 전달하는 방식인 동기화와 특정 상황에 발생해야 할 행위, 행동들을 전달하는 방식인 실행제어를 제공

 

동기화 : MOD에서는 서버와 클라이언트 별도 공간에 있는 프로퍼티 값의 동기화를 의미

어느 한쪽의 프로퍼티 값을 변경하면, 다른 한쪽은 동일한 값으로 자동으로 변경

서버와 클라이언트의 프로퍼티가 동일한 값이 될 수 있도록 별도의 처리를 하지 않아도, 자동으로 동기화가 이루어지기 때문에 제작자는 좀 더 편하게 서버와 클라이언트 간 통신을 구현 가능

 

컴포넌트의 기능과 특성에 따라 프로퍼티 동기화가 될 수도, 혹은 안 될 수 있음

 

주로 클라이언트에서만 작동하는 컴포넌트가 있다고 가정했을 때, 해당 컴포넌트는 서버로 데이터를 보낼 일이 없으니 프로퍼티는 동기화는 이루어지지 않음

스크립트 컴포넌트에서는 프로퍼티 동기화 설정이 가능하도록 기능을 제공 -> 제작자가 본인이 만든 컴포넌트의 기능과 특성, 또는 제작자의 스타일에 따라 동기화 가능 여부를 설정케 함으로써 불필요한 동작을 줄이고 효율적인 구조로 설계해 나갈 수 있게 함

일반적으로 동기화는

서버에서 클라이언트 단반향으로 진행

- 프로퍼티 A가 있을 때, 서버에서 특정 조건에 의해 프로퍼티 A에 어떤 값이 할당되면, 클라이언트에 있는 프로퍼티 A는 서버에서 할당된 동일한 값으로 맞춰지게 됨. 하지만 반대로 클라이언트의 프로퍼티 A에 값을 할당하면 서버의 프로퍼티 A에는 어떤 변화도 발생하지 않음.

- 이유 : 서버와 클라이언트는 일 대 일 관계가 아닌 일 대 다 관계이기 때문. 클라이언트 A와 클라이언트 B가 있을 때, 클라이언트의 프로퍼티 C를 클라이언트 A에서는 1로, 클라이언트 B에서는 2로 할당했다고 가정한다면 서버는 프로퍼티 C의 값을 어떤 클라이언트의 값과 맞춰야 할지 판단이 어려워짐

 

때에 따라 클라이언트에서 할당한 값을 서버로 동기화하는 경우도 있지만, 특수한 몇몇 컴포넌트를 제외하고는 서버와 클라이언트 간의 관계적 특성으로 인해 주로 서버에서 할당한 값을 클라이언트로 동기화가 이루어짐

 

실행제어 : 각 공간에 정의된 액션을 서로 요청하여 수행케 하는 

서버와 클라이언트 간 통신에는 데이터의 전달, 즉 동기화 외에도 공간에 정의된 "액션"을 요청하고 수행하는 과정도 필요

클라이언트가 유저의 입력을 받으면, 서버에게 "몬스터 공격"이라는  "액션"을 요청하게 되고, 서버는 클라이언트의 요청에 따라 "몬스터 공격"이라는 "액션"을 수행 -> 이것이 실행 제어

 

위에 말한 "액션"은 결국 스크립트에서는 "함수"라 할 수 있는데, 스크립트에서 각 함수의 설정을 어떻게 하느냐에 따라 클라이언트에서 서버로 수행을 요청할 수도 있고, 반대로 서버에서 클라이언트로 수행을 요청할 수도 있음


아래 상황을 예로 들면, 서버에 선언된 함수 B의 실행 공간을 클라이언트로 설정했다면, 함수 B는 서버 내 다른 함수에서 호출이 가능하지만, 클라이언트에서 실행되기 때문에 서버에서 호출할 수 있는 클라이언트 함수처럼 사용 가능.

 

MethodB의 실행 공간을 클라이언트, MethodC의 실행 공간을 서버로 설정했을 때의 요청과 수행

 

728x90
반응형

댓글