Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
477f0a5
fix(core): sounds.json のサウンド名を名前空間付き・拡張子なしに修正
bafv4 Aug 25, 2026
bc16429
fix(buildPack): useGrid=false の main で rows/columns を省略し、grid 数を 1 以上…
bafv4 Aug 25, 2026
3aff623
fix(parsePack): エリア復元を buildPack と対称にし、フォールバック矩形の縮尺ズレを直す
bafv4 Aug 25, 2026
55e77d5
perf(parsePack): 透明 lock.png 判定に走査サイズ上限を設ける
bafv4 Aug 25, 2026
cc5f4ae
fix(toast): ハイドレート中のトーストが表示されず握り潰される問題を修正
bafv4 Aug 25, 2026
36306bc
fix(header): Web のリセットボタンをエクスポート/インポート中に無効化する
bafv4 Aug 25, 2026
85dc421
fix(packInfo): 解像度 Select で「カスタム」を選ぶと表示が即座に戻る問題を修正
bafv4 Aug 25, 2026
092291b
fix(i18n): 共通 UI のハードコード日本語を翻訳キー化し、未使用キーを削除
bafv4 Aug 25, 2026
9251398
fix(version): バージョンを package.json 単一ソースに揃え、semver 違反の `v` 接頭辞を除去
bafv4 Aug 25, 2026
ba08655
chore(deps): 未使用の @tauri-apps/plugin-fs を削除
bafv4 Aug 25, 2026
9e9ed09
perf(area-editor): AreaEditor を memo 化しミラー effect をフィールド単位に分割
bafv4 Aug 25, 2026
7f4e0a7
fix(sounds): 音声ファイルの読み取り失敗を未処理 rejection にせずトースト通知する
bafv4 Aug 25, 2026
e38de2a
perf(layout-editor): ドメイン state 全体購読をやめ子へ安定参照のハンドラを渡す
bafv4 Aug 25, 2026
7d49445
fix(background): 背景画像アップロードの失敗処理と形式検証を追加
bafv4 Aug 25, 2026
dd2f909
fix(adapters): パックフォルダごと圧縮された zip / フォルダを読めるようにする
bafv4 Aug 25, 2026
cd4f97d
perf(preview): 背景 canvas を表示サイズ×DPR で確保し rAF で再描画を合体
bafv4 Aug 25, 2026
3c496ed
fix(web): blob URL の即時 revoke で zip ダウンロードが中断されうる問題を修正
bafv4 Aug 25, 2026
216907e
perf(audio): ffmpeg の blob URL を revoke しアイドル時に terminate する
bafv4 Aug 25, 2026
87b3905
perf(preview): ドラッグ中 floor 後に同値なら store 更新を省く
bafv4 Aug 25, 2026
b95eb8c
perf(app): タブ本文を React.lazy + Suspense で遅延ロードする
bafv4 Aug 25, 2026
74e4df2
feat(desktop): 保存先の存在検証用に path_is_dir コマンドを追加
bafv4 Aug 25, 2026
6782fc6
i18n(preview): プレビュー下のキャプションをハードコード日本語から i18n 化
bafv4 Aug 25, 2026
c527710
feat(adapters): 上書き保存先を tauri-plugin-store に記憶するアダプタを追加
bafv4 Aug 25, 2026
51018c2
feat(files): Desktop の上書き保存先をセッションを跨いで復元する
bafv4 Aug 25, 2026
b84c4bf
feat(core): 未解決 BinaryRef の契約を binaryFields に集約する
bafv4 Aug 25, 2026
847820c
fix(store): 復元できなかったバイナリを種別ごとに集計する
bafv4 Aug 25, 2026
105c188
fix(files): バイナリ復元の欠落を通知し、未ロードのまま書き出さない
bafv4 Aug 25, 2026
9170220
perf(store): レイヤ/lock画像の並び替えを Set 化して O(n^2) を解消
bafv4 Aug 25, 2026
9c03a67
fix(core): 非有限値と0サイズを弾く数値ガードを coords.ts に集約
bafv4 Aug 25, 2026
3d4b44e
fix(buildPack): rows/columns/padding を正規化済みの値から出力する
bafv4 Aug 25, 2026
98dd6e7
fix(store): 数値ガードの適用と hydrate 時の破損 state 修復
bafv4 Aug 25, 2026
9d997f9
fix(ui): 解像度・エリアの数値入力から非有限値を弾く
bafv4 Aug 25, 2026
2174536
fix(persist): 永続 JSON が無いときに保存済みバイナリを全削除しないようにした
bafv4 Aug 25, 2026
8e547a4
perf(persist): 入力イベントごとの永続化を間引き、操作の区切りで強制フラッシュする
bafv4 Aug 25, 2026
21bc147
fix(persist): removeItem でバイナリ実体も回収し、実行中の書き込みの復活を防ぐ
bafv4 Aug 25, 2026
ca0357a
perf(desktop): Tauri のバイナリ IPC を 10進 JSON 配列から生バイトに置き換え
bafv4 Aug 25, 2026
739c773
fix(i18n): Desktop のネイティブ保存/エクスポートダイアログのタイトルを i18n 化
bafv4 Aug 25, 2026
c452a99
fix(persist): hydrate 直後の孤児掃除が同一タブの書き込みと競合しないようにした
bafv4 Aug 25, 2026
a65ccca
Merge branch 'fix/layout-group-spec' into integration/audit-2026-08
bafv4 Aug 25, 2026
4abd0ef
Merge branch 'fix/numeric-safety' into integration/audit-2026-08
bafv4 Aug 25, 2026
fdbfafc
Merge branch 'perf/preview-render' into integration/audit-2026-08
bafv4 Aug 25, 2026
a666cfe
Merge branch 'perf/editor-rerender' into integration/audit-2026-08
bafv4 Aug 25, 2026
62eb62f
Merge branch 'fix/pack-read-root' into integration/audit-2026-08
bafv4 Aug 25, 2026
fefc225
Merge branch 'perf/tauri-binary-ipc' into integration/audit-2026-08
bafv4 Aug 25, 2026
07af476
Merge branch 'feat/desktop-save-target-persist' into integration/audi…
bafv4 Aug 25, 2026
b02fcb6
Merge branch 'fix/binary-restore-integrity' into integration/audit-20…
bafv4 Aug 25, 2026
f2c2fc4
Merge branch 'fix/upload-error-handling' into integration/audit-2026-08
bafv4 Aug 25, 2026
dd8d6eb
Merge branch 'perf/lazy-load' into integration/audit-2026-08
bafv4 Aug 25, 2026
f1b2d22
Merge branch 'fix/ui-small-issues' into integration/audit-2026-08
bafv4 Aug 25, 2026
ae6f7d4
Merge branch 'perf/persist-writes' into integration/audit-2026-08
bafv4 Aug 25, 2026
240c193
Merge branch 'chore/i18n-and-version-hygiene' into integration/audit-…
bafv4 Aug 25, 2026
5738c76
docs(spec): SeedQueue 実ソースで確認した失敗モードと lock.png の挙動を仕様書に反映
bafv4 Aug 25, 2026
c132563
chore(deps): 未使用の @tauri-apps/plugin-fs 削除に合わせて lockfile を更新
bafv4 Aug 25, 2026
512b0ca
feat(header): ヘッダーのタイトル横に最新リリースページへのリンクを追加
bafv4 Aug 25, 2026
6a0dae7
feat(lock): lock 画像の重み付き抽選(seedqueue.weight / defaultWeight)に対応
bafv4 Aug 25, 2026
ed304dd
chore(release): v3.2.0(バージョン更新)
bafv4 Aug 26, 2026
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
49 changes: 43 additions & 6 deletions REWRITE_SPEC.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,23 @@ SeedQueue が参照するリソース識別子(`assets/seedqueue/` 配下)
| `replaceLockedInstances` | boolean | — | `false` | — |
| `mainFillOrder` | `"FORWARD"`/`"BACKWARD"`/`"RANDOM"` | — | `FORWARD` | main の埋め順 |

