개발/소프트웨어 마에스트로

SWM에서 게임 개발로 살아남기(1. 개요)

잠수돌침대 2022. 11. 12. 13:37

해당 시리즈를 시작하기 앞서 본인은 블로그를 잘하는 편도 아니고, 한다 해도 관리를 꾸준하게 할 자신도 없다.

본인은 현재 과기부에서 주관하고 한국정보산업협회가 운영하는 소프트웨어 마에스트로(Software Mastro, 이하 SWM) 13기로 선발되어 팀장으로서 프로젝트를 진행하고 있는 개발자에 불과할 뿐.

 

SWM 많관부~아 정말 알찬 6개월이었다

 

현재 이 글을 쓰는 11월을 기준으로 프로젝트는 거의 마지막을 향해 달려가고 있고, 배포까지 완료된 상태이다.

 

https://alard.in/ 에서 다운로드 받을 수 있다(현재는 폐쇄)

 

본인은 해당 프로젝트의 전반적인 콘텐츠 기획 및 개발, 다시 말해 몇 가지의 미니 게임을 기획하고 개발하는 파트를 맡았다는 점을 짚으며 이 글을 읽어줬으면 좋겠다.

 

최종 평가를 앞두고 본인이 만든 미니 게임들에 어떤 이유와 철학이 담겨있고, 개발 의도는 어떠하였는지에 대한 명시를 할 필요성을 느꼈다. 이에 약 3~4일 동안 노션에 어떤 생각을 하며 게임을 만들게 되었는지에 대한 포트폴리오를 작성하였고, 이것이 다른 연수생/멘토/Expert에게 긍정적인 반응을 보여 블로그에도 시리즈물로 이식하기로 다짐하였다.

 

이 글을 읽고 '이런 곳에서 게임도 만들 수 있구나', 'SWM는 이런 곳이구나' 등을 느끼며 추후 이곳에 지원할 사람들에게 많은 도움이 되었으면 하는 차원에서 이 글을 작성해본다.


1. 개요

6개월동안 진행한 SW Maestro 13기의 프로젝트는 Alardin : 특정 시간에만 진행할 수 있는 기능성 게임 플랫폼이다.

이를 SW Maestro 기간 동안 구현하고자 하는 1차적인 목표이자, 알기 쉬운 나만의 용어로 변경하자면 아래와 같다고도 할 수 있을 것 같다.

친구와 함께 소통 중심의 미니 게임들을 진행하며 같이 일어나는 알람 애플리케이션

 

본인은 해당 프로젝트의 미니 게임 기획 및 제작을 맡았고, 프로젝트 기간 동안 총 멀티용 게임 5개, 싱글용 게임 2개를 제작하는 것을 목표로 두었다. 각 게임이 어떤 방식으로 작동하는지, 어떤 알고리즘을 사용하였는지 소개하고자 하는 시간을 가지고자 한다.

1. 프로젝트는 어떻게 진행이 되었는가? - 왜 Vanilla JS?

사진 : 중간 평가 자료 일부 캡쳐

팀원이 총 3명 존재하였기 때문에 각각에게 맞는 일을 찾아가는 것이 제1의 목표였다. 이에 파트를 Back-End(이하 BE), Front-End(이하 FE), Game Planning/Develop(이하 Game) 파트로 나누어 각각의 업무를 분담하는 방식을 채택하였다.

 

위의 사진은 파트별로 어떠한 소통 방식을 취하고 있는 것인지 보여준다. 본인은 가장 아래인 Game 파트를 맡은 것을 확인할 수 있는데, 이는 다시 말해 내가 담당하는 Game 파트와 BE 파트의 소통을 없애는(또는 최소화하는) 방향으로 시스템을 만든 것을 알 수 있다.

 

이러한 시스템을 구현해내기 위해 React-Native(이하 RN)로 동작되는 FE 내 WebView 형식으로 임베딩 되는 게임 형태가 필요했음을 깨달았다. 이는 자연스럽게 호환과 이식/여러 게임의 개발에 가장 큰 유리함을 가지고 있는 Vanilla JS로 게임을 만들기로 한 가장 큰 계기가 되었다.

2. RN과의 소통 방식 명시 - postMessage, Listener

앱 내의 소통을 위해서는 우선적으로 Game 파트와 FE 파트와의 조율이 우선적으로 필요했다. 이를 위한 소통 수단으로 RN 내 WebView에서 메시지를 보낼 수 있는 postMessage 함수를 주로 사용하기로 하였다.

💡 사용자 B의 정답 확인이 필요하다… 사용자 A야 이 정답을 체크해줘!
💡 게임이 끝났어! 해당 사용자의 게임을 끝내고 다른 사용자에게 게임이 끝났다고 알려줘!

위와 같은 명령을 송신하는 것을 postMessage

위와 같은 명령을 수신하는 것을 listener로 구현하는 것을 1차적 목표로 두었다.

 

이는 다시 말해 Game과 클라이언트 간의 소통은 PostMessage를 통해, 클라이언트 간 실시간 통신 위해(RTM 사용 타이밍) listener를 구현하였다는 말과도 같다.

 

기본적인 형태는 아래의 JS 코드와 같다.

// example code for postMessage below.
const toJSON = (messageType, text) => {
  return JSON.stringify({ type: messageType, message: text });
};

window.ReactNativeWebView.postMessage("OUTPUT_DATA", outputData); // Message about output datas
window.ReactNativeWebView.postMessage(toJSON("SEND_MESSAGE", {user: otherUser,text: "SUCCESS",}));
// Message about send message to other person.

// example code for game start listener below.
const listener = (event) => {
  const { message, type } = JSON.parse(event.data);
	if (type === "GAME_START") {
    // Op here for Game Start
  }
};

const listenToRN = () => {
  if (window.ReactNativeWebView) {
    document.addEventListener("message", listener); // Android Deivce Listener
    window.addEventListener("message", listener); // iOS Deivce Listener
  } else {
    //console.log("Not React Native WebView");
  }
};

postMessage로 보내는 모든 message는(위의 예시에서는 outputData) 해당 메시지 타입과 함께 객체 형태를 RN에게 보내게 된다. RN에서는 메시지 타입을 보고 게임을 끝낼 것인지, 단순 메시지를 보낼 것인지에 대한 정보를 파악하게 된다.

 

위의 과정 동안 RN의 판단을 통해 처리되고자 하는 객체는 다시 적합한 형태로 가공되거나, 다른 유저에게 그대로 전달되는 방식으로 소통을 하게 되는 것이다.