Skip to content

kms5064/DUCKTOPIA

Repository files navigation

DUCKTOPIA: The Mustard Wars

Game Intro

Image

Game introduction

DUCKTOPIA: The Mustard Wars는 2~8인 협동 생존 멀티게임입니다.
오리에게 점령당한 세상에서 마지막 희망인 허니머스타드 공장을 지키며, 오리 군단과 맞서 싸우는 게임입니다.

🦆 시나리오

어느 날, 정체불명의 생태계 변화가 일어났다.
오리들은 폭발적으로 증식했고, 빠르게 진화하며 이성을 갖추기 시작했다.
그들은 도시를 점령하고, 인간을 사냥하며, 세상을 덕토피아(DUCKTOPIA) 로 만들어갔다.
그들은 단순한 새가 아니다.
그들은 인간을 먹는다.
그들은 지구의 새로운 지배자다.

그러나, 인류에겐 단 하나의 희망이 남아 있었다.

과학자들은 허니머스타드가 오리들에게 치명적이라는 사실을 발견했다.
(아이러니하게도, 인간들은 오리를 먹을 때 항상 머스타드를 곁들였었지...)

하지만 오리들도 이를 눈치채고, 모든 허니머스타드 공장을 파괴했다.
이제 마지막 공장 단 하나만이 남았다.

이곳이 무너지면, 인류도 끝장이다.
마지막 허니머스타드 공장을 사수하라!
끝없이 몰려오는 오리들의 침공을 막아라!
오리냐, 인간이냐. 최후의 전쟁이 시작된다!

🎮 게임 진행

  1. 자원 수집과 사냥: 필드에서 오리 몬스터를 사냥하고, 아이템 상자를 열어 장비와 음식을 획득하세요. 외곽 필드의 풀에서는 귀중한 머스타드 씨앗을 찾을 수 있습니다.

  2. 아이템 조합과 강화: 수집한 장비 아이템을 조합해 확률적으로 새로운 아이템을 얻을 수 있습니다.

  3. 허니머스타드 제작: 오리 몬스터에서 얻은 계란 프라이 및 꿀 아이템과 머스타드 씨앗을 게임에서 중요한 요소인 허니머스타드를 제작하세요. 이것을 무기에 조합하면 오리 군단의 보스에게 치명적인 무기가 됩니다.

  4. 오리 웨이브: 밤이 되면 오리 웨이브가 발생합니다. 플레이어들은 협력하여 허니머스타드 공장을 지켜야 합니다. 웨이브는 시간이 지날수록 더 강력해집니다.

  5. 보스 전투: 충분한 준비가 되면, 허니머스타드를 조합한 무기로 오리 군단의 보스에게 도전하세요. 보스는 일반 무기로는 처치할 수 없으며, 오직 허니머스타드를 조합한 무기만이 효과적입니다!

🛠️ 게임 특징

  • 협동 생존: 2~8명의 플레이어가 함께 협력하여 생존하고 목표를 달성합니다. 혼자서는 버티기 힘든 위협에 맞서 팀워크를 발휘하세요.

  • 낮과 밤의 사이클: 낮에는 자원을 모으고 준비하는 시간, 밤에는 오리 군단의 공격을 방어하는 시간으로 게임 사이클이 진행됩니다.

  • 아이템 제작 시스템: 다양한 재료를 조합하여 무기, 방어구, 소모품을 제작하고 강화할 수 있습니다. 특히 허니머스타드 조합은 게임의 핵심 요소입니다.

  • 전략적 방어: 제한된 자원으로 효율적인 방어 전략을 수립해야 합니다. 팀원들과 역할을 분담하여 공장 방어, 자원 수집, 아이템 제작 등을 효율적으로 진행하세요.

  • 진화하는 위협: 시간이 지날수록 오리 몬스터들은 더 강력해지고 다양해집니다. 계속해서 장비를 강화하고 전략을 발전시켜야 합니다.

🏆 승리 조건

오리 군단의 최종 보스를 물리치고 인류의 자유를 되찾는 것이 최종 목표입니다. 이를 위해서는:

  1. 충분한 자원을 모아 허니머스타드를 제작해야 합니다.
  2. 허니머스타드를 무기에 조합하여 강력한 무기를 만들어야 합니다.
  3. 팀원들과 협력하여 보스 몬스터를 처치해야 합니다.

Teammates

이름 MBTI 블로그 주소 Github 주소
김제훈 (Leader) INTJ 블로그 GitHub
오누리 (Sub Leader) INTP 블로그 GitHub
이준성 INFP 블로그 GitHub
한윤재 ISTP 블로그 GitHub
이이삭 ISTP 블로그 GitHub
이유민 INFJ 블로그 GitHub
조용필 INTP 블로그 GitHub
김의중 ISFP 블로그 GitHub