> **実ソースで確定した失敗モード**(2026-08-25、`Layout.java` を確認)。いずれも `createLayout` の
> `catch (Exception)` に落ち、警告トーストを出して**カスタムレイアウト全体が破棄**される(=既定グリッドに戻る)。
> パックが「読まれているのに効かない」ように見えるため、出力側で必ず避けること。
>
> - `locked` / `preparing` で `rows`/`columns` を**省略すると NullPointerException**。
> `Group.fromJson` は main にだけ `SeedQueue.config.rows/columns` を既定値として渡し、
> それ以外は `defaultRows == null` の分岐で `jsonObject.get("rows")` を無条件に触るため。
> **`rows`/`columns` を省略してよいのは `main` だけ。**
> - `x`/`y`/`width`/`height` は `has()` 検査なしの `getAsJsonPrimitive` で読むため、
> **1 つでも欠けると NullPointerException**。Group と positions の全要素で 4 つとも必須。
> - `rows`/`columns` が負だと `new Pos[rows * columns]` が `NegativeArraySizeException`。
> `0` は例外にならないが空配列(インスタンスが 1 つも表示されない)になる。
> - `main.cosmetic: true` は `IllegalArgumentException`。
> - `mainFillOrder` が enum 名以外だと `valueOf` が例外。
> - `instance_background` / `instance_overlay` は `!has(...) || getAsBoolean()` なので**省略時 true**。
> よって出力するのは `false` のときだけでよい。

