@luna-editor/engine 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Player.js +191 -37
- package/dist/components/BackgroundLayer.js +7 -5
- package/dist/components/GameScreen.d.ts +8 -2
- package/dist/components/GameScreen.js +41 -7
- package/dist/components/OverlayUI.d.ts +2 -3
- package/dist/components/OverlayUI.js +3 -14
- package/dist/components/PluginComponentProvider.d.ts +1 -1
- package/dist/components/PluginComponentProvider.js +20 -2
- package/dist/contexts/DataContext.d.ts +3 -1
- package/dist/contexts/DataContext.js +38 -9
- package/dist/contexts/PlaybackTextContext.d.ts +32 -0
- package/dist/contexts/PlaybackTextContext.js +29 -0
- package/dist/data-api-types.d.ts +251 -0
- package/dist/data-api-types.js +6 -0
- package/dist/emotion-effect-types.d.ts +86 -0
- package/dist/emotion-effect-types.js +6 -0
- package/dist/hooks/useBacklog.js +0 -1
- package/dist/hooks/useFontLoader.d.ts +9 -2
- package/dist/hooks/useFontLoader.js +126 -87
- package/dist/hooks/useImagePreloader.d.ts +5 -0
- package/dist/hooks/useImagePreloader.js +53 -0
- package/dist/hooks/usePluginAPI.js +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/plugin/PluginManager.d.ts +21 -4
- package/dist/plugin/PluginManager.js +132 -58
- package/dist/plugin/luna-react.d.ts +41 -0
- package/dist/plugin/luna-react.js +99 -0
- package/dist/sdk.d.ts +31 -217
- package/dist/sdk.js +12 -2
- package/dist/types.d.ts +13 -1
- package/package.json +6 -6
package/dist/sdk.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import
|
|
2
|
+
import { useDataAPI } from "./contexts/DataContext";
|
|
3
|
+
import type { DataAPI, DataContext, DataSubscriber } from "./data-api-types";
|
|
4
|
+
import type { FacePosition } from "./emotion-effect-types";
|
|
5
|
+
import type { Character, ConversationBranchState, EntityState, ScenarioBlock, ScenarioBlockType } from "./types";
|
|
3
6
|
/**
|
|
4
7
|
* ブロックオプションの定義
|
|
5
8
|
* プラグインがシナリオブロックに追加できるカスタムオプションを定義
|
|
@@ -39,132 +42,8 @@ export interface LunaPlugin {
|
|
|
39
42
|
onUninstall?(api: PluginInstallAPI): Promise<void>;
|
|
40
43
|
setup(api: PluginAPI): void;
|
|
41
44
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
*/
|
|
45
|
-
export interface ScenarioPlaybackData {
|
|
46
|
-
/** 現在のブロックインデックス(0始まり) */
|
|
47
|
-
currentBlockIndex: number;
|
|
48
|
-
/** 総ブロック数 */
|
|
49
|
-
totalBlocks: number;
|
|
50
|
-
/** 現在のシナリオID */
|
|
51
|
-
scenarioId: string;
|
|
52
|
-
/** シナリオ名 */
|
|
53
|
-
scenarioName: string;
|
|
54
|
-
/** 現在のブロック */
|
|
55
|
-
currentBlock: ScenarioBlock | null;
|
|
56
|
-
/** 表示中のテキスト(改行は自動的に<br />に変換されます) */
|
|
57
|
-
displayText?: string | React.ReactNode;
|
|
58
|
-
/** テキストアニメーション中かどうか */
|
|
59
|
-
isTyping?: boolean;
|
|
60
|
-
/** 表示中のキャラクター */
|
|
61
|
-
displayedCharacters?: DisplayedCharacter[];
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* バックログデータ
|
|
65
|
-
*/
|
|
66
|
-
export interface BacklogData {
|
|
67
|
-
/** バックログエントリ */
|
|
68
|
-
entries: BacklogEntry[];
|
|
69
|
-
/** 総エントリ数 */
|
|
70
|
-
totalEntries: number;
|
|
71
|
-
/** ログエントリを追加 */
|
|
72
|
-
addLogEntry?: (entry: BacklogEntry) => void;
|
|
73
|
-
/** ログをクリア */
|
|
74
|
-
clearLogs?: () => void;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* プレイヤー設定データ
|
|
78
|
-
*/
|
|
79
|
-
export interface PlayerSettingsData extends PlayerSettings {
|
|
80
|
-
/** テキスト速度 (ミリ秒/文字) */
|
|
81
|
-
textSpeed: number;
|
|
82
|
-
/** 自動再生速度 (秒) */
|
|
83
|
-
autoPlaySpeed: number;
|
|
84
|
-
/** BGM音量 (0-1) */
|
|
85
|
-
bgmVolume: number;
|
|
86
|
-
/** SE音量 (0-1) */
|
|
87
|
-
seVolume: number;
|
|
88
|
-
/** ボイス音量 (0-1) */
|
|
89
|
-
voiceVolume: number;
|
|
90
|
-
/** スキップ設定 */
|
|
91
|
-
skipMode?: "all" | "unread" | "none";
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* プラグインアセットデータ
|
|
95
|
-
*/
|
|
96
|
-
export interface PluginAssetsData {
|
|
97
|
-
/**
|
|
98
|
-
* プラグインのアセットURLを取得
|
|
99
|
-
* @param pluginName - プラグインのパッケージ名
|
|
100
|
-
* @param filename - アセットファイル名
|
|
101
|
-
* @returns アセットのURL
|
|
102
|
-
*/
|
|
103
|
-
getAssetUrl: (pluginName: string, filename: string) => string;
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* フォントデータ
|
|
107
|
-
*/
|
|
108
|
-
export interface FontsData {
|
|
109
|
-
/** 利用可能なフォント一覧 */
|
|
110
|
-
fonts: WorkFont[];
|
|
111
|
-
/** 選択されているフォントファミリー */
|
|
112
|
-
selectedFontFamily: string | undefined;
|
|
113
|
-
/** フォントが読み込み完了しているかどうか */
|
|
114
|
-
isLoaded: boolean;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* 全データコンテキスト
|
|
118
|
-
*/
|
|
119
|
-
export interface DataContext {
|
|
120
|
-
/** シナリオ再生情報 */
|
|
121
|
-
playback: ScenarioPlaybackData;
|
|
122
|
-
/** バックログ情報 */
|
|
123
|
-
backlog: BacklogData;
|
|
124
|
-
/** プレイヤー設定 */
|
|
125
|
-
settings: PlayerSettingsData;
|
|
126
|
-
/** プラグインアセット */
|
|
127
|
-
pluginAssets: PluginAssetsData;
|
|
128
|
-
/** 会話分岐データ */
|
|
129
|
-
branchData?: ConversationBranchState;
|
|
130
|
-
/** 分岐履歴 */
|
|
131
|
-
branchHistory?: BranchChoiceHistory[];
|
|
132
|
-
/** 現在の背景データ(単一、後方互換性用) */
|
|
133
|
-
background?: BackgroundData | null;
|
|
134
|
-
/** 現在の背景データ(複数、背景グループ対応) */
|
|
135
|
-
backgrounds?: BackgroundData[];
|
|
136
|
-
/** フォント設定 */
|
|
137
|
-
fonts?: FontsData;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* データ購読コールバック
|
|
141
|
-
*/
|
|
142
|
-
export type DataSubscriber<T> = (data: T) => void;
|
|
143
|
-
/**
|
|
144
|
-
* データAPI - プラグインからのデータアクセスインターフェース
|
|
145
|
-
*
|
|
146
|
-
* @example Pull型(現在値の取得)
|
|
147
|
-
* ```typescript
|
|
148
|
-
* const blockIndex = api.data.get('playback', 'currentBlockIndex');
|
|
149
|
-
* const playback = api.data.get('playback');
|
|
150
|
-
* ```
|
|
151
|
-
*
|
|
152
|
-
* @example Push型(変更の監視)
|
|
153
|
-
* ```typescript
|
|
154
|
-
* const unsubscribe = api.data.subscribe('playback', (data) => {
|
|
155
|
-
* console.log('Playback updated:', data);
|
|
156
|
-
* });
|
|
157
|
-
* // cleanup
|
|
158
|
-
* unsubscribe();
|
|
159
|
-
* ```
|
|
160
|
-
*
|
|
161
|
-
* @example プロパティ単位での監視
|
|
162
|
-
* ```typescript
|
|
163
|
-
* api.data.watch('playback', 'currentBlockIndex', (index) => {
|
|
164
|
-
* console.log('Block changed to:', index);
|
|
165
|
-
* });
|
|
166
|
-
* ```
|
|
167
|
-
*/
|
|
45
|
+
export type { BacklogData, FontsData, PlayerSettingsData, PluginAssetsData, ScenarioPlaybackData, } from "./data-api-types";
|
|
46
|
+
export type { DataAPI, DataContext, DataSubscriber };
|
|
168
47
|
/**
|
|
169
48
|
* UI表示管理API - プラグインUIコンポーネントの表示/非表示を制御
|
|
170
49
|
*/
|
|
@@ -191,86 +70,6 @@ export interface UIAPI {
|
|
|
191
70
|
*/
|
|
192
71
|
isVisible(type: ComponentType): boolean;
|
|
193
72
|
}
|
|
194
|
-
export interface DataAPI {
|
|
195
|
-
/**
|
|
196
|
-
* データの現在値を取得(Pull型)
|
|
197
|
-
* @param key - データカテゴリ
|
|
198
|
-
*/
|
|
199
|
-
get<K extends keyof DataContext>(key: K): DataContext[K];
|
|
200
|
-
/**
|
|
201
|
-
* データの特定プロパティを取得(Pull型)
|
|
202
|
-
* @param key - データカテゴリ
|
|
203
|
-
* @param property - プロパティ名
|
|
204
|
-
*/
|
|
205
|
-
get<K extends keyof DataContext, P extends keyof DataContext[K]>(key: K, property: P): DataContext[K][P];
|
|
206
|
-
/**
|
|
207
|
-
* データカテゴリ全体の変更を監視(Push型)
|
|
208
|
-
* @param key - データカテゴリ
|
|
209
|
-
* @param callback - 変更時のコールバック
|
|
210
|
-
* @returns unsubscribe関数
|
|
211
|
-
*/
|
|
212
|
-
subscribe<K extends keyof DataContext>(key: K, callback: DataSubscriber<DataContext[K]>): () => void;
|
|
213
|
-
/**
|
|
214
|
-
* 特定プロパティの変更を監視(Push型)
|
|
215
|
-
* @param key - データカテゴリ
|
|
216
|
-
* @param property - プロパティ名
|
|
217
|
-
* @param callback - 変更時のコールバック
|
|
218
|
-
* @returns unsubscribe関数
|
|
219
|
-
*/
|
|
220
|
-
watch<K extends keyof DataContext, P extends keyof DataContext[K]>(key: K, property: P, callback: DataSubscriber<DataContext[K][P]>): () => void;
|
|
221
|
-
/**
|
|
222
|
-
* プレイヤー設定を更新
|
|
223
|
-
* @param settings - 更新する設定値(部分更新可能)
|
|
224
|
-
*/
|
|
225
|
-
updateSettings(settings: Partial<PlayerSettingsData>): void;
|
|
226
|
-
/**
|
|
227
|
-
* BGM音量を設定
|
|
228
|
-
* @param volume - 音量(0-1の範囲)
|
|
229
|
-
*/
|
|
230
|
-
setBgmVolume(volume: number): void;
|
|
231
|
-
/**
|
|
232
|
-
* SE音量を設定
|
|
233
|
-
* @param volume - 音量(0-1の範囲)
|
|
234
|
-
*/
|
|
235
|
-
setSeVolume(volume: number): void;
|
|
236
|
-
/**
|
|
237
|
-
* ボイス音量を設定
|
|
238
|
-
* @param volume - 音量(0-1の範囲)
|
|
239
|
-
*/
|
|
240
|
-
setVoiceVolume(volume: number): void;
|
|
241
|
-
/**
|
|
242
|
-
* 全カテゴリの音量を一括設定
|
|
243
|
-
* @param volumes - カテゴリ別音量設定
|
|
244
|
-
*/
|
|
245
|
-
setVolumes(volumes: {
|
|
246
|
-
bgm?: number;
|
|
247
|
-
se?: number;
|
|
248
|
-
voice?: number;
|
|
249
|
-
}): void;
|
|
250
|
-
/**
|
|
251
|
-
* 現在のブロックのオプション値を型安全に取得
|
|
252
|
-
*
|
|
253
|
-
* @example
|
|
254
|
-
* ```typescript
|
|
255
|
-
* // プラグイン側で型を定義
|
|
256
|
-
* type MyBlockOptions = {
|
|
257
|
-
* ultemist_bubble_style: "normal" | "monologue" | "star";
|
|
258
|
-
* ultemist_effect_type: "none" | "shake" | "fade";
|
|
259
|
-
* };
|
|
260
|
-
*
|
|
261
|
-
* // コンポーネントで使用
|
|
262
|
-
* const bubbleStyle = dataAPI.getBlockOption<MyBlockOptions, "ultemist_bubble_style">("ultemist_bubble_style");
|
|
263
|
-
* // 型: "normal" | "monologue" | "star" | undefined
|
|
264
|
-
*
|
|
265
|
-
* // または簡易版(キーのみ指定)
|
|
266
|
-
* const bubbleStyle = dataAPI.getBlockOption<MyBlockOptions>("ultemist_bubble_style");
|
|
267
|
-
* ```
|
|
268
|
-
*
|
|
269
|
-
* @param key - オプションのキー
|
|
270
|
-
* @returns オプションの値、または未設定の場合undefined
|
|
271
|
-
*/
|
|
272
|
-
getBlockOption<T extends Record<string, unknown>, K extends keyof T = keyof T>(key: K): T[K] | undefined;
|
|
273
|
-
}
|
|
274
73
|
/**
|
|
275
74
|
* ブロックオプション登録API
|
|
276
75
|
*/
|
|
@@ -466,12 +265,15 @@ export interface CharacterSpeakContext {
|
|
|
466
265
|
id?: string;
|
|
467
266
|
name?: string;
|
|
468
267
|
};
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
268
|
+
/**
|
|
269
|
+
* 【機能概要】: 顔位置情報(感情エフェクト用)
|
|
270
|
+
* 【実装方針】: インライン定義からFacePosition型に変更し、型の再利用性を向上
|
|
271
|
+
* 【テスト対応】: TC-009を通すための実装
|
|
272
|
+
* 🔵 信頼性レベル: note.md(行301-308)の推奨事項に基づく
|
|
273
|
+
*
|
|
274
|
+
* @see FacePosition - 完全な型定義は emotion-effect-types.ts を参照
|
|
275
|
+
*/
|
|
276
|
+
facePosition?: FacePosition;
|
|
475
277
|
}
|
|
476
278
|
export interface ScenarioContext {
|
|
477
279
|
scenario: {
|
|
@@ -553,15 +355,27 @@ export declare enum ComponentType {
|
|
|
553
355
|
Config = "Config",
|
|
554
356
|
ConversationBranch = "ConversationBranch",
|
|
555
357
|
Background = "Background",
|
|
556
|
-
FullscreenTextBox = "FullscreenTextBox"
|
|
358
|
+
FullscreenTextBox = "FullscreenTextBox",
|
|
359
|
+
/**
|
|
360
|
+
* 【機能概要】: 感情エフェクトコンポーネント登録用の型定義
|
|
361
|
+
* 【実装方針】: 既存のComponentType値と同じパターン(PascalCase、文字列リテラル型)で追加
|
|
362
|
+
* 【テスト対応】: TC-001, TC-003, TC-004, TC-012を通すための実装
|
|
363
|
+
* 🔵 信頼性レベル: タスクノート、要件定義書、設計文書に明確に定義されている
|
|
364
|
+
*
|
|
365
|
+
* @see EmotionEffectState - 関連する型定義は emotion-effect-types.ts を参照
|
|
366
|
+
*/
|
|
367
|
+
EmotionEffect = "EmotionEffect"
|
|
557
368
|
}
|
|
558
369
|
/**
|
|
559
370
|
* コンポーネント登録API
|
|
560
|
-
*
|
|
371
|
+
* DataAPIはPluginComponentProviderから自動的にpropsとして渡されます
|
|
561
372
|
*/
|
|
562
373
|
export interface ComponentAPI {
|
|
563
|
-
registerComponent(type: ComponentType, component: React.ComponentType
|
|
374
|
+
registerComponent(type: ComponentType, component: React.ComponentType<{
|
|
375
|
+
dataAPI?: DataAPI;
|
|
376
|
+
}>): void;
|
|
564
377
|
}
|
|
378
|
+
export type { EffectPosition, EmotionEffectPosition, EmotionEffectState, EmotionType, FacePosition, PositionType, } from "./emotion-effect-types";
|
|
565
379
|
export type { BacklogEntry, DisplayedCharacter } from "./types";
|
|
566
380
|
export interface PlayerSettings {
|
|
567
381
|
textSpeed: number;
|
|
@@ -597,7 +411,7 @@ export declare function calculateFaceRelativePosition(options: FaceRelativeEffec
|
|
|
597
411
|
x: number;
|
|
598
412
|
y: number;
|
|
599
413
|
};
|
|
600
|
-
export { React };
|
|
414
|
+
export { React, useDataAPI };
|
|
601
415
|
/**
|
|
602
416
|
* 画面サイズ変換ユーティリティの型定義
|
|
603
417
|
*/
|
package/dist/sdk.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// SDK exports for plugin development
|
|
2
2
|
// This file contains all types and utilities needed for plugin development
|
|
3
3
|
import React from "react";
|
|
4
|
+
import { useDataAPI } from "./contexts/DataContext";
|
|
4
5
|
// Component registration types
|
|
5
6
|
export var ComponentType;
|
|
6
7
|
(function (ComponentType) {
|
|
@@ -17,6 +18,15 @@ export var ComponentType;
|
|
|
17
18
|
ComponentType["ConversationBranch"] = "ConversationBranch";
|
|
18
19
|
ComponentType["Background"] = "Background";
|
|
19
20
|
ComponentType["FullscreenTextBox"] = "FullscreenTextBox";
|
|
21
|
+
/**
|
|
22
|
+
* 【機能概要】: 感情エフェクトコンポーネント登録用の型定義
|
|
23
|
+
* 【実装方針】: 既存のComponentType値と同じパターン(PascalCase、文字列リテラル型)で追加
|
|
24
|
+
* 【テスト対応】: TC-001, TC-003, TC-004, TC-012を通すための実装
|
|
25
|
+
* 🔵 信頼性レベル: タスクノート、要件定義書、設計文書に明確に定義されている
|
|
26
|
+
*
|
|
27
|
+
* @see EmotionEffectState - 関連する型定義は emotion-effect-types.ts を参照
|
|
28
|
+
*/
|
|
29
|
+
ComponentType["EmotionEffect"] = "EmotionEffect";
|
|
20
30
|
})(ComponentType || (ComponentType = {}));
|
|
21
31
|
// Component types are already exported as part of the interfaces above
|
|
22
32
|
// Plugin utility function
|
|
@@ -58,8 +68,8 @@ export function calculateFaceRelativePosition(options) {
|
|
|
58
68
|
y: baseY + offsetY,
|
|
59
69
|
};
|
|
60
70
|
}
|
|
61
|
-
// Export React for plugin use
|
|
62
|
-
export { React };
|
|
71
|
+
// Export React and hooks for plugin use
|
|
72
|
+
export { React, useDataAPI };
|
|
63
73
|
export { OverlayUI } from "./components/OverlayUI";
|
|
64
74
|
// Screen size constants
|
|
65
75
|
export { aspectRatio, BasisHeight, BasisWidth } from "./constants/screen-size";
|
package/dist/types.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ export interface ScenarioBlock {
|
|
|
16
16
|
updatedAt: Date;
|
|
17
17
|
/** Plugin-defined block options (key-value pairs) */
|
|
18
18
|
options?: BlockOptions | null;
|
|
19
|
+
characterLayoutMode?: "detailed" | "simple";
|
|
19
20
|
speaker?: {
|
|
20
21
|
id: string;
|
|
21
22
|
name: string;
|
|
@@ -311,13 +312,24 @@ export interface PlayerSettings {
|
|
|
311
312
|
defaultBackgroundFadeDuration?: number;
|
|
312
313
|
/** 全ての音声をミュートする (デフォルト: false) */
|
|
313
314
|
muteAudio?: boolean;
|
|
314
|
-
/**
|
|
315
|
+
/** 選択されたフォントファミリー(テキスト用) */
|
|
315
316
|
selectedFontFamily?: string;
|
|
317
|
+
/** 選択されたUIフォントファミリー(メニュー・ラベル等) */
|
|
318
|
+
selectedUIFontFamily?: string;
|
|
319
|
+
/** 非アクティブキャラクターの明るさ (0-1, デフォルト: 0.8) */
|
|
320
|
+
inactiveCharacterBrightness?: number;
|
|
321
|
+
/** キャラクター間隔(簡易モード用、デフォルト: 0.1) */
|
|
322
|
+
characterSpacing?: number;
|
|
316
323
|
}
|
|
317
324
|
export interface PluginConfig {
|
|
318
325
|
packageName: string;
|
|
319
326
|
bundleUrl: string;
|
|
320
327
|
config?: unknown;
|
|
328
|
+
/** アセットのファイル名→絶対URLマッピング(外部アプリから利用時に必要) */
|
|
329
|
+
assets?: {
|
|
330
|
+
filename: string;
|
|
331
|
+
url: string;
|
|
332
|
+
}[];
|
|
321
333
|
}
|
|
322
334
|
/** 作品のサウンドデータ(プラグインからアクセス可能) */
|
|
323
335
|
export interface WorkSound {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@luna-editor/engine",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
4
4
|
"description": "Luna Editor scenario playback engine",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -31,11 +31,11 @@
|
|
|
31
31
|
"lucide-react": "^0.503.0"
|
|
32
32
|
},
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@types/react": "^19",
|
|
35
|
-
"@types/react-dom": "^19",
|
|
36
|
-
"
|
|
37
|
-
"react": "^19.
|
|
38
|
-
"
|
|
34
|
+
"@types/react": "^19.2.9",
|
|
35
|
+
"@types/react-dom": "^19.2.3",
|
|
36
|
+
"react": "^19.2.3",
|
|
37
|
+
"react-dom": "^19.2.3",
|
|
38
|
+
"typescript": "^5"
|
|
39
39
|
},
|
|
40
40
|
"publishConfig": {
|
|
41
41
|
"access": "public"
|