Technology Stack

Language

  • Javascript
  • C#

Backend

  • Node.js

Database

  • MySQL
  • Redis

DevOps & Cloud

  • AWS
  • Docker

Tools

  • Git
  • Notion

Game Engine

  • Unity

Service Architecture

Image

Gateway Server

1rc_gateway
├─ classes
│  ├─ server
│  │  ├─ server.class.js
│  │  └─ serverSession.class.js
│  └─ user
│     ├─ user.class.js
│     └─ userSession.class.js
├─ config
│  ├─ config.js
│  └─ constants
│     ├─ env.js
│     ├─ header.js
│     └─ server.js
├─ db
│  ├─ database.js
│  ├─ migrations
│  │  └─ createSchemas.js
│  ├─ redis
│  │  ├─ redis.js
│  │  └─ subscribe
│  │     ├─ connectServer.js
│  │     ├─ updateInGame.js
│  │     └─ userOut.js
│  ├─ sql
│  │  └─ user.db.sql
│  └─ user
│     ├─ user.db.js
│     └─ user.queries.js
├─ events
│  ├─ game
│  │  ├─ onGameConnection.js
│  │  ├─ onGameData.js
│  │  ├─ onGameEnd.js
│  │  └─ onGameError.js
│  ├─ lobby
│  │  ├─ onLobbyConnection.js
│  │  ├─ onLobbyData.js
│  │  ├─ onLobbyEnd.js
│  │  └─ onLobbyError.js
│  ├─ onConnection.js
│  ├─ onData.js
│  ├─ onEnd.js
│  └─ onError.js
├─ handlers
│  ├─ index.js
│  ├─ server
│  │  ├─ gameStart.handler.js
│  │  ├─ latencyCheck.handler.js
│  │  ├─ onGameServer.handler.js
│  │  └─ onLobbyServer.handler.js
│  └─ user
│     ├─ signIn.handler.js
│     └─ signUp.handler.js
├─ init
│  ├─ initServer.js
│  ├─ loadProtos.js
│  └─ serverOnRedis.js
├─ protobuf
│  ├─ main.proto
│  └─ packetNames.js
├─ server.js
├─ sessions
│  └─ session.js
└─ utils
   ├─ dateFormatter.js
   ├─ error
   │  ├─ customError.js
   │  └─ errorHandler.js
   └─ packet
      ├─ makePacket.js
      └─ makeServerPacket.js

Description

  • 로그인/회원가입 기능
    • 설명
  • 게임 서버가 여러개일 경우 로드 벨런싱 후 연결
    • 설명
  • 클라이언트와 다른 서버들(Lobby Server, Game Server)간의 연결을 총괄
    • 설명

Handlers

  • gameStart.handler
    • Lobby 서버에서 게임시작 요청 패킷을 받으면, Game 서버들의 부하(진행중인 게임 수)를 확인하여
      부하가 가장 적은 서버로 게임 정보를 전달해주는 역할
  • latencyCheck.handler
    • 디버깅용 핸들러로 Gateway에서 다른 서버간 지연시간을 측정하는 용도로 사용
  • onGameServer.handler
    • 클라이언트의 패킷 중 Game 서버와 관련된 경우, User의 상태를 확인(게임 진행중) 후
      패킷을 지정된 Game 서버로 보내주는 역할
  • onLobbyServer.handler
    • 클라이언트의 패킷 중 Lobby 서버와 관련된 경우, User의 상태를 확인(게임 진행X) 후
      패킷을 Lobby 서버로 보내주는 역할
  • signIn.handler
    • 로그인 핸들러
    • 사용자가 입력한 정보를 토대로 DB에서 회원 존재 여부를 확인하고 비밀번호를 확인하고 로그인. 로그인한 유저 세션에 추가
    • 중복 로그인은 userSession에서 체크 만약 중복이면 로그인 불가
  • signUp.handler
    • 회원가입 핸들러
    • 유저가 입력한 닉네임,이메일,패스워드가 유효한 양식인지 검사하고 유효하다면 비밀번호는 암호화해서 유저정보 저장

Lobby Server

