파이썬을 이용한 게임 통계 서버는 주로 게임 내에서 발생하는 데이터를 수집하고 분석하여, 다양한 통계와 리포트를 제공하는 역할을 합니다. 이 서버는 실시간 데이터 처리가 중요한 경우도 있지만, 주로 비실시간으로 게임 데이터를 수집하여 후처리하는 구조로 구성됩니다.

게임 통계 서버의 기본 구조

  1. 데이터 수집 (Data Collection):

    • 게임 클라이언트 또는 서버에서 발생하는 이벤트 데이터를 수집하는 역할입니다.
    • 로그 파일, API 콜, 또는 메시지 큐 시스템(Kafka, RabbitMQ 등)을 통해 데이터를 수집할 수 있습니다.
    • 수집되는 데이터 예시:
      • 플레이어 로그인/로그아웃
      • 게임에서의 승리/패배 기록
      • 구매 이력 (in-app purchase)
      • 전투 통계 (공격 성공률, 방어 성공률, 획득 경험치 등)
  2. 데이터 저장 (Data Storage):

    • 수집된 데이터를 데이터베이스나 분산 스토리지 시스템에 저장합니다.
    • 일반적으로 관계형 데이터베이스(MySQL, PostgreSQL) 또는 NoSQL(MongoDB, Redis, Cassandra) 데이터베이스를 사용합니다.
    • 데이터 저장의 설계는 효율적인 조회와 분석을 염두에 두어야 하므로, 테이블 설계와 인덱싱이 중요합니다.
  3. 데이터 처리 (Data Processing):

    • 수집된 데이터를 처리하여 유의미한 통계 데이터를 생성하는 단계입니다.
    • 실시간 처리가 필요하다면 Spark Streaming, Flink와 같은 스트리밍 처리 엔진을 사용할 수 있습니다.
    • 비실시간 처리는 주로 일별/주별/월별 배치 작업으로 진행되며, Python의 스크립트를 사용하여 배치 프로세스를 구현할 수 있습니다.
    • 통계 처리 예시:
      • 특정 기간 동안의 유저 행동 분석 (DAU, MAU 등)
      • 각 플레이어의 게임 성과 평가 (승률, 평균 전투 시간 등)
      • 게임 경제 분석 (아이템 구매 패턴, 경제 밸런스 등)
  4. API 서버 (API Server):

    • 처리된 데이터를 외부에서 요청할 수 있도록 API 형태로 제공하는 서버입니다.
    • 예를 들어, 게임 클라이언트나 관리 페이지에서 특정 유저의 통계를 조회하는 요청이 들어오면, API 서버가 데이터베이스에서 해당 정보를 조회하여 응답합니다.
    • Flask, Django와 같은 웹 프레임워크를 이용해 RESTful API를 구현할 수 있습니다.
  5. 데이터 시각화 (Data Visualization):

    • 수집된 통계 데이터를 관리자나 운영자가 보기 쉽게 시각화하여 제공할 수 있습니다.
    • Python의 matplotlib, seaborn, plotly 등을 이용하여 그래프를 그리거나, Tableau, Grafana와 같은 별도 도구를 사용할 수 있습니다.

간단한 예시: Flask와 SQLite를 이용한 게임 통계 서버

다음은 간단한 Flask 서버와 SQLite 데이터베이스를 이용한 게임 통계 서버의 예시입니다.

1. 데이터베이스 설계 (SQLite)

CREATE TABLE players (
    id INTEGER PRIMARY KEY,
    username TEXT NOT NULL,
    wins INTEGER DEFAULT 0,
    losses INTEGER DEFAULT 0
);

CREATE TABLE matches (
    id INTEGER PRIMARY KEY,
    player_id INTEGER,
    result TEXT CHECK(result IN ('win', 'lose')),
    match_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY(player_id) REFERENCES players(id)
);

2. Flask 서버

from flask import Flask, request, jsonify
import sqlite3

app = Flask(__name__)

# 데이터베이스 연결 함수
def get_db():
    conn = sqlite3.connect('game_stats.db')
    conn.row_factory = sqlite3.Row
    return conn

# 플레이어 추가 API
@app.route('/players', methods=['POST'])
def add_player():
    username = request.json['username']
    conn = get_db()
    cursor = conn.cursor()
    cursor.execute("INSERT INTO players (username) VALUES (?)", (username,))
    conn.commit()
    return jsonify({"id": cursor.lastrowid, "username": username}), 201

# 매치 결과 기록 API
@app.route('/matches', methods=['POST'])
def add_match():
    player_id = request.json['player_id']
    result = request.json['result']

    conn = get_db()
    cursor = conn.cursor()

    # 매치 기록 추가
    cursor.execute("INSERT INTO matches (player_id, result) VALUES (?, ?)", (player_id, result))

    # 플레이어의 승/패 업데이트
    if result == 'win':
        cursor.execute("UPDATE players SET wins = wins + 1 WHERE id = ?", (player_id,))
    else:
        cursor.execute("UPDATE players SET losses = losses + 1 WHERE id = ?", (player_id,))

    conn.commit()
    return jsonify({"player_id": player_id, "result": result}), 201

# 특정 플레이어의 통계 조회 API
@app.route('/players/<int:player_id>', methods=['GET'])
def get_player_stats(player_id):
    conn = get_db()
    cursor = conn.cursor()
    cursor.execute("SELECT * FROM players WHERE id = ?", (player_id,))
    player = cursor.fetchone()

    if player:
        return jsonify({"id": player["id"], "username": player["username"], "wins": player["wins"], "losses": player["losses"]})
    else:
        return jsonify({"error": "Player not found"}), 404

if __name__ == '__main__':
    app.run(debug=True)

3. 실행 예시

  1. 플레이어 추가

    POST /players
    {
      "username": "player1"
    }

    응답:

    {
      "id": 1,
      "username": "player1"
    }
  2. 매치 결과 기록

    POST /matches
    {
      "player_id": 1,
      "result": "win"
    }

    응답:

    {
      "player_id": 1,
      "result": "win"
    }
  3. 플레이어 통계 조회

    GET /players/1

    응답:

    {
      "id": 1,
      "username": "player1",
      "wins": 1,
      "losses": 0
    }

확장 가능성

  1. 실시간 데이터 처리: Kafka나 RabbitMQ와 같은 메시지 큐 시스템을 도입해 대규모 게임에서 발생하는 실시간 이벤트를 처리할 수 있습니다.
  2. 데이터 분석 도구 통합: 수집된 데이터를 바탕으로 다양한 분석 도구(Spark, Hadoop 등)를 통해 더 복잡한 통계를 생성하고 예측 모델을 적용할 수 있습니다.
  3. 스케일링: API 서버는 Flask 대신 FastAPI를 사용하거나, 데이터베이스를 MySQL이나 PostgreSQL로 변경하고 클라우드 인프라를 통해 확장성을 개선할 수 있습니다.

이런 게임 통계 서버 구조는 유저 행동 분석, 비즈니스 의사결정에 중요한 정보를 제공하는 데 필수적입니다.

+ Recent posts