**Group** は「グリッド指定」または「`positions` 明示指定」のいずれか:

| キー | 型 | 既定 | 備考 |
Expand Down Expand Up @@ -336,13 +353,25 @@ SeedQueue(`LockTexture.createLockTextures`)の読み込み順は厳密に次
つまり **複数画像でも 1 枚目は必ず `lock.png`、2 枚目以降が `lock-1.png`, `lock-2.png`, …**。

- **正しい出力**:N 枚なら `lock.png`(1枚目), `lock-1.png`(2枚目), `lock-2.png`(3枚目), …
- **旧アプリのバグ**:2 枚以上のとき `lock.png` を作らず `lock-1.png` から始めていた。SeedQueue は `lock.png` の
読み込みに失敗すると `lock-1.png` 以降を**一切探さない**ため、ロック画像が 1 枚も読まれない。新実装で是正する。
- **旧アプリのバグ**:2 枚以上のとき `lock.png` を作らず `lock-1.png` から始めていた。新実装で是正する。
- 訂正(2026-08-25、`LockTexture.createLockTextures` の実ソースで確認):以前ここに書いていた
「`lock.png` が無いと以降を一切読まない」は不正確。リソースパックは MOD のアセットに**重なる**ため
`lock.png` は MOD 同梱版が必ず解決する。パックが `lock-1.png` だけを入れると
**1 枚目=MOD 既定、2 枚目=パックの画像**という意図しない組み合わせになる。
走査は `lock-<現在読めた枚数>.png` を条件にした do-while なので、番号は詰まっている必要がある。
- 結論として「1 枚目は必ず `lock.png` を出す」という実装方針は変わらない。
- サイズ自由(既定 lock.png は 16x26)。SeedQueue は読み込んだ寸法でアスペクト比を保持する。**正方形/固定サイズ要件はない**。
- 無効化:透明 PNG を `lock.png` として上書きする(プレースホルダ。サイズはアプリ任意で 128x128 とする)。
ファイルを置かないと MOD 既定の lock.png にフォールバックするため、無効化には透明上書きが必要。
- 任意のメタ:`<lock>.png.mcmeta` に `{"seedqueue": {"weight": N}}` で重み付き抽選、`lock.png` には
`{"seedqueue": {"defaultWeight": N}}` で既定重み。lock もアニメ可。いずれも機能拡充の候補。
- **重み付き抽選(実装済み)**:`<lock>.png.mcmeta` に `{"seedqueue": {"weight": N}}`、
`lock.png.mcmeta` に `{"seedqueue": {"defaultWeight": N}}`。`LockTexture.java` で確認した意味論:
- `defaultWeight` は **`lock.png` のメタデータからのみ**読む。読めなければ `1`。
- 各画像の `weight` が `0`(= GSON がフィールド未指定を 0 にする)なら `defaultWeight` で埋める。
- 実効値は `Math.max(1, weight)`。抽選は `random.nextInt(実効重みの総和)` を累積で引くので、
選ばれる確率は **実効重み ÷ 総和**。
- 本アプリは既定値どおり(`defaultWeight` が 1/個別重みが既定と同値)のときは `.mcmeta` を出さない。
取り込んだ `.mcmeta` の `seedqueue` 以外のセクション(`animation` 等)は保持して書き戻す。
- lock はアニメ可(`animation` セクション)。アニメーションの編集自体は未対応(取り込み時に保持するのみ)。