2.src_lobby
├─ classes
│  ├─ room
│  │  ├─ room.class.js
│  │  └─ roomSession.class.js
│  └─ user
│     ├─ user.class.js
│     └─ userSession.class.js
├─ config
│  ├─ config.js
│  └─ constants
│     ├─ character.js
│     ├─ core.js
│     ├─ env.js
│     ├─ game.js
│     ├─ header.js
│     ├─ map.js
│     ├─ monster.js
│     └─ player.js
├─ db
│  └─ redis
│     ├─ redis.js
│     └─ subscribe
│        ├─ deleteRoom.js
│        └─ healthCheck.js
├─ events
│  ├─ onConnection.js
│  ├─ onData.js
│  ├─ onEnd.js
│  └─ onError.js
├─ handlers
│  ├─ game
│  │  ├─ deleteRoom.handler.js
│  │  └─ gamePrepareReq.handler.js
│  ├─ index.js
│  ├─ room
│  │  ├─ createRoom.handler.js
│  │  ├─ getRoomList.handler.js
│  │  ├─ joinRoom.handler.js
│  │  └─ leaveRoom.handler.js
│  ├─ server
│  │  └─ latencyCheck.handler.js
│  └─ user
│     ├─ loginCast.handler.js
│     └─ logoutCast.handler.js
├─ init
│  ├─ initServer.js
│  ├─ loadProtos.js
│  └─ serverOnRedis.js
├─ protobuf
│  ├─ main.proto
│  └─ packetNames.js
├─ server.js
├─ sessions
│  └─ session.js
└─ utils
   ├─ calculate.js
   ├─ dateFormatter.js
   ├─ error
   │  ├─ customError.js
   │  └─ errorHandler.js
   └─ packet
      └─ makePacket.js

Description

  • 방 생성/삭제 및 참여를 총괄
    • 설명

Handlers

  • gamePrepareReq.handler
    • 방의 호스트(방장)가 게임 시작을 클릭하였을 때, 게임 시작에 필요한 정보를 게임서버에 전달해주는 역할
  • createRoom.handler
    • 방만드는 핸들러
    • 방이름 유효성을 검사하고 로그인된 유저가 맞는지 검증. roomSession에 room클래스 추가하고 그 room안에 유저(방장)추가
  • getRoomList.handler
    • 방목록 조회 핸들러
    • 존재하는 방목록 조회해서 response
  • joinRoom.handler
    • 방에 참가하는 핸들러
    • 방과 유저가 유효한지 검사하고 방 정원이 가득찼는지 검사. 참가가 가능하다면 해당 유저의 참가를 참가중인 인원에게 notifi
  • leaveRoom.handler
    • 방을 떠나는 핸들러
    • 방과 유저가 유효한지 검사하고 유저가 방장인지 확인. 방장이라면 room도 같이 삭제하고 아니라면 떠났다는 사실 notifi
  • latencyCheck.handler
    • 디버깅에 사용되는 핸들러로, Gateway 서버에서 지연시간확인을 위한 패킷을 보내면 이를 다시 돌려주는 역할
  • loginCast.handler
    • Gateway 서버에서 로그인된 유저를 Lobby 서버에 접속시켜주기 위함
  • logoutCast.handler
    • Gateway 서버에서 로그아웃 및 접속종료한 유저를 Lobby 서버에 동기화 시켜주는 역할

Game Server

3.src_game
├─ classes
│  ├─ base
│  │  ├─ destructibleObjectBase.class.js
│  │  ├─ destructibleObjectBase.class2.js
│  │  └─ movableObjectBase.class.js
│  ├─ core
│  │  └─ core.class.js
│  ├─ game
│  │  ├─ bossMonster.class.js
│  │  ├─ game.class.js
│  │  ├─ gameSession.class.js
│  │  ├─ monster.class.js
│  │  └─ player.class.js
│  ├─ item
│  │  ├─ item.class.js
│  │  ├─ itemBox.class.js
│  │  └─ itemManager.class.js
│  ├─ object
│  │  ├─ grass.class.js
│  │  └─ wall.class.js
│  ├─ server
│  │  └─ serverSession.class.js
│  └─ user
│     ├─ user.class.js
│     └─ userSession.class.js
├─ config
│  ├─ config.js
│  └─ constants
│     ├─ character.js
│     ├─ core.js
│     ├─ env.js
│     ├─ game.js
│     ├─ header.js
│     ├─ item.js
│     ├─ map.js
│     ├─ monster.js
│     ├─ objects.js
│     └─ player.js
├─ db
│  ├─ database.js
│  └─ redis
│     ├─ redis.js
│     └─ subscribe
│        └─ healthCheck.js
├─ events
│  ├─ onConnection.js
│  ├─ onData.js
│  ├─ onEnd.js
│  └─ onError.js
├─ handlers
│  ├─ game
│  │  ├─ chatting.handler.js
│  │  ├─ createGame.handler.js
│  │  ├─ startGame.handler.js
│  │  └─ waveStart.handler.js
│  ├─ index.js
│  ├─ item
│  │  ├─ closeBox.handler.js
│  │  ├─ equipmentUpgrade.handler.js
│  │  ├─ getItem.handler.js
│  │  ├─ openBox.handler.js
│  │  ├─ putAnItem.handler.js
│  │  └─ takeOutAnItem.handler.js
│  ├─ monster
│  │  ├─ monsterAttack.handler.js
│  │  └─ monsterMoveNotification.handler.js
│  ├─ object
│  │  ├─ objectAttackedByPlayer.handler.js
│  │  ├─ objectDamagedByMonster.handler.js
│  │  └─ objectMount.handler.js
│  ├─ player
│  │  ├─ attackPlayer.handler.js
│  │  ├─ attackPlayerMonster.handler.js
│  │  ├─ detachmentItem.handler.js
│  │  ├─ dropItem.handler.js
│  │  ├─ playerDamagedByMonster.js
│  │  ├─ updateLocation.handler.js
│  │  └─ useItem.handler.js
│  └─ server
│     ├─ latencyCheck.handler.js
│     └─ logoutCast.handler.js
├─ init
│  ├─ assets.js
│  ├─ initServer.js
│  ├─ loadProtos.js
│  └─ serverOnRedis.js
├─ protobuf
│  ├─ main.proto
│  └─ packetNames.js
├─ server.js
├─ sessions
│  └─ session.js
└─ utils
   ├─ calculate.js
   ├─ dateFormatter.js
   ├─ error
   │  ├─ customError.js
   │  └─ errorHandler.js
   └─ packet
      └─ makePacket.js
