2022. 7. 19. 00:57ㆍ해커톤, 개인 프로젝트/Nexon MOD 해커톤
멋쟁이사자처럼 X 넥슨 MOD Suppoters Hackathon Chapter 3주차 18일 회고
부족하지만 멋쟁이사자처럼 X 넥슨 MOD Suppoters Hackathon에 합격하게되어서 MOD를 먼저 사용해볼 수 있는 감사한 기회를 얻게 되었습니다...! 최선을 다해 공부하고, 리뷰하겠습니다! 부족한 글 보러 와주셔서 감사드립니다!
// 해당 글은 멋쟁이 사자처럼 공동 학습 교안을 바탕을 작성되었습니다.
오늘은 Chapter 7. 네트워크에 대해 공부하였다.
공부한 것을 나누며 이야기 하기 전에 앞서서 기본적인 단어 정리에 대해서 정리해보겠다.
클라이언트 : 접속된 각각의 유저 ex) MOD를 플레이 하는 유저
서버 : 클라이언트의 요청을 받는 서버 ex) MOD 서버
동기화 : 어느 한 쪽의 값이 달라졌을 때 양쪽의 값을 모두 바꾸는 행동을 취하는 것
단어 정리는 이쯤하고 MOD 네트워크 구조에 대해서 알아보도록 하자
MOD는 기본적으로 서버-클라이언트 모델을 지원하고 있다.
서버-클라이언트 모델에 대해서 자세히 이야기해보자면
서버-클라이언트 모델은 서버는 기본적으로 하나이고, 여러 클라이언트를 가지고 있다.
하나의 메이플 서버에 여러 유저가 동시접속하고 있는 것을 생각하면 이해하기 쉬울 것이다.
또한 서버에서 특정 Property 값을 바꾸면, 그 Property를 가지고 있는 클라이언트의 Property도 전부 값이 변한다.
그러나 클라이언트에서는 독자적으로 Property 값을 변경해도 다른 클라이언트나 서버에 영향을 미치지 않는다.
여기서 하나의 예시를 들어보자.
우리는 인기 많은 사냥터에 가서 사냥할 생각에 신나있었다.
그런데 맵에 도착해보니, 어느 유저가 해당 사냥터는 본인의 자리라고 말을 하는 것을 듣게 되었다.
화가난 우리는 상대방에게 그런게 어딨냐 했지만, 상대적으로 약한 우리는 그저 인기도를 내리고 도망가는 것 밖에 방법이 없었다.
그런데 인기도가 클라이언트 Property일 뿐이면, 우리가 내렸다 하더라도 서버의 Property에 영향을 끼치지 못하므로, 우리의 일격(?)은 물거품이 될 것이다.
그러나 인기도가 서버의 Property라면 우리의 공격은 성공적일 것이다.
위에서 배운 개념들을 더해 MOD의 핵심 네트워크 개념들을 더 배워보자
위에서 이야기 했듯이 서버에서는 특정 Property의 값을 바꾸면 갖고 있는 클라이언트의 Property 또한 전부 값이 변경되는 반면 클라이언트에서는 Property의 값을 바꿔도 서버의 Property에 영향을 미치지 않는다.
만약 인기도가 클라이언트 Property이고, 모든 유저가 상대방의 인기도를 동시에 내렸다고 해보자.
서버-클라이언트는 1:n 관계이기 때문에 서버는 펑 터져버리고 말 것 이다.
그렇기에 동기화는 서버 -> 클라이언트 단방향으로 진행된다.
MOD에서는 Property에 동기화 옵션을 설정할 수 있게 해준다.
이를 Property 실행제어라 말한다.
동기화 옵션은 아래와 같다.
- [Sync] : 동기화가 되는 property
- [None] : 동기화 되지 않는 Property
또한 Property의 타입들도 설정할 수 있는데, 일부 타입(any, table)은 동기화가 지원되지않는다.
또 MOD에서는 Function 실행 제어를 지원한다.
Function은 호출한 쪽이 서버인지 클라이언트인지에 따라 동작하는 공간이 다르다. 따라서 실행 제어를 통해 공간을 활성화 시켜주어야 한다.
공간을 활성화 해준다는 것은 해당 Function이 특정한 속성을 지니게 하는 것이다.
Function 공간 활성화 옵션은 아래와 같습니다.
- Client : 서버가 클라이언트의 함수를 호출하면 서버와 연결된 클라이언트들에게 함수 호출을 요청하고, 연결된 클라이언트들에 있는 함수가 실행된다.
- 호출시 클라이언트에서 실행된다.
- ClientOnly : 클라이언트에만 불릴 수 있으며 서버에서는 부를 수 없다.
- Server : 클라이언트 쪽에서 서버의 함수를 호출하면 서버 쪽에 신호를 보내 서버 안에서 함수가 실행되게 한다.
- 호출시 서버에서 실행된다.
- ServerOnly : 서버에만 불릴 수 있고, 클라이언트에서는 부를 수 없다. 대부분의 로직는 서버에서 서버 기준으로 짜게 된다. 즉, 로직은 주로 서버 위주의 행위를 많이 하게 됩니다.
- Multicast : 서버와 클라이언트 양쪽 모두 실행한다.
아래 코드는 위 공간 활성화 옵션들을 잘 설명해줄 수 있는 예시 코드이다.
MyFirstComponent {
Property:
Function:
void OnBeginPlay()
{
log("BEGIN PLAY")
wait(2)
self:Server() -- 1. 서버가 서버 메시지를 뿌립니다.
self:Client("HAHAHA") -- 2. 클라이언트에서 메시지를 뿌려달라고 요청 후 바로 다음을 실행합니다.
log("END")
void Client( string arg1 ) -- 3. 클라이언트에 도착하면 클라이언트가 메시지를 받은 순간 요청을 실행합니다.
{
log("CLIENT" .. arg1)
}
void Server()
{
log("SERVER")
}
}
위 코드의 프로세스를 따라가면서 이야기해보자
1. log("BEGIN PLAY")을 통해 "BEGIN PLAY"라는 문자열을 log에 출력한다.
2. wait(2)를 통해서 2초 후에 다음 명령어를 실행한다.
3. self:Server()를 통해 void Server() 함수를 호출한다.
- 서버( Server() )가 서버( Server 공간 활성화 옵션 )에 메세지를 뿌린다.
4. self:Client ( "문자열" )를 통해 void Client( string arg1 ) 함수를 호출한다.
- 클라이언트( Clien() )가 클라이언트( Clien 공간 활성화 옵션 )에 메세지를 뿌린다.
서버에서 요청했을 때 클라이언트까지 요청이 도달하는 시간이 서버가 다음 코드를 실행하는 시간보다 짧으면 클라이언트가 먼저 찍히게 된다. 즉, 요청이 클라이언트까지 도달하지 못했기 때문에 다음 코드인 end가 먼저 찍히고 클라이언트가 찍힌다.
*wait(2)을 써주지 않았을 때 CLIENT 뒤에 파라미터로 받은 문자열이 출력되지 않는 현상 발생하는 이유
답 : 서버에서 엔티티를 생성하고 클라이언트에도 엔티티가 생성되기까지 시간이 걸린다. 클라이언트에서 엔티티가 생성되는 도중에 서버에서 엔티티의 값을 넣어 전송하면 클라이언트에서 값을 받지 못하는 현상이 발생한다. 이를 타이밍 이슈라고 한다.
MOD는 Server only 에서 이야기 했듯이 MOD의 로직 대부분은 서버 기반으로 돌아가며,
서버에서 로직의 흐름을 관리하고 중간중간 변경된 사항을 각 클라이언트에 전달하는 시스템이다.
특정 클라이언트 안에서만 생성되는 엔티티의 대표적인 예시들
- UI
- 입력
- effect - effect의 경우 보통 서버로 제어하는데 특정 클라이언트에서만 연출하고 싶을 땐 로컬 엔티티를 사용한다.
- 최적화 - 서버에 엔티티가 너무 많을 때 비용 때문에 최적화 시 로컬 엔티티를 사용한다.
오늘도 부족하디 부족한 글 보느라 정말 감사하고, 제발 또 봤으면 좋겠다.
꼭 다시 놀러와주라!
'해커톤, 개인 프로젝트 > Nexon MOD 해커톤' 카테고리의 다른 글
멋쟁이사자처럼 X 넥슨 MOD Suppoters Hackathon Chapter 9~ 10 회고 (0) | 2022.07.20 |
---|---|
멋쟁이사자처럼 X 넥슨 MOD Suppoters Hackathon Chapter 8 회고 (0) | 2022.07.19 |
멋쟁이사자처럼 X 넥슨 MOD Suppoters Hackathon 공동 월드 회고 (0) | 2022.07.15 |
멋쟁이사자처럼 X 넥슨 MOD Suppoters Hackathon 워크 스페이스 회고 (0) | 2022.07.15 |
멋쟁이사자처럼 X 넥슨 MOD Suppoters Hackathon Chapter 6 회고 (0) | 2022.07.13 |