CODE GALLERY No.18 / 株式会社ガチャ放題 提供(という設定)
ガチャ放題
お金も石もいらない。何回でも引ける。
出てくるのは、だいたい役に立たない36体。
ソシャゲのガチャは、引く前がいちばん楽しい。だったら、引く前の楽しさだけを無限に味わえばいい。
これは、無料で何度でも引けるソシャゲ風のガチャゲームです。日替わりのピックアップ、週替わりの期間限定、天井と交換所、ログインボーナスにミッション、推しがしゃべるホーム画面まで、ひととおりそろえました。そのかわり、出てくるのは洗濯機で相方を失った靴下や、押しても速くならない「閉」ボタン、本番環境の女神といった、ろくでもない面々です。
キャラはすべて、ブラウザの中でその場で組み立てる3Dのフィギュアです。下のボタンから、全画面で開いて遊べます。
- 3つのガチャ恒常・本日のピックアップ・週替わりの期間限定
- 天井と交換所200回で好きな注目キャラと交換
- 推しがしゃべるホームに3Dで立ち、タップでセリフ
- ログボ・ミッション毎日受け取れて、実績で称号がもらえる
HOW TO PLAY遊び方
- ホーム:推しのキャラが3Dで立っています。タップするとセリフを言います。完凸(同じキャラを6体集める)すると、4つ目のセリフが聞けます
- ガチャ:横にめくると、恒常・本日のピックアップ・期間限定の3つを選べます。10連は10枠目が SR 以上確定です
- 召喚:カプセルの色がレア度の目安です。途中で色が変わったら昇格、帯が画面を横切ったら UR 以上が確定しています。画面をタップすると早送り、SKIP で結果まで飛ばせます
- 図鑑:引いたキャラを3Dで回して見られます。ここで「推し」に設定すると、ホームに飾られます
- ミッション:毎日0時にリセットされるデイリーミッションと、達成すると称号がもらえる実績があります
- 記録はこのブラウザの中だけに保存され、どこにも送られません。石は無限なので、もらっても∞のままです
GACHA3つのガチャと天井
レア度ごとの提供割合は、どのガチャも同じです。N 50%・R 30%・SR 14%・SSR 5%・UR 0.9%・シークレット 0.1%。違うのは、その枠の中で誰が出やすいかです。
- ガチャ放題(恒常):通常の31体が均等に出ます。UR は2体なので、1体あたり0.45%です
- 本日のピックアップ:毎日0時に、SSR・UR から1体が選ばれます。UR なら UR 枠0.9%のうち0.6%を、SSR なら SSR 枠5%のうち2.5%を、その1体がひとりじめします
- 期間限定:月曜0時に、夏の「真夏の有給消化フェス」と冬の「年末年始の締切祭り」が入れ替わります。限定 UR は0.6%、限定 SSR は合わせて2%です。期間が終わると、次の週まで引けません
確率を上げても、200回引いて目当ての UR に会えない人が2〜3割残ります。そこで天井があります。ガチャごとに1回1ポイントがたまり、200ポイントで交換所が開いて、そのガチャのピックアップ・限定キャラを1体選んで受け取れます。運が悪くても、200回で必ず終わります。1回300円なら6万円。現実のガチャの天井も、だいたいこのくらいの金額に設定されています。
SOURCE CODE抽選のしくみ
抽選は、キャラごとの重みの表を作ってから1回で選びます。レア度の枠(合計10000)を、まずピックアップ・限定キャラが決まった割合だけ受け取り、残りを他のキャラで均等に分けます。重みを表にしておくと、提供割合の表示も同じ表から計算できるので、表示と実際の抽選がずれません。
const RARITY = [5000, 3000, 1400, 500, 90, 10]; // N R SR SSR UR シークレット(合計10000)
// キャラごとの重みの表。minTier 未満のレア度は出ない(10連の10枠目は SR 以上)
function table(banner, minTier = 0) {
const out = [];
RARITY.forEach((w, r) => {
if (r < minTier) return;
const all = poolOf(banner).filter(c => c.r === r);
const pu = all.filter(c => isPickup(banner, c));
const rest = all.filter(c => !isPickup(banner, c));
const share = pu.length ? pickupShare(banner, r) : 0; // 例:UR なら 60/90
pu.forEach(c => out.push({ c, w: w * share / pu.length }));
rest.forEach(c => out.push({ c, w: w * (1 - share) / rest.length }));
});
return out;
}
// 0以上1未満の乱数(Math.random より偏りの少ない暗号用の乱数)
function rand() {
const a = new Uint32Array(1);
crypto.getRandomValues(a);
return a[0] / 4294967296;
}
function pick(tb) {
const sum = tb.reduce((s, e) => s + e.w, 0);
let x = rand() * sum;
for (const e of tb) { if (x < e.w) return e.c; x -= e.w; }
}
公開する前に、それぞれのガチャを10万回ずつまわして、レア度別とピックアップ・限定キャラの出現率が、計算した提供割合と0.1%以内で一致することを確かめています。「その他」画面の「提供割合」には、ガチャごとの割合と、1体ずつの確率がすべて並びます。
フィギュアは three.js で、球・円柱・回転体・押し出した形を組み合わせて作っています。素材ごとに粗さ・透過・布や土の細かな凹凸を変え、撮影スタジオのような照明を映り込ませています。顔や文字は、2Dで描いた絵をフィギュアの表面に印刷するように貼っています。画像ファイルは1枚も使っていません。BGM と効果音も Web Audio API でその場で作っています。
※ 登場するキャラクターはすべて架空です。実在の会社員・課長・竜王・本番環境とは関係ありません。