assets
├─ armor_accessory.json
├─ armor_bottom.json
├─ armor_helmet.json
├─ armor_shoes.json
├─ armor_top.json
├─ dropTable.json
├─ dropTable_ori.json
├─ etcObject.json
├─ food.json
├─ monster.json
├─ monster_ori.json
├─ objectDropTable.json
├─ objects.json
├─ profanity.json
├─ upgradeRate.json
└─ weapon.json

Description

  • 인게임 로직을 실질적으로 실행하는 서버
    • 설명
  • CPU 부하가 많을 것으로 예상되어 2개로 운영
    • 설명

Handlers

  • chatting.handler
    • 채팅 핸들러
    • 유저가 작성한 채팅을 검열하여 Notifi
  • createGame.handler
    • 게임 생성 핸들러 게임 시작 전 게임클래스를 생성하고 room에 있던 유저들을 추가해주고 몬스터와 오브젝트들을 생성하고 정보를 Notifi
  • startGame.handler
    • 게임 시작 핸들러
    • 게임을 시작하며 몬스터,오브젝트,유저인벤토리를 초기화해주고 게임정보를 Notifi하며 게임 시작
  • waveStart.handler
    • 웨이브 시작 핸들러
    • 호스트 클라이언트에서 몬스터들이 생성될 좌표 생성하고 서버로 전달. 받은 좌표들을 기반으로 웨이브 몬스터 생성하고 Notifi
  • openBox.handler
    • 아이템 상자를 여는 핸들러
    • 클라이언트로부터 Box의 Id를 받아서 찾고 보유한 아이템을 조회 후 서버가 notifi전송
    • itemBox클래스에 occupied속성을 추가해 한명만 열 수 있게 설정
  • closeBox.handler
    • 아이템 상자를 닫는 핸들러
    • 클라이언트로부터 Box의 Id를 받아서 찾고 어떤 상자를 닫은건지 동기화를 위한 boxId를 Notifi
    • occupied null로 초기화해서 점유중이지 않음을 표시
  • putAnItem.handler
    • 코어(머스타드 공장)과 아이템박스에 아이템 넣는 핸들러
    • 클라이언트로부터 어떤오브젝트를 열었는지 boxId,어떤 아이템인지 itemCode, 몇개인지 count를 받고 유저 인벤토리에서 해당 아이템을 count만큼 차감하고(보유한 갯수보다 count가 크다면 count를 보유한갯수로 변경하고 아이템 삭제) 아이템 상자에 추가
    • 코어라면 특정아이템만 넣을 수 있고 조합식이 완성되면 새 아이템 생성
  • takeOutAnItem.handler
    • 코어(머스타드 공장)과 아이템박스에서 아이템 꺼내는 핸들러
    • 클라이언트로부터 어떤오브젝트를 열었는지 boxId,어떤 아이템인지 itemCode, 몇개인지 count를 받고 박스 인벤토리에서 해당 아이템을 count만큼 추가하고(보유한 갯수보다 count가 크다면 count를 보유한갯수로 변경하고 아이템 삭제) 유저 인벤토리에 추가
  • equipmentUpgrade.handler
    • 장비 아이템 조합 및 강화를 처리하는 핸들러
    • 두 개의 아이템 코드를 받아 같은 종류의 장비인지 확인 후 조합 진행
    • 동일 등급 아이템 조합 시 한 단계 높은 등급의 아이템 생성 (최고 등급은 유지)
    • 다른 등급 아이템 조합 시 확률에 따라 상위 등급 또는 한 단계 높은 등급 생성
    • 특수 조합으로 허니머스타드와 무기 조합 시 머스타드 무기 생성 (보스 몬스터에게 효과적)
    • 조합 결과는 모든 플레이어에게 브로드캐스트
  • getItem.handler
    • 필드에 떨어진 아이템을 습득하는 핸들러
    • 클라이언트로부터 플레이어 위치와 ID를 받아 가장 가까운 아이템을 찾음
    • 아이템과 플레이어 간의 거리, 인벤토리 공간 여부 등을 검증한 후 습득 처리
    • 아이템 습득 성공 시 필드에서 아이템을 제거하고 모든 플레이어에게 알림 전송
  • monsterAttack.handler
    • 몬스터가 공격하는 핸들러(모션 동기화)
    • monsterId를 받고 그 몬스터가 공격했다는걸 Notifi
  • monsterMoveNotification.handler
    • 몬스터들의 위치정보를 받아서 game클래스의 monsterMoveQueue라는 대기열에 넣어서 한덩어리를 순차적으로 처리
  • objectAttackedByPlayer.handler
    • 파밍용 오브젝트(풀) 피격 핸들러
    • objectId를 받아서 어떤 오브젝트가 피격됐는지 확인하고 근접무기에만 데미지를 받도록 검증
    • 피격시마다 HP 업데이트 notifi 해주고 만약 부서졌을경우 아이템을 필드에 생성하고 아이템 생성notifi
  • objectDamagedByMonster.handler
    • 몬스터에게 적대적인 오브젝트(코어,방어벽) 피격 핸들러
    • objectId와 monsterId를 받아서 몬스터의 공격력만큼 오브젝트의 hp를 차감하고 nootifi
  • objectMount.handler
    • 오브젝트 설치하는 핸들러
    • itemCode와 position을 받아서 인벤토리에서 해당 아이템 차감하고 오브젝트 생성하고 notifi
  • attackPlayerMonster.handler
    • 플레이어가 몬스터를 공격하는 핸들러
    • 플레이어의 무기와 방어구 공격력을 계산하여 몬스터에게 데미지를 입힘
    • 몬스터가 사망하면 몬스터의 등급에 따라 아이템 드롭 처리
    • 드롭 아이템은 무기(10%), 방어구(20%), 음식(70%) 확률로 생성되며 몬스터 위치에 랜덤 오프셋을 추가하여 배치
    • 몬스터 등급에 따라 드롭 확률, 아이템 개수, 아이템 등급이 결정됨
    • 생성된 아이템은 필드에 드롭되고 모든 플레이어에게 아이템 생성 알림을 전송
  • detachmentItem.handler
    • 장착된 장비를 탈착하는 핸들러
    • itemCode를 받고 코드의 번호의 맨 앞자리로 부위를 판별해서 그 부위에 장착된 itemCode와 받은 itemCode가 일치하는지 검증하고 일치하면 유저의 장착장비속성을 null로 바꾸고 인벤토리에 아이템 추가
  • dropItem.handler
    • 플레이어가 인벤토리 아이템을 떨어뜨리는 핸들러
    • itemCode와 count를 받고 유저 인벤토리에 존재하는지 갯수는 충분한지 검증해서 인벤토리에서 아이템 갯수차감 or 삭제 후 필드에 아이템 생성
  • playerDamagedByMonster.handler
    • 플레이어 피격 핸들러
    • monsterId를 받고 그 몬스터의 공격력만큼 피해 입히고 Notifi
  • updateLocation.handler
    • 위치동기화 핸들러
    • 클라이언트에서 이동한 좌표를 전송하면 해당 플레이어 위치 같이 게임중인 모든 클라이언트에 Notifi
  • useItem.handler
    • 인벤토리의 아이템을 사용하는 핸들러
    • 아이템 코드를 기반으로 아이템 타입(음식, 무기, 방어구 등)을 판별
    • 음식 아이템은 허기와 체력을 회복시키고, 무기와 방어구는 장착 처리
    • 아이템 타입별로 다른 처리 로직을 적용하고 결과를 모든 플레이어에게 브로드캐스트

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors