본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 28. 06:48

Vanilla JS로 구현한 1980년대 메인프레임 슬롯머신: RNG 수학, Web Audio 및 CLI 통합

요약

Vanilla JavaScript를 사용하여 외부 라이브러리 없이 1980년대 메인프레임 스타일의 슬롯머신 에뮬레이터를 구현한 프로젝트입니다. RNG 수학 엔진, Web Audio를 활용한 절차적 사운드 합성, 그리고 CLI 기반의 시각적 아키텍처 설계 과정을 다룹니다.

핵심 포인트

  • 외부 의존성 없는 순수 Vanilla JS 기반 개발
  • 가중치 기반의 카지노 수학 엔진 구현
  • Web Audio를 이용한 레트로 사운드 합성
  • 모노스페이스 타이포그래피를 활용한 터미널 UI

안녕하세요, 제 이름은 Donovan Lafferty입니다. 저의 최신 프로젝트 쇼케이스를 위해, 저는 빈티지 컴퓨팅 미학의 엄격한 제약 조건과 현대적인 브라우저 네이티브 엔지니어링을 결합한 무언가를 만들고 싶었습니다.

그 결과물은 1980년대 초반 마이크로컴퓨터 텍스트 터미널의 외형, 느낌, 그리고 소리를 모방하도록 설계된 완전 기능의 텍스트 기반 도트 매트릭스 (dot-matrix) 슬롯머신 에뮬레이터입니다. Vanilla JavaScript (ES6+), HTML5, 그리고 Tailwind CSS를 사용하여 완전히 처음부터 구축되었으며, 이 프로젝트는 외부 게임 엔진, 라이브러리 또는 의존성(dependencies) 없이 완전히 작동합니다.

이 빌드 로그에서는 핵심 소프트웨어 아키텍처(architecture), 변동성(volatility)을 구동하는 카지노 수학 엔진, 그리고 절차적 레트로 사운드 합성(procedural retro sound synthesis)에 어떻게 접근했는지 자세히 설명하겠습니다.

👉 YouTube에서 전체 게임플레이 시연 보기: https://youtu.be/OWGsAOXGGtE
👉 브라우저에서 즉시 라이브 빌드 플레이하기: https://silver-nadia-34.tiiny.site

1. 시각적 아키텍처: 고대비 모노스페이스 스타일링

순수한 레트로 엔지니어링 미학을 확립하기 위해, 저는 클래식한 아날로그 질감이나 시뮬레이션된 CRT 스캔라인 필터를 우회했습니다. 대신, 레이아웃은 평면적이고 픽셀이 선명한 단색 디스플레이에 최적화된, 매우 날카로운 고해상도(high-DPI) 커스텀 모노스페이스(monospace) 타이포그래피(Fira Mono 서체 활용)를 우선시합니다.

터미널 섀시(chassis) 선택을 통해 사용자는 클래식 하드웨어 프로필을 즉석에서 전환할 수 있습니다:

  • *P1 Phosphor Green *(클래식 터미널 VFD 스타일)
  • VT100 Amber Plasma (DEC 플라즈마 에뮬레이션)
  • Teletype Paper White (초기 종이 터미널 출력)
  • Lab VFD Cobalt (컴팩트한 실험실 진공 형광 스타일)

평면적인 텍스트 공간 내에서 당첨 조합을 시각적으로 눈에 띄게 만들기 위해, 엔진은 당첨 페이라인(payline) 벡터 좌표를 매핑하고 동기화된 반전 색상 깜빡임 사이클(.win-blink)을 VT100 그리드 셀에 직접 주입합니다.

2. 카지노 수학 엔진: 변동성 튜닝 및 적중 빈도

진정한 느낌을 주는 슬롯머신을 설계하려면 균등한 무작위성 (Uniform Randomness)을 넘어서야 합니다. 만약 모든 심볼이 모든 릴에서 나타날 확률이 동일하다면, 그 게임은 실제 카지노 경험을 재현하는 데 실패하게 됩니다.

가상 릴 스트립 및 심볼 가중치 (Virtual Reel Strips & Symbol Weighting)
수학 엔진은 고밀도의 가중치 시뮬레이션 배열을 활용합니다. 각 가상 릴 스트립은 다양한 빈도(가중치)로 정의된 커스텀 심볼 객체들의 배열입니다. 낮은 등급의 심볼은 라인 적중을 일정하게 유지하기 위해 빈번하게 나타나는 반면, 높은 등급의 심볼은 의도적으로 희귀하게 배치됩니다:

  • [7] LUCKY SEVEN (잭팟 배수: 120x) — 가중치: 2
  • [@] MONITOR (배수: 45x) — 가중치: 3
  • [$] CORE (배수: 20x) — 가중치: 4
  • [♣] CLOVER (배수: 10x) — 가중치: 4
  • [▲] SHIELD (배수: 5x) — 가중치: 5
  • [≈] COMMS (배수: 2x) — 가중치: 6
  • [?] PORT (스캐터/와일드 유틸리티) — 가중치: 1

수학적 밸런싱 (Math Balancing)
표준 플레이에서 각 스트립은 정확히 1개의 스캐터 포트 (Scatter Port)를 포함한 25개의 심볼로 구성됩니다. 단일 열의 가시적인 3개 행 중 어디에든 스캐터가 착륙할 확률 ($p$)은 정확히 $\frac{3}{25} = 12.0%$입니다.

이것을 이항 분포 (Binomial Distribution)를 사용하여 5릴 매트릭스 전체에 매핑하면, 보너스 트리거 확률은 약 1.43%로 계산됩니다. 이는 플레이어가 약 70번의 스핀마다 한 번꼴로 메인 보너스 시퀀스를 경험하게 된다는 것을 의미합니다. 이는 매우 몰입감 있는 표준 플레이 루프를 생성합니다.

3. 고급 게임플레이 로직: 이중 유틸리티 스캐터 와일드 (Dual-Utility Scatter Wilds)

이 프로젝트에서 가장 복잡한 알고리즘 작업 중 하나는 **이중 유틸리티 스캐터 와일드 (Dual-Utility Scatter Wilds)**를 고려하면서 왼쪽에서 오른쪽으로 심볼을 처리할 수 있는 페이라인 점수 엔진을 설계하는 것이었습니다.

[?] 포트 심볼이 그리드에 착륙하면, 페이라인 평가기 (Payline Evaluator)는 두 단계의 체크를 실행합니다:

  1. Global Scatter Array Scan (글로벌 스캐터 배열 스캔): 5개 컬럼 전체에 걸쳐 [?] 심볼의 총 개수를 추적하여 보너스 게임 트리거 여부를 확인합니다.
  2. Wild Substitution Algorithm (와일드 대체 알고리즘): 활성화된 페이라인 (Payline) 상에서 [?] 심볼을 와일드 (Wild)로 취급합니다. 평가기 (Evaluator)는 경로 상의 첫 번째 비-와일드 (non-wild) 심볼을 찾기 위해 배열을 동적으로 검색하여 당첨 타겟 유형을 설정하며, 라인이 일반 심볼과 스캐터 (Scatter)가 혼합되어 있더라도 페이아웃 (Payout)을 매끄럽게 계산합니다.

또한, 가장 높은 배당을 제공하는 심볼을 위해 특별히 **2-of-a-Kind Momentum Mechanic (2개 일치 모멘텀 메커니즘)**을 하드코딩했습니다. 활성화된 페이라인에 연속된 [7] 심볼이 단 2개만 착륙하거나 ([7]과 와일드 [?]의 조합 포함), 라인 배팅액의 15배라는 흥미로운 페이백 (Payback)을 제공하여 아쉬운 결과에서도 플레이어에게 보상을 보장합니다.

  1. "Core Intrusion" 보너스 루프 및 화면 축소 전환 (Screen-Collapse Transition)

3, 4 또는 5개의 스캐터 (Scatter)가 착륙하면 **Core Intrusion Free Spins Mode (코어 인트루전 프리 스핀 모드)**가 활성화되며, 각각 **8회, 12회 또는 20회의 프리 스핀 (Free Spins)**이 부여됩니다.

영화 같은 경험을 극대화하기 위해, 게임은 사용자 입력을 일시 중지하고 자동화된 터미널 컷신 (Cutscene)을 실행합니다. 화면은 경고를 의미하는 붉은색 비상 인터페이스로 다시 열리기 전, 극적인 "CRT 전원 종료" 스타일의 수평 축소 애니메이션을 거칩니다.

// 자동화된 컷신 스테이징 살펴보기
function executeTransitionCutscene(onMidpoint, onComplete) {
  const shutter = document.getElementById('crt-shutter');
...

이 프리 스핀 루프 동안에는 변동성 (Volatility)을 극대화하기 위해 수학적 구조가 완전히 변경됩니다:

  • 배당이 낮은 심볼 (SHIELDCOMMS)은 릴 (Reel)에서 완전히 제거됩니다.
  • 잭팟 심볼인 LUCKY SEVEN의 출현 빈도 가중치가 두 배로 증가합니다.
  • 릴 스트립 (Reel strip)이 단 16개의 심볼로 축소되어, 리트리거 (Retrigger) 확률이 **4.87% (약 20.5회 스핀당 1회)**까지 상승합니다. 보너스 도중 3, 4 또는 5개의 스캐터가 착륙하면, 자동 게임 진행을 멈추지 않고 플레이어의 남은 총 횟수에 +5, +10 또는 +15회의 추가 스핀을 깔끔하게 쌓아줍니다.

5. Web Audio API를 통한 절차적 오디오 합성 (Procedural Audio Synthesis)

게임을 진정으로 가볍고 단일 파일 내에 완전히 독립적으로 유지하기 위해, 외부 .mp3 또는 .wav 사운드 샘플을 로드하는 것을 거부했습니다. 대신, 전체 사운드스케이프(Soundscape)는 브라우저의 네이티브 Web Audio API를 사용하여 실시간으로 합성(Synthetically generated)됩니다.

커스텀 오실레이터 체인(Oscillator chains)과 지수적 이득 엔벨로프 감쇠(Exponential gain envelope decays)를 구축함으로써, 게임은 빈티지 하드웨어 구성 요소를 모방합니다:

  • 기계식 키 입력 (Mechanical Keystrokes): 고주파의 초단파 사인파 버스트 ($950\text{Hz} - 1200\text{Hz}$ 동안 $0.012$초).
  • 텔레타입 릴레이 및 릴 잠금 (Teletype Relays & Reel Locks): 물리적인 스테퍼 모터(Stepper motors)가 제자리에 클릭되며 맞물리는 소리를 모방한 짧고 선명한 톱니파(Sawtooth waves).
  • 잭팟 차임 (Jackpot Chimes): $1046\text{Hz}$까지 스케일링되는 순수 사인파 주파수의 폭포수 같은 음악적 아르페지오 배열.
  • 비상 사이렌 워블 (Emergency Siren Warbles): Core Intrusion 전환 중에 긴장감을 조성하기 위해 피치가 오르내리는 교차 저주파 톱니파 스윕(Sawtooth wave sweeps).
  1. 대화형 명령줄 인터페이스 (Interactive Command Line Interface (CLI))

제어 패널 브릿지는 물리적 버튼 레이아웃을 대화형 입력 터미널 채널에 직접 연결합니다. 사용자가 데크 인터페이스를 통해 활성 라인이나 베팅액을 변경하면, 자동 타이핑(Autotyping) 기능이 변경을 실행하기 전 실제 기계식 타이핑 사운드 효과와 함께 입력 필드 내에 원시 시스템 명령(예: THEME COBALT, BET +5, LINES 5)을 한 글자씩 타이핑합니다. 사용자는 또한 입력 바를 선택하여 이러한 진단 터미널 명령을 수동으로 입력할 수도 있습니다.

제 작업을 확인해 주셔서 감사합니다! 의사 난수 생성(Pseudo-RNG) 로직, Web Audio 아키텍처, 또는 Vanilla JS를 이용한 빈티지 인터페이스 복제에 대해 궁금한 점이 있다면 아래 댓글 섹션에서 이야기 나누어 봅시다.

Donovan Lafferty 개발.

커스텀 오실레이터 체인(Oscillator chains)과 지수적 이득 엔벨로프 감쇠(Exponential gain envelope decays)를 구축함으로써, 게임은 빈티지 하드웨어 구성 요소를 모방합니다:

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0