← ソースコード説明書

packages/core - 共有型定義・コア抽象化

作成日: 2026-03-06 / 更新日: 2026-06-10

概要

モノレポ全体の基盤パッケージ。Op 命令型、タイムライン型、プラットフォーム抽象化インターフェース(IInput, IAudio, IStorage)、セーブデータスキーマを定義する。他のすべてのパッケージが依存する最下層レイヤー。

ディレクトリ構成

packages/core/
├── src/
│   ├── types/
│   │   ├── Op.ts               # ランタイム命令セット (199行)
│   │   ├── Action.ts           # 入力アクション enum
│   │   ├── SaveData.ts         # セーブデータスキーマ
│   │   ├── ViewState.ts        # 画面状態スナップショット
│   │   ├── BacklogEntry.ts     # バックログエントリ
│   │   └── ProjectConfig.ts    # プロジェクト設定
│   ├── interfaces/
│   │   ├── IInput.ts           # 入力 dispatch インターフェース
│   │   ├── IAudio.ts           # BGM/SE/VOICE 再生
│   │   └── IStorage.ts         # セーブ/ロード抽象化
│   ├── engine/
│   │   ├── IOpHandler.ts       # Op 実行インターフェース (350行)
│   │   └── OpRunner.ts         # Op 実行ループ
│   ├── registry/
│   │   └── commandDefinitions.ts # コマンド定義
│   ├── timeline/
│   │   ├── types.ts            # Timeline v1.1 スキーマ (183行)
│   │   ├── easing.ts           # イージング関数
│   │   ├── evaluator.ts        # タイムライン評価
│   │   ├── validator.ts        # タイムラインバリデーション
│   │   └── __tests__/          # テスト (4ファイル)
│   ├── events/
│   │   ├── types.ts            # イベントタイムライン型
│   │   ├── emitBetween.ts      # 範囲イベント発火
│   │   ├── seekStateAt.ts      # 状態シーク
│   │   ├── seekExtras.ts       # シーク拡張
│   │   └── validate.ts         # イベントバリデーション
│   ├── constants/
│   │   └── layout.ts           # 解像度定数 (1280x720)
│   └── index.ts                # 公開 API (180行)
├── test/
│   ├── SaveData.test.ts
│   ├── OpRunner.test.ts
│   └── commandSync.test.ts
├── package.json
├── tsconfig.json
└── vitest.config.ts

主要型定義

Op 型 (types/Op.ts)

ランタイム命令の IR (Intermediate Representation)。コンパイラが .ks/.ksc を Op[] に変換し、OpRunner が実行する。

// 主要 Op 型(判別子は `op`。実体は packages/core/src/types/Op.ts)
type Op =
  | { op: 'TEXT_APPEND'; who?: string; text: string }
  | { op: 'TEXT_NL' }
  | { op: 'PAGE' }
  | { op: 'WAIT_CLICK' }
  | { op: 'WAIT_MS'; ms: number }
  | { op: 'WAIT_VOICE_END' }
  | { op: 'BG_SET'; id: string; fadeMs?: number; effect?: 'fade'|'slide_left'|'slide_right'; x?: number; y?: number; s?: number }
  | { op: 'BG_CLEAR'; fadeMs?: number }
  | { op: 'CH_SET'; name: string; pose: string; pos: 'left'|'center'|'right'; fadeMs?: number; x?: number; y?: number; s?: number }
  | { op: 'CH_HIDE'; name: string; fadeMs?: number }
  | { op: 'CH_CLEAR'; fadeMs?: number }
  | { op: 'CH_MOVE'; name: string; pos: 'left'|'center'|'right'; durationMs: number }
  | { op: 'CH_EXPR'; name: string; expression: string; fadeMs?: number }
  | { op: 'CHOICE'; options: Array<{ label: string; jump: number }> }
  | { op: 'JUMP'; pc: number }
  | { op: 'JUMP_IF'; condition: string; pc: number }
  | { op: 'CALL'; pc: number }
  | { op: 'RETURN' }
  | { op: 'VAR_SET'; name: string; value: number }
  | { op: 'VAR_ADD'; name: string; value: number }
  | { op: 'VAR_SUB'; name: string; value: number }
  | { op: 'BGM_PLAY'; id: string; vol?: number; fadeMs?: number }
  | { op: 'BGM_STOP'; fadeMs?: number }
  | { op: 'SE_PLAY'; id: string; vol?: number }
  | { op: 'VOICE_PLAY'; id: string }
  | { op: 'OVERLAY_SET'; id: string; fadeMs?: number; x?: number; y?: number; s?: number }
  | { op: 'OVERLAY_HIDE'; id?: string; fadeMs?: number }
  | { op: 'SCREEN_FILTER'; filter: string; intensity?: number; options?: Record<string, unknown> }
  // ... 他(CH_LIP/CH_MOTION, LIVE2D_*, VRM_*, CAMERA_SET, SHAKE, FLASH,
  //      FADE_BLACK/WHITE, PARTICLE_EMIT, EFFECT_PLAY, SLASH_EMIT,
  //      BATTLE_START, MAP_*, ITEM_*, TIMELINE_PLAY など。全定義は Op.ts 参照)

注: 統一 WAIT op は無く WAIT_CLICK / WAIT_MS / WAIT_VOICE_END に分かれる。条件分岐は IF op ではなく JUMP_IF(条件付きジャンプ)で表現する。変数代入は VAR_SET / VAR_ADD / VAR_SUB の 3 種。オーバーレイは OVERLAY_SET / OVERLAY_HIDE

Action enum (types/Action.ts)

enum Action {
  OK, Back, Menu, SkipToggle, AutoToggle,
  Log, QuickSave, QuickLoad, Screenshot, HideWindow
}

SaveData (types/SaveData.ts)

interface SaveData {
  save_schema_version: 1;    // フリーズ済み
  engine_version: string;
  work_id: string;
  scenario_id: string;
  node_id: string;
  vars: Record<string, unknown>;
  read: Record<string, boolean>;
  timestamp: number;
}

Timeline (timeline/types.ts)

interface TimelineRoot {
  version: '1.1';
  duration: number;
  tracks: Track[];
}

interface Track {
  id: string;
  target: string;         // 'bg' | 'ch:xxx' | 'ovl:xxx'
  property: string;       // 'x' | 'y' | 'scale' | 'alpha' | 'rotation'
  keyframes: Keyframe[];
}

interface Keyframe {
  time: number;
  value: number;
  easing?: EasingType;
}

プラットフォーム抽象化

インターフェースメソッド役割
IInputdispatch(action)入力イベント → アクション変換
IAudioplayBgm, playSe, playVoice, stop, setVolumeカテゴリ別音声再生
IStoragesave, load, list, deleteセーブデータ永続化
IOpHandler各 Op 型に対応するメソッドOp 命令の実行

依存関係

  • 外部依存: なし
  • 被依存: compiler, ksc-compiler, interpreter, web, battle, editor, hono

テスト

  • test/SaveData.test.ts — セーブデータスキーマ検証
  • test/OpRunner.test.ts — Op 実行ループテスト
  • test/commandSync.test.ts — コマンド定義の同期チェック
  • src/timeline/__tests__/ — タイムライン評価・バリデーション (4 ファイル)
Ad: stickyBottom (728x90)
kaedevn - ノベルゲームを作れるプラットフォーム