### 6.6 sounds.json / sounds

Expand All @@ -365,12 +394,20 @@ SeedQueue のサウンドイベントは **13 種**(`SeedQueueSounds.java`)
| `open_wall` | Wall を開く | — |
| `bypass_wall` | Wall をバイパス | — |

`sounds.json` の各エントリは `{ "sounds": ["seedqueue:<name>" または "<file>"] }`。MC の規則上、上書き時に
`sounds.json` の各エントリは `{ "sounds": ["seedqueue:<name>"] }`。MC の規則上、上書き時に
既定音と二重再生させないため**上書きするイベントには `"replace": true` を付ける**。`sounds: []` で無音。

**サウンド名は名前空間付き・拡張子なしで書く**(mod 本体の `assets/seedqueue/sounds.json` を直接確認して確定。
確認日 2026-08-25。実体は `"lock_instance": { "sounds": ["seedqueue:lock_instance"] }`)。
MC はサウンド名を `assets/<ns>/sounds/` 相対のパスとして解釈し `.ogg` を**自動で付加する**ため、
名前に拡張子を書くと `assets/seedqueue/sounds/<event>.ogg.ogg` を探しに行き**黙って無音になる**。

- **default(内蔵音を使う)**:そのイベントを `sounds.json` に書かない(MOD 既定にフォールバック)。
- **off(無音)**:`{ "replace": true, "sounds": [] }`。
- **custom(独自音)**:`assets/seedqueue/sounds/<event>.ogg` を配置し `{ "replace": true, "sounds": ["<event>.ogg"] }`。
- **custom(独自音)**:`assets/seedqueue/sounds/<event>.ogg` を配置し `{ "replace": true, "sounds": ["seedqueue:<event>"] }`。

> `parsePack` は既存パックの読込互換のため、`seedqueue:<event>` / `<event>` / `<event>.ogg` の 3 形式を
> 受け付ける(`<event>.ogg` は v3.1.0 以前の誤った出力で作られたパック向けの後方互換)。

> 旧アプリは 6 イベントしか扱わず、`reset_instance` を独立イベントとして扱わない・`play_instance`/`schedule_*`/
> `open_wall`/`bypass_wall`/`scheduled_join_warning` を欠いていた。新実装は 13 イベントを正として UI を設計する
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "wall-maker-v3",
"private": false,
"version": "v3.1.0",
"version": "3.2.0",
"type": "module",
"license": "GPL-3.0-or-later",
"engines": {
Expand All @@ -22,7 +22,6 @@
"@tailwindcss/vite": "^4.3.2",
"@tauri-apps/api": "^2.11.1",
"@tauri-apps/plugin-dialog": "^2.7.1",
"@tauri-apps/plugin-fs": "^2.5.1",
"@tauri-apps/plugin-opener": "^2.5.4",
"@tauri-apps/plugin-os": "^2.3.2",
"@tauri-apps/plugin-store": "^2.4.3",
Expand Down
10 changes: 0 additions & 10 deletions pnpm-lock.yaml

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

2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

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

6 changes: 5 additions & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
[package]
name = "wall-maker-v3"
version = "3.1.0"
# ここは crate 自体のバージョン。Cargo には外部ファイル(package.json)を参照する手段が
# ないため、**リリース時に package.json の `version` と手動で合わせること**。
# アプリとして配布されるバージョンは `tauri.conf.json` の `version`(= `../package.json`
# 参照)が使われるので、ここがズレてもバンドル成果物のバージョンは package.json 由来になる。
version = "3.2.0"
description = "SeedQueue Wall Maker — Minecraft Speedrunning 用 SeedQueue リソースパックエディタ"
authors = ["bafv4"]
edition = "2021"
Expand Down
Loading
Loading