Skip to content

Latest commit

 

History

42 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚀 우주탐험

종류 인원 플레이 허브

슬롯머신 로그라이크. 릴을 굴려 나온 심볼(elements)의 시너지로 산소를 만들고, 구역이 끝날 때 생명유지장치가 산소를 가져간다. 못 대면 표류 — 얼마나 멀리 갔나가 기록.

의존성 없음. index.html 하나 열면 끝.

open index.html

한눈에

종류 로그라이크 · 싱글
인원 1인
플레이 https://41ways.github.io/oxy-voyage/
로컬 실행 open index.html
한 줄 규칙 릴을 굴려 심볼 시너지로 산소를 만들고, 구역마다 생명유지장치에 산소를 바친다
허브 https://41ways.github.io/norara/

목차파일 · 심볼 추가하는 법 · 정족수 — 고점 덱의 진입장벽 · 사람과 봇을 나눠서 잰다 · 밸런스 (v0.7 · 900판) · 현재 상태 (v0.5)

파일

파일 하는 일
index.html 화면, 연출, 진행. 규칙은 안 들고 있음
engine.js 심볼 테이블 + 점수 판정 + 소모량 곡선. DOM 안 씀
sim/balance.js engine.js를 그대로 불러다 수천 판 돌리는 밸런스 시뮬레이터

게임과 시뮬레이터가 같은 engine.js를 쓴다. "돌려본 수치"와 "실제로 도는 게임"이 어긋날 수 없게 하려고 이렇게 나눴다.

node sim/balance.js 250

심볼 추가하는 법

engine.jsSYMBOLS에 항목 하나 붙이면 뽑기 목록·툴팁·화물칸에 자동으로 붙는다.

solar:{ e:'☀️', n:'태양광 패널', base:0, r:'common', d:'인접한 심볼이 서로 전부 다르면 +5',
  effect:function(c){ var a=c.adj(); if(!a.length) return;
    var ids={}, n=0;
    for(var i=0;i<a.length;i++){ var id=a[i].entry.id; if(!ids[id]){ ids[id]=1; n++; } }
    if(n===a.length) c.addSelf(5); } },

필드

  • e 이모지 / n 이름 / base 기본값 / r 등급(common uncommon rare legend) / d 설명
  • baseOf(entry) 기본값이 인스턴스마다 다를 때 (수경재배처럼 자라는 것)
  • badge(entry) 칸 좌상단에 띄울 짧은 글자 (남은 턴, 누적치)
  • costCut 화물칸에 들고만 있어도 구역 소모량이 깎임
  • sticky 정비로 버릴 때 이 확률로 안 떨어짐
  • noOffer 뽑기 목록에 안 뜸 (부화·변신으로만 얻는 것)

effect(c)에서 쓸 수 있는 것

호출 설명
c.self c.cells c.deck 지금 칸 / 판 전체 / 화물칸
c.adj(...ids) 인접 8칸 (id 주면 필터)
c.all/row/col(...ids) 판 전체 / 같은 행 / 같은 열
c.emptyAdj() 인접한 빈칸 수
c.addSelf(n) c.add(t,n) c.mul(t,m) 값 조작. mul은 한 칸당 스핀 1회만 먹음
c.kill(t) 파괴 (화물칸에서도 영구 제거)
c.morph(t,id) 다른 심볼로 변신
c.gain(n) 칸과 무관하게 산소 획득
c.spinMul(m) 이번 스핀 총합에 배수 (전체 천장 3배)
c.debt({mul,add}) 다음 구역 소모량에 빚을 남김
c.deckAdd(id) 화물칸에 심볼 추가
c.link(t) 연출용으로 칸을 묶음 (조회 계열은 자동)
c.rand() c.note(msg) 난수, 항해일지 한 줄

조회 계열이 돌려준 칸과 add/mul/kill의 대상은 자동으로 연출 링크에 묶인다. 단 값이 실제로 움직였을 때만 확정된다 — 조회만 하고 조건이 안 맞아 아무 일도 안 일어난 칸까지 빛나면 왜 빛나는지 알 수가 없어서.

효과는 왼쪽 위 칸부터 순서대로 실행된다. 그래서 먼저 죽으면 효과를 못 쓴다.

정족수 — 고점 덱의 진입장벽

고점을 노리는 심볼은 화물칸에 일정 장수가 모여야 제 값이 나온다. 그 전엔 있으나 마나여서, "센 거 서너 개만 얹어놓고 안정형으로 가기"가 손해가 된다. 안정형은 안정형대로, 고점 덱은 한 축에 몰빵해야 성립한다.

심볼 등급 정족수 (안정 축 수준) 완성 (고점이 뚫림)
🌌 웜홀 희귀 6장 → 2.2% 11장 → 6%
☢️ 반응로 희귀 5장 → 인접 2배 9장 → 2배 +9씩
🧠 AI 코어 전설 3장 → 인접당 +5 5장 → +14
🩸 비상 배급 전설 3장 → +400 5장 → +1100
⚛️ 임계 반응 전설 2장 → 2배 4장 → 3배
🦑 우주 크라켄 전설 2장 → 기본값 3배 4장 → 6배
🗝️ 마스터 코드 전설 2장 → 전부 개방 4장 → 개당 140
✨ 초공간 정렬 전설 2장 → 순도 +4 4장 → +7
🌈 스펙트럼 전설 2장 → 12종 4장 → 9종

정족수는 등급별로 한 판에 실제 몇 장이 손에 들어오는지에 맞췄다. 처음엔 전설에 611장을 걸었는데, 전설은 아무리 모아도 35장이라 도달 자체가 불가능한 벽이었다.

사람과 봇을 나눠서 잰다

시뮬레이터가 셋이다. 셋이 재는 게 다르다.

파일 두는 방식 재는 것
sim/balance.js 고정 선호표 — 축 하나만 기계처럼 집음 축별 상한과 통과율
sim/strategist.js 전방탐색 — 후보를 실제로 6스핀 굴려보고 고름 최적에 가까운 플레이의 천장
sim/human.js 전방탐색 없음 — 카드를 읽고 어림으로 고름 실제로 사람이 얻는 점수

봇과 사람의 차이가 핵심이다. 봇은 당장의 기댓값을 정확히 재지만, 그래서 정족수 심볼을 영영 못 고른다 — 문턱을 넘기 전엔 눈앞의 값이 나쁘니까(국소 최적 함정). 사람은 정확히 못 재는 대신 카드에 적힌 문턱을 읽고 계획을 밀고 나간다. sim/human.js는 그 비대칭을 그대로 넣었다.

  • 전방탐색 없음. 기본값 · 짝이 덱에 있나 · 이미 몇 장 모았나로 어림
  • 설명에 세 자리 수가 보이면 과대평가한다 (성향에 따라 1.0 ~ 2.2배)
  • 마이너스 기본값을 꺼린다
  • 문턱이 적힌 카드는 한 장이라도 있으면 목표로 삼는다
  • 한 번 정한 축을 웬만해선 안 바꾼다 (구역마다 12%만 재고)
  • 같은 후보도 판단이 ±30% 흔들린다

밸런스 (v0.7 · 900판)

성향 중앙 구역 중앙 점수 상위 25% 상위 5% 최고 정족수 완성
🙂 안정 지향 10구역 3,308 4,180 5,043 9,240 5% 0%
🔥 고점 지향 10구역 3,513 4,831 8,441 216,168 2% 1%

평균은 사실상 동률인데 천장이 23배 갈린다. 안정 지향은 9,240에서 멈추고, 고점 지향은 정족수를 채운 판에서 216,168까지 간다.

봇(strategist.js)으로 재면 신중형 중앙 2,919 / 최고 161,198, 대깨형 중앙 2,234 / 상위 5% 124,087 — 중앙값은 신중이 높고 천장은 대깨가 5.7배다.

문턱 편향 — 계획이 계획이 되게 하는 값

판 하나가 40~50픽인데 특정 희귀는 그중 두세 번 뜨는 게 고작이다. 그대로 두면 정족수는 영영 못 넘는 벽이라, 화물칸에 쌓아둔 문턱 심볼은 훨씬 자주 나오게 했다.

가중치 = 등급 가중치 × (1 + 편향 × min(보유 장수, 7.5))
  일반 심볼   편향 0.4
  문턱 심볼   편향 5.0

1.2 / 2.5 / 4 / 5 / 7 을 재봤고 5.0을 골랐다 — 정족수 도달 11%, 완성 5%로 "드물지만 노려볼 만한" 선이 나온다. 더 낮추면 문턱이 장식이 되고, 더 올리면 누구나 완성해서 고점의 의미가 없어진다.

소모량 곡선은 손으로 안 정한다

"구역별 탈락률을 일정하게"는 소모량을 그 구역 정산 직전 산소 분포의 같은 백분위에 놓는 문제다. 소모량 = p15면 정확히 15%가 떨어진다. 남은 산소가 다음 구역으로 이월돼 자기참조라, 다섯 번 수렴시킨다.

node sim/fit-costs.js 15 220 5
구역 15 16 17 18 19 20 21 24 28
탈락률 16% 15% 14% 13% 16% 15% 14% 17% 21%

심볼을 늘리거나 선택지 수를 바꾸면 수입 분포가 통째로 바뀌므로 반드시 다시 맞춘다.

여기까지 오면서 잡은 것들

  • 비상 배급의 되먹임 — "이번 구역 소모량의 N%를 획득"으로 뒀더니 수입이 소모량과 같이 지수로 커져서 게임이 끝나질 않았다(41구역 상한 도달). 자기참조를 끊고 고정값으로.
  • 배수 겹침 — 반응로 ×2가 여러 장 겹치면 한 칸이 2ⁿ이 된다. 어떤 소모량 곡선으로도 못 막아서, 한 칸은 스핀당 한 번만 배수를 먹게 캡을 걸었다.
  • 희귀도 램프 상한 — 구역이 깊어질수록 희귀·전설이 잘 나오게 했는데, 상한이 없으면 후반 덱이 전부 희귀가 되어 복리가 안 멈춘다.
  • 조합이 성립할 확률 — 소각로·만능공구가 "인접"만 볼 땐 채택률이 0.4장이었다. 사거리를 넓히고 나서야 원형으로 굴러갔다.
  • 공짜로 커지는 심볼 — 미세 블랙홀이 인접 1개당 무조건 3을 빼고 6을 얻었다. 옆칸이 뭐든 +3이라 인접 수만 채우면 되는 구조. 기준을 대상의 기본값으로 바꿨다.
  • 판 밀도를 고려 안 한 페널티 — 곰팡이 기본값 8에 인접 −3을 걸었더니, 판 평균 인접이 3.4칸이라 실질 −2.2였다. 숫자만 보면 이득처럼 보이는데 실제론 손해.

순도 — 이 게임의 최고 고점

판에서 가장 많이 깔린 한 종류의 비율로 스핀 총합에 배수가 붙는다 (60% ×1.15 → 100% ×3.0). 통일 덱이 최고 고점이고, 동시에 곁가지 픽 하나하나에 눈에 보이는 대가가 붙는다. 통일을 실제로 도달 가능하게 만드는 두 심볼이 🧫 배양조(가장 많은 종류를 복제)와 🗑️ 폐기 슈트(소수파를 영구 폐기)다.

정반대 축도 있다 — 🔭 관측 망원경은 판의 종류 수로 값을 내고, 🌈 스펙트럼은 12가지 이상이면 총합을 2배로 만든다. 순도를 포기해야 성립한다.

현재 상태 (v0.5)

  • 심볼 59종 (흔함 17 / 보통 23 / 희귀 12 / 전설 7, 변신 전용 포함)
  • 스핀 5회 고정 · 선택지 4장 · 구역 30개 표 + 이후 1.25배씩
  • 계열: 순도 / 다양성 / 우주 동물(🐁🐈‍⬛🐕🐢) / 외계(🥚👾👽🦑) / 통신(📡📻📶🖥️) / 오염(🦠🔥🧰🧯) / 밀수(📦🛠️🪝🗝️) / 온실(🌱🌷🌸) / 광맥(💎⛏️🕳️) / 증폭(☢️🧊) / 저당(⚛️🩸🎫)
  • 아이템·유물 없음, 기록은 localStorage

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages