Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@ webTaleKitは、現在アルファ版です。
| :--- | :--- | :--- | :---
| 0.1.0 | 初音| HATUNE | 初期リリース
| 0.2.0 | 礎 | ISHIZUE | 基本機能アップデート<br>0.2.12~<br>ダイアログ表示タグの追加<br>engineConfig反映バグの修正<br>未定義タグがある場合、undefineを呼び出すバグの修正<br>文字列以外を囲むとこける問題の修正<br>リンク切れでこける問題の修正<br>メッセージウインドウオーバーフローの修正<br>if属性の実装<br>for属性の実装<br>既読管理の追加
| 0.3.0 | 舞踊 | BUYO | - トランジション・アニメーション関連のアップデート<br>- テキストスピードの調整タグの追加<br>- テキスト表示フォントサイズの変更<br>- Webフォントのサポート(フォント変更設定の追加)<br>- 動画再生のサポート<br>- 子要素でフィルター・アニメーション設定
| 0.4.0 | 狭間 | HAZAMA | - Vue.jsやReact、SvelteなどのUIフレームワークとの連携追加のアップデート<br>
| 0.5.0 | 操手 | AYATURI | - ゲームパッドのサポート追加<br> - キーコンフィグの追加<br> - VOICEBOX APIの対応<br>- npm run recの追加
| 0.6.0 | 絡繰 | KARAKURI | - wtsLinterの追加<br>- VSCodeとの連携追加<br>- wst2htmlの追加<br>- プラグイン機能の追加<br>- クロスプラットホームへのビルド追加
| 0.7.0 | 綴り | TUDURI | GUIエディタの追加<br>
| 0.3.0 | 綴り | TUDURI | GUIエディタの追加
| 0.4.0 | 舞踊 | BUYO | - トランジション・アニメーション関連のアップデート<br>- テキストスピードの調整タグの追加<br>- テキスト表示フォントサイズの変更<br>- Webフォントのサポート(フォント変更設定の追加)<br>- 動画再生のサポート<br>- 子要素でフィルター・アニメーション設定<br>
| 0.5.0 | 狭間 | HAZAMA | - Vue.jsやReact、SvelteなどのUIフレームワークとの連携追加のアップデート<br>
| 0.6.0 | 操手 | AYATURI | - ゲームパッドのサポート追加<br> - キーコンフィグの追加<br> - VOICEBOX APIの対応<br>- npm run recの追加
| 0.7.0 | 絡繰 | KARAKURI | - wtsLinterの追加<br>- VSCodeとの連携追加<br>- wst2htmlの追加<br>- プラグイン機能の追加<br>- クロスプラットホームへのビルド追加
| 0.8.0 | 迅雷 | JINRAI | パフォーマンスアップデート<br>
| 0.9.0 | 出島 | DEJIMA | KAGタグコンバータの追加<br>
| 1.0.0 | 暁月 | AKATUKI | メジャーアップデート
Expand Down
124 changes: 124 additions & 0 deletions documents/saveAndLoad.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
# WebTaleKit セーブ・ロード機能 設計仕様書

## 1. 概要

WebTaleKitのゲームデータを保存・読み込みするセーブ・ロード機能の設計仕様。プレイヤーがゲーム進行を保存し、後で続きからプレイできるようにする機能を実装する。

## 2. 基本設計

### 2.1 保存データの構成

セーブデータには以下の情報を含める:

- セーブ日時(タイムスタンプ)
- シナリオの進行状況(ScenarioManager.progress)
- 現在のシナリオインデックス
- 表示中の画像情報(位置、サイズ、反転情報など)
- 選択履歴
- スクリプト変数(sceneFile内の変数)
- 現在のシーン名
- BGM情報(ソースと再生状況)
- バージョン情報(セーブデータの互換性確保)
- スクリーンショット(オプション)

### 2.2 ストレージ方式

- プライマリ: localStorage
- 容量制限: 約5MB
- 必要に応じてIndexedDBへの拡張も検討

## 3. 機能仕様

### 3.1 Core.js への追加機能

#### 3.1.1 セーブ機能

```
saveGame(slotNumber): Promise<boolean>
```

- 現在のゲーム状態をJSONに変換
- ストレージにslotNumberをキーとして保存
- 成功時はtrueを返す

#### 3.1.2 ロード機能

```
loadGame(slotNumber): Promise<boolean>
```

- slotNumberに対応するセーブデータを読み込み
- シーンの再ロード
- 進行状況・変数・表示画像・BGMなどの復元
- 成功時はtrueを返す

