Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

150 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C++ Real-time Multiplayer Game Server

C++23 기반 실시간 멀티플레이어 게임 서버 프로젝트입니다. Linux epoll, non-blocking socket, eventfd를 사용해 TCP 클라이언트 연결을 처리하고, 로그인, 세션, 패킷 파싱, 룸, 채팅, ready/start 흐름을 구현합니다.

현재는 RoomStatus::Playing 전환 시 GameManager가 game instance를 생성하고, 서버 event loop에서 고정 주기로 movement, attack, snapshot, game-ended 흐름을 처리합니다.

Goals

  • C++ 기반 TCP 서버 구현
  • Linux epoll 기반 이벤트 처리
  • non-blocking socket 통신
  • 클라이언트 세션 관리
  • 패킷 구조 설계, 파싱, 직렬화
  • 로그인 및 인증 처리
  • 게임 룸 생성 / 목록 / 입장 / 퇴장
  • 룸 owner, ready, start 상태 관리
  • 룸 단위 채팅 브로드캐스트
  • Tick 기반 게임 상태 업데이트
  • Docker 기반 빌드 및 실행 환경 구성

Current Progress

  • Dockerfile 및 Docker Compose 구성
  • CMake 빌드 구성
  • 설정 파일 로딩 구조 구현
  • epoll 기반 non-blocking TCP 서버 구현
  • eventfd 기반 서버 wakeup/shutdown 처리
  • 클라이언트 세션 관리 및 cleanup 처리
  • 패킷 파서 / 직렬화 구현
  • 로그인 및 인증 처리 구현
  • 게임 룸 생성 / 목록 / 입장 / 퇴장 구현
  • 룸 owner / ready / start 상태 구현
  • 룸 단위 채팅 구현
  • 로컬 테스트용 test-client 구현
  • Tick 기반 게임 루프 구현
  • GameManager 및 게임 인스턴스 구현
  • 이동 / 충돌 / 공격 / HP / 게임 종료 흐름 구현
  • 자동화 테스트 작성
  • 인증 정보 저장 방식 개선

Tech Stack

  • Language: C++23
  • Build: CMake
  • Network: POSIX Socket, epoll, eventfd
  • Platform: Linux / Ubuntu 24.04
  • Environment: Docker, Docker Compose

Project Structure

game-server/
├── config/
│   └── config.ini                  # server host, port, max clients, buffer size
├── src/
│   ├── auth/                       # login request/response protocol and auth result
│   ├── chat/                       # chat payload protocol
│   ├── config/                     # config file parser
│   ├── game/                       # game state, movement protocol, and game manager
│   ├── networks/                   # packet, parser, serializer, session
│   ├── rooms/                      # room state, room manager, room protocol
│   ├── users/                      # in-memory user manager
│   ├── utils/                      # utility functions
│   ├── Server.cpp                  # epoll TCP server
│   ├── Server.hpp
│   └── main.cpp
├── tools/
│   └── TestClient.cpp              # local interactive test client
├── CMakeLists.txt
├── Dockerfile                      # multi-stage server image build
├── docker-compose.yml
├── build.sh
└── README.md

Configuration

Server configuration is loaded from config/config.ini.

[server]
host=0.0.0.0
port=8080
max_clients=1024
buffer_size=4096
Key Description
host 서버가 바인딩할 IP 주소
port 서버가 수신 대기할 포트 번호
max_clients 동시에 연결할 수 있는 최대 클라이언트 수
buffer_size 클라이언트 recv 버퍼 크기

Build & Run

Local Build

cmake -S . -B build
cmake --build build --parallel

Run Server

./build/game-server

Run Test Client

./build/test-client 127.0.0.1 8080

Available test users are seeded at server startup:

Login ID Password Handle
test password tester
test2 password tester2
test3 password tester3
test4 password tester4

Example test-client flow:

login test password
create-room alpha 3
ready
start-game

Use another terminal for a second client:

login test2 password
list-rooms
join-room 1
ready
chat hello

Docker Compose

docker compose up --build
docker compose logs -f
docker compose down

The Dockerfile uses a multi-stage build. The runtime image includes only the game-server binary and config file; test-client is for local development builds.

Strict Warning Build

cmake -S . -B build-warnings -DCMAKE_CXX_FLAGS='-Wall -Wextra -Wpedantic -Wconversion'
cmake --build build-warnings --parallel

Test Client Commands

Command Description
ping [message] Send C2S_PING
login <id> <password> Authenticate session
create-room <name> <max_players> Create and enter a room
list-rooms Request lobby room list
join-room <room_id> Join a waiting room
leave-room Leave current room
ready Set ready state to true
unready Set ready state to false
start-game Owner starts the game when all players are ready
chat <message> Broadcast chat to players in the same room
move <dx> <dy> Send movement input (-1..1)
attack <target_user_id> Attack a nearby player
send <type> [payload] Send an arbitrary packet for manual testing
wait [ms] Pause scripted input

Packet Structure

All packet fields use network byte order.

Field Size Description
packet_size 2 bytes Total packet size, including header and payload
packet_type 2 bytes Packet type
sequence 4 bytes Request/response sequence number
payload variable Packet-specific data

The packet header is 8 bytes. Maximum packet size is limited to 16 KiB.

Implemented Protocols

Packet Payload
C2S_LOGIN [id_length:u16][password_length:u16][id][password]
S2C_LOGIN_RESULT [result:u16][user_id:u64][handle_length:u16][handle]
C2S_CREATE_ROOM [name_length:u16][max_players:u16][name]
C2S_JOIN_ROOM [room_id:u32]
C2S_LEAVE_ROOM empty
C2S_ROOM_LIST empty
S2C_ROOM_LIST [room_count:u16] rooms...
S2C_ROOM_STATE room id, status, owner id, room name, max players, players with ready state
C2S_SET_READY [ready:u8]
C2S_START_GAME empty
C2S_CHAT [message_length:u16][message]
S2C_CHAT [user_id:u64][handle_length:u16][handle][message_length:u16][message]
C2S_MOVE [dx:i16][dy:i16]
C2S_ATTACK [target_user_id:u64]
S2C_SNAPSHOT [room_id:u32][tick:u64][player_count:u16] players...
S2C_ATTACK [room_id:u32][tick:u64][attacker_user_id:u64][target_user_id:u64][result:u16][damage:u16][target_hp:u16]
S2C_GAME_ENDED [room_id:u32][tick:u64][winner_user_id:u64][reason:u16]

Current Limitations

  • User data is seeded in memory at server startup.
  • Passwords are currently compared as plain text and should be replaced with hashing.
  • Gameplay currently uses a simple fixed arena (-10..10), one queued move and one queued attack per player per tick, 25 damage per hit, and no cooldown or advanced skills yet.
  • Automated tests are not configured yet; use test-client and strict warning builds for smoke validation.

About

C++ Real-time Multiplayer Game Server

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages