▍AI Dev Lab
RuneCast

RuneCast ができるまで — Elder Futhark 24 文字を引く

北欧ルーン占いの開発ログ。 Elder Futhark 24 文字を 3 つのアエッティルに分け、 対称形のルーンは逆位置を持たないという伝統を実装に落とし込むまでと、 3 種類のスプレッドの作り方を記録しています。

RuneCast は、 北欧 の ルーン文字 (Elder Futhark 24 文字) を 投げて 引く 占い。 石 を 転がす 演出 の あと、 正位置 / 逆位置 の 意味 と 助言 が 出ます。 引く 処理 は すべて ブラウザ の 中 で、 質問 文 も サーバー に 送られ ません。

#🎯 タロット と 同じ 作り に しない

占い 系 は これ が 何本目 か という 状態 で、 すでに 数秘術 ・ タロット ・ マヤ暦 ・ 十干十二支 ・ 西洋占星術 が 並んで いました。 一番 近い の は タロット (ArcanaFlip) です が、 同じ 「カード を めくる」 体験 を もう 一度 作って も 意味 が ありません。

ルーン に は タロット に ない 前提 が 2 つ あります。

  1. 文字 数 が 24 と 少なく、 1 文字 ずつ に 名前 と 意味 が ある
  2. 文字 の 形 が 左右対称 な もの は、 逆位置 が 存在 しない

この 2 つ目 が 決め手 でした。 78 枚 すべて に 正逆 が ある タロット と 違い、 ルーン は 形 の 都合 で 逆位置 を 持て ない もの が ある。 これ を 実装 に 落とし込む と、 それ だけ で 別 の ツール に なり ます。

#🏗️ 「逆位置 を 持て ない ルーン」 を データ に 持たせる

各 ルーン に reversible を 持たせ ました。

ts
export interface Rune {
  id: string
  glyph: string        // ᚠ ᚢ ᚦ …

  name: string         // 翻字 (Fehu / Uruz …)

  jp: string           // フェフ・家畜

  keyword: string      // 富 / 豊かさ

  upright: string
  reversed: string
  reversible: boolean  // 対称形 なら false

  aett: 1 | 2 | 3      // 3 つ の アエッティル

}

reversible: false に なる の は、 ハガラズ (ᚺ 雹) ・ イサ (ᛁ 氷) ・ ヤラ (ᛃ 収穫) ・ エイワズ (ᛇ イチイ) ・ ソウィロ (ᛊ 太陽) ・ ギューフ (ᚷ 贈り物) ・ イングワズ (ᛜ) ・ ダガズ (ᛞ 夜明け) — いずれ も 上下 を ひっくり返して も 同じ 形 に なる 文字 です。

引く 処理 は こう なり ます。

ts
export function castRunes(spread: Spread): DrawnRune[] {
  const pool = [...RUNES]
  const out: DrawnRune[] = []
  for (let i = 0; i < spread.count; i++) {
    const idx = Math.floor(Math.random() * pool.length)
    const rune = pool.splice(idx, 1)[0]       // 重複 なし

    const reversed = rune.reversible && Math.random() < 0.5
    out.push({ rune, reversed, position: spread.positions[i] })
  }
  return out
}

rune.reversible && の 一語 だけ で、 「対称 な ルーン は 何度 引いて も 必ず 正位置」 が 成立 します。 逆位置 を 持た ない ルーン に は、 「逆位置 なし」 と 明記 した うえ で 停滞 側 の 読み を 添え ました。 ハガラズ の ように もともと 試練 を 意味 する 文字 は、 正位置 の まま で 十分 厳しい ので、 無理 に 逆 を 作ら ない 方 が 伝統 に 沿い ます。

#🔑 24 文字 を 3 つ の アエッティル に 割る

Elder Futhark は 8 文字 ずつ 3 群 (アエッティル) に 分かれ ます。 第 1 が フレイヤ、 第 2 が ヘイムダル、 第 3 が テュール。 aett: 1 | 2 | 3 を 持たせて 一覧 を 区切る と、 24 個 の 羅列 が 意味 の ある 3 ブロック に 見え ます。

スプレッド は 3 種類 に 絞り ました。

スプレッド枚数位置
一筋1今 の 導き
運命の三女神3ウルド (過去) / ヴェルザンディ (現在) / スクルド (未来)
五連の石5状況 / 障害 / 助言 / 基盤 / 結果

三女神 の 名前 は 北欧神話 の ノルン から 取って います。 「過去 ・ 現在 ・ 未来」 と だけ 書く より、 ウルド / ヴェルザンディ / スクルド と 併記 した 方 が 世界観 が 立ち、 検索 でも 拾わ れ ます。

#😓 苦労した ところ

引く 前 の 間 (ま)。 ボタン を 押した 瞬間 に 結果 が 出る と、 占い に なりません。 石 が 転がる 演出 を 挟んで 850ms 待ち、 その 間 は 結果 を null に 戻して います。 短すぎる と 軽く、 長すぎる と ただ の 待ち時間 に なる ので、 数字 を 何度 か 振り直し ました。

逆位置 の 表示。 逆位置 の ルーン は CSS の rotate(180deg) で 実際 に ひっくり返して います。 文字 が 上下 逆 に 見える こと 自体 が 説明 に なる ので、 ラベル より 先 に 形 で 伝わり ます。

ルーン文字 の フォント。 ᚠ ᚢ ᚦ … は 環境 に よって 豆腐 (□) に なる 可能性 が あり ます。 実機 で 確認 し、 グリフ が 出ない 場合 に 備えて 翻字 (Fehu) と 日本語 通称 (フェフ) を 必ず 併記 する 構成 に しました。

#🔭 今後 の 拡張

  • 質問文 から 決定的 に 引く モード (同じ 問い なら 同じ 結果 に なる ハッシュ 方式)
  • ルーン 1 文字 ずつ の 解説 ページ (24 文字 × 語源 ・ 神話 ・ 現代 の 読み)
  • 引いた 履歴 を 端末 内 に 保存 して 振り返る
  • 石 を 布 の 上 に 投げて 落ちた 位置 で 読む 「キャスティング」 方式

#💡 この サービス から 言える こと

題材 に 固有 の 制約 が ある なら、 それ を 実装 に 落とす と 差別化 に なり ます。 「対称 な 文字 は 逆位置 を 持た ない」 は、 知って いれば 一行 の 条件式 です が、 知ら ずに 作る と ただ の 24 枚 カード に なり ます。

占い 系 は 見た目 だけ 変えて 量産 でき て しまう 領域 です。 だ から こそ、 その 文化 の 中 で 何 が 決まって いる の か を 先 に 調べる 方 が、 結果的 に 早く 別物 に なり ました。

[ ./next_action ]

読んだら、 RuneCast を実際に動かす。

この開発ログは RuneCast をどう作ったかの記録です。 読み終わったらそのままサービス本体へ戻って、 実物で価値を確かめてください。

[ ./related_logs ]

関連する開発ログ

all logs →
ShadowTwin

立体パズルの別解を作る:同じ影と最少の積み木

ShadowTwinの開発記録。3方向の図から別々の最少配置を2つ探す仕組み、5問の独立全探索、スマホの横並び比較、保存・再編集と入力検査を解説します。実照明の計算や能力診断ではありません。

read log →
SlitCard

スリットアニメーションを作る:4コマの合成と透明原稿の設計

SlitCardの開発記録。4コマの帯を交互に合成し、すき間と黒帯で別のコマを見せる仕組みを解説。同縮尺の台紙・透明シートSVG、50mm確認線、手動プレビュー・初期非表示、再編集と実出力検査を整理します。

read log →
WindowLight

日当たりシミュレーションを作る:窓の光を床へ投影する幾何モデル

WindowLightの開発記録。太陽位置近似から窓の4隅を床へ投影し、凸多角形を部屋で切り取る設計を解説。国立天文台の16時刻との限定照合、大気差・低高度・実際の採光との違い、SVGと設定の再編集を整理します。

read log →
GridLights

電源構成の比較を作る:割合と実量を100個の電球で読み解く

電源構成比較GridLightsの開発記録。12か国の年次発電データを最大剰余法で100個の電球に変換し、割合とTWhを比較する設計を解説。欠損を0補完しない7分類、予想と実値、出典付きSVGと実データ検証を整理します。

read log →
SoundLoom

音のお絵かきを作る:実WAVから絵を測り直す設計

音のお絵かきの開発記録。描画を正弦波のPCMとWAVへ変換し、保存音声の周波数をGoertzel法で測って比較する仕組みを解説。音量・測定窓・量子化の限界と、編集・離脱時の古い結果を抑止する検証を整理します。

read log →
MazeLoom

宝探し迷路を作る:寄り道まで含めた最短ルートの探索

宝探し迷路の開発記録。通路を木として生成し、現在地と3つの宝の取得状態を組み合わせて最短ルートを探す仕組みを解説。問題コードの版固定、画面と解答付きPDFの一致、手数と印刷の検証を整理します。

read log →