9P by GN⁺ 15일전 | ★ favorite | 댓글 3개
  • 누구나 동시에 조작할 수 있는 백만 개의 체스보드를 제공하는 실험적 웹사이트 One Million Chessboards
  • 한 사람이 말을 움직이면 모든 사용자에게 실시간 반영되며, 턴 없이 자유롭게 보드 간 이동도 가능
  • 모든 체스판 상태는 64밀리언 uint64로 구성된 2차원 메모리 배열로 저장되며, 서버는 단 하나임
  • Go 언어로 작성된 첫 프로젝트이며, WebSocket 기반의 zstd 압축된 Protobuf 메시지로 동기화가 이루어짐
  • 낙관적 적용 + 롤백 방식의 클라이언트 로직 구현에만 일주일이 소요될 만큼 기술적으로 도전적인 프로젝트였음

One Million Chessboards

  • One Million Chessboards백만 개의 체스보드를 제공하고, 누구나 동시에 말을 움직일 수 있음
  • 턴 기반이 아님, 한 사람이 말을 움직이면 모든 사용자에게 즉시 반영
  • 보드 간 이동도 자유롭게 가능하며, 전례 없는 체험을 제공함

배경

  • 이전에 만든 One Million Checkboxes 프로젝트에 이은 실험적 작품으로, 더 큰 규모와 도전 과제를 목표로 함
  • 제작자는 이 프로젝트에 많은 시간을 투자했으며, 재미있게 즐겨주길 바람

기술적 구현 방식

  • 이 프로젝트는 최근 작업한 것 중 가장 기술적으로 도전적인 작업이었음
  • 주요 기술 개요:
    • 확장성 고려한 설계
    • 단일 서버에서 구동
    • 전체 체스보드를 메모리 내 2차원 uint64 배열로 구성 (총 64밀리언 셀)
    • Go 언어로 작성된 백엔드, 제작자의 첫 Go 프로젝트
    • 단일 writer 스레드 + 다수의 reader 스레드, mutex로 접근 제어
    • 클라이언트는 낙관적 업데이트 적용, 서버로부터 충돌 업데이트가 오면 롤백 처리
    • zstd 압축된 protobuf 메시지를 WebSocket으로 클라이언트에 전송
    • 클라이언트는 50x50 존으로 구분, 인접 존의 움직임만 수신
    • 전역 데이터(통계, 미니맵 등)는 HTTP GET으로 폴링, Cloudflare 캐시 활용

클라이언트 동작 방식의 핵심

  • 낙관적 적용 + 롤백 방식(optimistic update with rollback) 은 약 1,600줄 코드로 구성, 7일간 전념하여 개발

    “최근 들어 가장 어렵게 싸운 문제였음”

출시 후 반응

  • 출시 8시간 만에 130만 건 이상의 말 이동 기록, 동시 사용자 약 400명
  • 서버의 부하는 무시할 수준으로 낮음

현재 통계

  • 온라인 플레이어 수 : 199,276명
  • 총 움직임: 5,238,978회
  • 말의 총 수: 1,490,061,914개
  • 킹의 수: 9,035,389개

조금만 사이즈를 줄였으면 어땠을까... 누군가를 만날 확률이 너무 적어요 ㅋㅋ ㅠㅠ

테스트 해봤는데 현재 테이블을 벗어나서 흑 기준으로 아래 체스판으로 넘어갈 수 있는 부분이 흥미롭네요.

Hacker News 의견
  • 안녕하세요! 제가 만들었음. 블로그 설명이 부족해서 미안함. 아키텍처에 대한 질문이 있으면 기쁘게 답변하겠음. 이 프로젝트를 단일 프로세스로 수천 명의 동시 클라이언트를 처리할 수 있도록 만드는 데 몰두했음. golang이 이 작업에 잘 맞았음

  • 이 게임이 흥미로워졌음. 예를 들어, 사람들이 외곽 가장자리를 두 칸 깊이로 채운 단일 보드가 무적임을 알아냈음. emergent gameplay를 보는 것이 좋음. eieio의 프로젝트의 천재성임. 겉으로는 단순해 보이지만 대규모로 흥미로운 가능성을 발견하게 됨

  • 누군가 왕을 약 40개의 룩으로 막았음. 내가 나이트로 들어갔더니 즉시 왕으로 나를 잡고 다른 룩으로 틈을 막았음. 재미있었음

  • 보드 간 이동은 가능하지만 캡처는 불가능함. 이상한 점은 이동이 투영되지 않는 것이 아님. 예를 들어, 퀸의 파란 선은 보드 경계를 넘어 정확히 가리키지만 다른 보드의 모든 조각에서 멈춤. 규모의 연습으로 잘했음

  • 오류가 발생했음. Uncaught TypeError: null의 속성을 읽을 수 없음

  • 각 보드에 "턴"이 있을 줄 알았음. 무작위 보드를 선택하고 검은 퀸을 해방시켜 상대가 아무것도 하지 못하는 동안 모든 흰색 조각을 정리할 수 있을 줄은 몰랐음

  • 다른 색으로 플레이하는 치터가 있음. 어제 본 것 같았지만 오늘 확실히 봤음. 복수심에 사용된 것 같음. 검은 요새가 파괴되자마자 가장 가까운 흰색 요새의 조각들이 최악의 위치로 이동했음

  • 이것이 봇 전쟁으로 발전할 것이라고 예측함. 예를 들어, 폰을 전진시키는 코드 조각이 있음

  • 사람들을 쫓아다니는 것이 매우 재미있음. 체스 때문이 아니더라도 즐거움

  • Android 폰에서 Firefox로 잘 작동함. 잘했음