#### 3.1.3 WebTaleScript用ハンドラー

```
saveHandler(scenarioObject): Promise<void>
loadHandler(scenarioObject): Promise<void>
```

- コマンドリスト拡張により`<save>`と`<load>`タグをサポート

### 3.2 UI実装

#### 3.2.1 セーブ・ロード画面

- タブ切り替え方式(セーブ/ロード)
- スロット一覧表示(デフォルト10スロット)
- 各スロットにはタイムスタンプ、シーン名、スクリーンショット(オプション)を表示
- 「戻る」ボタンでゲームに戻る

#### 3.2.2 表示・非表示の制御

```
showSaveLoadScreen(mode='save'): void
```

- mode: 'save'または'load'
- セーブ・ロード画面のDOM要素を表示

## 4. 拡張機能

### 4.1 オートセーブ

- 選択肢選択後や特定シーン区切りで自動保存
- 専用の「オートセーブ」スロットを用意

### 4.2 ショートカットキー

- F5: セーブ画面表示
- F9: ロード画面表示

### 4.3 スクリーンショット

- Canvas要素から現在の画面をJPEG形式で保存
- 容量節約のため圧縮率を調整

### 4.4 バージョン管理

- セーブデータにバージョン情報を含め、アップデート時の互換性を確保
- 旧バージョンのセーブデータを新バージョンで読み込む際の変換処理

## 5. 実装手順

1. Core.jsに基本機能の実装(saveGame, loadGame)
2. WebTaleScriptハンドラーの追加(saveHandler, loadHandler)
3. UI画面の実装(HTML/CSS/JS)
4. 動作テスト
5. 拡張機能の実装(オートセーブ、スクリーンショット等)

## 6. 注意事項

- シリアライズできない要素(DOM要素、循環参照等)の扱い
- LocalStorageの容量制限への対応
- 非同期処理の適切な扱い
- クロスブラウザ対応の確保

## 7. 将来的な拡張性

- クラウドセーブ機能
- エクスポート/インポート機能
- セーブデータの暗号化
- 複数プロファイル対応
1 change: 1 addition & 0 deletions example/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

91 changes: 91 additions & 0 deletions example/src/scene/en/saveload.scene
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<scene>
<script>
export const sceneConfig = {
name: "Save/Load Test",
template: "./src/screen/title.html",
background: "./src/resource/background/living_room.jpg",
bgm: "./src/resource/bgm/calm_music.wav"
}
</script>
<scenario>
<say name="Guide">
Hello. This is a test scene for the save and load functionality.
</say>
<say name="Guide">
In this scene, you can test the save and load functionality.
</say>
<say name="Guide">
First, click the "save" button at the bottom of the screen to display the save screen.
</say>
<say name="Guide">
On the save screen, you can select a slot to save the game state.
</say>
<say name="Guide">
Next, click the "load" button to display the load screen.
</say>
<say name="Guide">
On the load screen, you can load a saved game state.
</say>
<say name="Guide">
You can also use the "q.save" and "q.load" buttons for quick save and load.
</say>
<choice prompt="Which feature would you like to test?">
<option label="Test save functionality" id="1">
<say name="Guide">
Let's test the save functionality.
</say>
<say name="Guide">
You can display the save screen by clicking the "save" button at the bottom of the screen or by using the following command.
</say>
<save />
<say name="Guide">
Save completed. Now let's test the load functionality.
</say>
<jump index="20" />
</option>
<option label="Test load functionality" id="2">
<say name="Guide">
Let's test the load functionality.
</say>
<say name="Guide">
You can display the load screen by clicking the "load" button at the bottom of the screen or by using the following command.
</say>
<load />
<say name="Guide">
Load completed.
</say>
<jump index="20" />
</option>
<option label="Test quick save" id="3">
<say name="Guide">
Let's test the quick save functionality.
</say>
<say name="Guide">
Clicking the "q.save" button at the bottom of the screen will save the current state to slot 0.
</say>
<save slot="0" message="Quick save completed." />
<jump index="20" />
</option>
<option label="Test quick load" id="4">
<say name="Guide">
Let's test the quick load functionality.
</say>
<say name="Guide">
Clicking the "q.load" button at the bottom of the screen will load the state from slot 0.
</say>
<load slot="0" message="No quick save data found." />
<jump index="20" />
</option>
</choice>
<say name="Guide">
The save and load functionality test is complete.
</say>
<say name="Guide">
You can use this functionality to save and load your game progress.
</say>
<say name="Guide">
Now, let's return to the title screen.
</say>
<jump index="0" />
</scenario>
</scene>
3 changes: 3 additions & 0 deletions example/src/scene/en/title.scene
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
<item label="Special Effects" onSelect="effects">
<route scene="effects" />
</item>
<item label="Save and Load Test" onSelect="saveload">
<route scene="saveload" />
</item>
</choice>
</scenario>

Expand Down
37 changes: 37 additions & 0 deletions example/src/scene/if_test.scene
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<scene>
<scenario>
<text>ifグローバル属性のテストです。</text>
<text>変数hogeの値を設定します。</text>

<call method="hoge = 1" />

<text>現在のhogeの値: {{hoge}}</text>

<text if="hoge==1">この文章はhoge==1の場合に表示されます。</text>
<text if="hoge==2">この文章はhoge==2の場合に表示されます。</text>

<text>hogeの値を2に変更します。</text>

<call method="hoge = 2" />

<text>現在のhogeの値: {{hoge}}</text>

<text if="hoge==1">この文章はhoge==1の場合に表示されます。</text>
<text if="hoge==2">この文章はhoge==2の場合に表示されます。</text>

<text>ifグローバル属性のテストが完了しました。</text>

<route to="title" />
</scenario>

<script>
export const sceneConfig = {
name: 'if_test',
background: './src/resource/background/title_bg.png',
bgm: './src/resource/bgm/title_theme.mp3',
template: './src/screen/title.html'
}

export let hoge = 0
</script>
</scene>
91 changes: 91 additions & 0 deletions example/src/scene/saveload.scene
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<scene>
<script>
export const sceneConfig = {
name: "セーブ・ロードテスト",
template: "./src/screen/title.html",
background: "./src/resource/background/living_room.jpg",
bgm: "./src/resource/bgm/calm_music.wav"
}
</script>
<scenario>
<say name="ガイド">
こんにちは。これはセーブ・ロード機能のテストシーンです。
</say>
<say name="ガイド">
このシーンでは、セーブ・ロード機能をテストすることができます。
</say>
<say name="ガイド">
まず、画面下部の「save」ボタンをクリックして、セーブ画面を表示してみましょう。
</say>
<say name="ガイド">
セーブ画面では、スロットを選択してゲームの状態を保存できます。
</say>
<say name="ガイド">
次に、「load」ボタンをクリックして、ロード画面を表示してみましょう。
</say>
<say name="ガイド">
ロード画面では、保存したゲームの状態を読み込むことができます。
</say>
<say name="ガイド">
また、「q-save」と「q-load」ボタンを使うと、クイックセーブ・クイックロードができます。
</say>
<choice prompt="どの機能をテストしますか?">
<item label="セーブ機能をテストする" id="1">
<say name="ガイド">
それでは、セーブ機能をテストしましょう。
</say>
<say name="ガイド">
画面下部の「save」ボタンをクリックするか、以下のコマンドでセーブ画面を表示できます。
</say>
<save />
<say name="ガイド">
セーブが完了しました。次はロード機能をテストしましょう。
</say>
<jump index="20" />
</item>
<item label="ロード機能をテストする" id="2">
<say name="ガイド">
それでは、ロード機能をテストしましょう。
</say>
<say name="ガイド">
画面下部の「load」ボタンをクリックするか、以下のコマンドでロード画面を表示できます。
</say>
<load />
<say name="ガイド">
ロードが完了しました。
</say>
<jump index="20" />
</item>
<item label="クイックセーブをテストする" id="3">
<say name="ガイド">
それでは、クイックセーブ機能をテストしましょう。
</say>
<say name="ガイド">
画面下部の「q.save」ボタンをクリックすると、スロット0に現在の状態が保存されます。
</say>
<save slot="0" message="クイックセーブが完了しました。" />
<jump index="20" />
</item>
<item label="クイックロードをテストする" id="4">
<say name="ガイド">
それでは、クイックロード機能をテストしましょう。
</say>
<say name="ガイド">
画面下部の「q.load」ボタンをクリックすると、スロット0から状態が読み込まれます。
</say>
<load slot="0" message="クイックセーブデータがありません。" />
<jump index="20" />
</item>
</choice>
<say name="ガイド">
セーブ・ロード機能のテストが完了しました。
</say>
<say name="ガイド">
この機能を使って、ゲームの進行状況を保存したり、読み込んだりすることができます。
</say>
<say name="ガイド">
それでは、タイトル画面に戻りましょう。
</say>
<jump index="0" />
</scenario>
</scene>
Loading