[ 2024.10.16 TIL ] Pangyo Night

박지영·2024년 10월 16일
0

Today I Learned

목록 보기
63/84
post-thumbnail

🎮 Pangyo Night

📃 프로젝트 정리

기술 스택

  • Node.js - Express

  • AWS RDS(MySQL) - Prisma ORM

  • Redis cloud - ioredis

  • Deployment - AWS EC2

  • PackageManager - Yarn

패킷 구조 및 핸들러 맵핑

pngwing com

API 명세서

pngwing com

컨셉

  • 판교의 등대 같은 불빛에 몰려드는 벌레 몬스터들을 타워(살충제)로 잡아낸다.

  • 야근을 방해하는 벌레로부터 등대를 지키는 컨셉

ERD

캡처

아트

  • 몬스터

  • 타워
    • 전기 살충제 - 밸런스 잡힌 기본 타워 / 1~3 레벨
  • 화염 살충제 - 공격 속도가 느리지만 강력한 타워 / 1~3 레벨
  • 화학 살충제 - 공격 속도가 빠르지만 약한 타워 / 1~3 레벨
  • 배경

시스템

  • 웨이브 레벨 상승
    1 ~ 7레벨 까지는 일정 점수를 달성할 때마다 상승하지만 7레벨 이후에는 50마리를 처치할 때 마다 레벨이 상승한다.

  • 타워 구매
    타워를 설치하고 싶은 곳을 클릭하고 원하는 타워를 선택하면 원하는 장소에 100골드를 소모해서 타워를 설치할 수 있다.

  • 타워 판매
    판매하고 싶은 타워를 클릭하면 판매 버튼이 활성화되고 판매를 누르면 타워를 판매해서 소모한 골드의 50%를 환급받을 수 있다.

  • 타워 업그레이드
    업그레이드하고 싶은 타워를 클릭하면 업그레이드 버튼이 활성화되고 업그레이드를 누르면 골드를 소모해 타워를 3레벨까지 업그레이드할 수 있다.
    1 -> 2레벨 75골드
    2 -> 3레벨 175골드

  • 슬로우 장판
    원하는 곳을 우클릭하면 100골드를 소모해서 몬스터의 이동속도를 50% 느려지게하는 장판을 5초간 생성한다. 5초의 재사용 대기시간을 가지고 있다.

📌 담당한 부분

게임

게임 시작 및 끝에 관한 함수를 구현했다.

  • 게임 시작
    유저의 초기 데이터를 Redis에 저장하고 클라이언트에 전달해서 게임 시작에 필요한 데이터를 관리한다.

  • 게임 끝
    유저의 게임이 끝났을 때 Redis에 저장된 정보를 바탕으로 유저의 점수를 검증하고 최고 기록일 경우 MySQL DB에 최고 기록 정보를 저장하고 최고 기록 달성 여부를 클라이언트로 전달한다.

Redis 설계

  • 유저 데이터
    keyprefix - user:uuid:game
    hash로 저장 /hset -> hgetall -> hget -> del
    보유 골드
    기지 체력
    점수
    초기 타워 갯수
    몬스터 레벨
    몬스터 스폰 간격
    각 항목을 hset 'key'로 업데이트

  • 웨이브
    keyprefix - waveLevel+uuid
    string으로 저장 / set -> get -> del
    유저의 현재 웨이브 레벨을 Int로 저장

  • 몬스터 처치 목록
    keyprefix - monster+uuid
    list로 저장 /rpush -> lrange -> del
    유저가 처치한 몬스터를 JSON 형태로 저장 (몬스터id, 레벨)

  • 설치한 타워
    keyprefix - tower+uuid
    list로 저장 /rpush -> lrange -> del
    유저가 설치한 타워를 JSON 형태로 저장 (id,towerId,x좌표,y좌표)

에러 처리 방식

서버 핸들러의 검증 중 예외 사항를 클라이언트로 반환하도록 구현.

검증 중 new Error로 에러를 발생시키면 서버가 꺼져버리는 현상이 있어서

상태 정보와 메시지를 클라이언트로 반환한다.

유저 데이터는 클라이언트에서 선처리가 이루어지지 않고

서버에서 검증 후 Redis의 유저 데이터에 반영하고

상태를 동기화하기 때문에 예외 사항이 발생하면 유저 데이터에 반영되지 않는다.

return { status: fail , type: type, message: 'message' }

상태 동기화 방식

유저 데이터의 변동이 생기는 이벤트가 생겼을 때

클라이언트에서 선반영 후 서버에 검증 요청을 보내는 방식이 아니라

서버에서 검증 후 검증이 통과되면 Redis의 유저 데이터에 반영하고

Redis의 유저 데이터를 클라이언트로 반환하는 방식으로 전체적인 상태 동기화 방식을 정했다.

랭킹 조회

DB에 저장된 Score를 내림차순으로 정렬한 후 조회하도록 했다.

랭킹 페이지를 따로 만들어서 fetch 함수로 랭킹API의 정보를 받아오고

한 페이지에 5명의 유저만 보여주도록 페이징 기능을 사용해서 구현했다.

📚 배운점

초기 기획을 확실하게 잡는 것도 중요하지만 흐름을 파악하는 것도 중요하다.

첫째날에 기획 회의가 길어져서 둘쨋날에 회의를 다시 시작했는데

우리 지금 기획도 중요한데 우리가 해야할 것에 대한 이유가 부족하다. 

또, 시간이 많이 없으니 할 수 있을지 없을지도 모르겠고 

코드의 흐름을 파악하고 자기 파트의 코드를 해석해보고 하면서 

추가적으로 기획을 추가 해나가는 방식이 나을 것 같다

는 의견이 많이 나왔다.

저번 프로젝트로 얻는 내 경험과는 상반된 의견이였는데

지금와서 보면 더 좋은 선택이 된 것 같다.

각자가 맡은 부분을 구현해나가면서 이해가 뒷받침되니까

추가하고 싶은 부분이 계속 생겼고 완성도를 높아지는 방향으로 갔다.

시간이 한정된 프로젝트에서는 이런 방식도 좋구나하는 좋은 경험이 되었다.

😭 아쉬웠던 부분

winston 등을 이용한 로깅과 jest 등을 활용한 테스트 코드도 작성해보고 싶었는데 못해본 부분이 아쉬웠다.

시간상의 문제도 있었고 jest에 대해서 아예 모르는 팀원들도 있었기 때문에

독단으로 의견을 피력하는 건 무리라고 생각해서 묻어두었다.

다음 프로젝트에서는 TS, 테스트 코드, 로깅 등도 활용할 수 있도록 노력해볼려고 한다.

profile
신입 개발자

0개의 댓글