From 850e4566de30ef2b9468949a07f0e124501a3cd5 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sun, 5 Jul 2026 14:56:09 +0900 Subject: [PATCH 1/5] enable etc2 --- examples/ParticleEffect/project.godot | 1 + examples/Ringo/project.godot | 1 + examples/Scripting/project.godot | 1 + examples/allAttributeV7/project.godot | 1 + examples/allPartsV7/project.godot | 1 + examples/overall/project.godot | 4 ++++ examples/overall_gdextension/project.godot | 3 +-- 7 files changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/ParticleEffect/project.godot b/examples/ParticleEffect/project.godot index 3fd4fbd..cff90c9 100644 --- a/examples/ParticleEffect/project.godot +++ b/examples/ParticleEffect/project.godot @@ -21,6 +21,7 @@ config/icon="res://icon.svg" [rendering] +textures/vram_compression/import_etc2_astc=true renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" diff --git a/examples/Ringo/project.godot b/examples/Ringo/project.godot index 52023c3..e8fbd17 100644 --- a/examples/Ringo/project.godot +++ b/examples/Ringo/project.godot @@ -21,6 +21,7 @@ config/icon="res://icon.svg" [rendering] +textures/vram_compression/import_etc2_astc=true renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" diff --git a/examples/Scripting/project.godot b/examples/Scripting/project.godot index 52023c3..e8fbd17 100644 --- a/examples/Scripting/project.godot +++ b/examples/Scripting/project.godot @@ -21,6 +21,7 @@ config/icon="res://icon.svg" [rendering] +textures/vram_compression/import_etc2_astc=true renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" diff --git a/examples/allAttributeV7/project.godot b/examples/allAttributeV7/project.godot index 73917eb..be51f71 100644 --- a/examples/allAttributeV7/project.godot +++ b/examples/allAttributeV7/project.godot @@ -20,6 +20,7 @@ config/icon="res://icon.svg" [rendering] +textures/vram_compression/import_etc2_astc=true renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" diff --git a/examples/allPartsV7/project.godot b/examples/allPartsV7/project.godot index 2ec4163..dd54af1 100644 --- a/examples/allPartsV7/project.godot +++ b/examples/allPartsV7/project.godot @@ -20,6 +20,7 @@ config/icon="res://icon.svg" [rendering] +textures/vram_compression/import_etc2_astc=true renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" diff --git a/examples/overall/project.godot b/examples/overall/project.godot index a2ee474..84a1f16 100644 --- a/examples/overall/project.godot +++ b/examples/overall/project.godot @@ -19,4 +19,8 @@ run/main_scene="uid://dnijei7f6aclq" config/features=PackedStringArray("4.6", "GL Compatibility") config/icon="res://icon.svg" +[rendering] + +textures/vram_compression/import_etc2_astc=true + diff --git a/examples/overall_gdextension/project.godot b/examples/overall_gdextension/project.godot index 89b8263..8b5c709 100644 --- a/examples/overall_gdextension/project.godot +++ b/examples/overall_gdextension/project.godot @@ -28,5 +28,4 @@ config/icon="res://icon.svg" rendering_device/driver.windows="d3d12" renderer/rendering_method="gl_compatibility" renderer/rendering_method.mobile="gl_compatibility" - - +textures/vram_compression/import_etc2_astc=true From f6513ff4bdc6ab024be74bacd2105b6b7e110666 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sun, 5 Jul 2026 15:26:35 +0900 Subject: [PATCH 2/5] add export.md and limitations.md and improve docs. --- docs/en/index.md | 2 ++ docs/en/limitations.md | 34 +++++++++++++++++++++++++++++++ docs/en/setup/build.md | 41 ++++++++++++++++++++++++++++++++++++++ docs/en/workflow/export.md | 31 ++++++++++++++++++++++++++++ docs/ja/index.md | 2 ++ docs/ja/limitations.md | 34 +++++++++++++++++++++++++++++++ docs/ja/setup/build.md | 41 ++++++++++++++++++++++++++++++++++++++ docs/ja/workflow/export.md | 31 ++++++++++++++++++++++++++++ 8 files changed, 216 insertions(+) create mode 100644 docs/en/limitations.md create mode 100644 docs/en/workflow/export.md create mode 100644 docs/ja/limitations.md create mode 100644 docs/ja/workflow/export.md diff --git a/docs/en/index.md b/docs/en/index.md index 0362eb8..8917f26 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -18,12 +18,14 @@ Animation playback uses `libssruntime` provided by [SpriteStudio-SDK](https://gi - [Integration with AnimationPlayer](workflow/animation_player.md) - [Asset Import and Editor Integration](workflow/usage_asset_pipeline.md) (start here for the initial `.sspj` import) - [Scripting and Events](workflow/usage_scripting.md) + - [Exporting Your Project](workflow/export.md) - **Advanced Topics** - [CLI Conversion and Automation](workflow/import.md) - [Performance Tuning and Advanced Settings](workflow/tips.md) - **API Reference** - [SpriteStudioPlayer2D](api/player.md) - [Resource Classes](api/resource.md) +- [Limitations & Scope](limitations.md) - [Migration from v1.x](migration_from_v1.md) ## Key Features diff --git a/docs/en/limitations.md b/docs/en/limitations.md new file mode 100644 index 0000000..4476add --- /dev/null +++ b/docs/en/limitations.md @@ -0,0 +1,34 @@ +# Limitations & Scope + +Constraints and platform-specific caveats to be aware of when shipping with the current SpriteStudio Player for Godot. For the list of what *is* supported, see the [Key Features](index.md#key-features) and workflow guides. + +> [!NOTE] +> This is a living document. Items are added as they are confirmed; wording and coverage may change as the plugin evolves. + +## Platforms & Export + +The plugin ships in two build variants — **GDExtension** and **custom module** — and both can be exported to every Godot target. Build and execution are actively verified on **Windows / macOS**; the other targets are supported but less frequently exercised. See [Build Guide](setup/build.md) for the export flow of each. + +Per-platform caveats to keep in mind: + +- **macOS (GDExtension)** — released as a `universal` build (`arch=universal`). +- **iOS** — requires macOS + Xcode, and only `template_debug` / `template_release` are produced (no editor target). +- **Android** — the runtime is shipped as a native library placed under the matching ABI directory (`arm64-v8a` / `armeabi-v7a` / `x86_64`); build only the ABI of the device/emulator you run on. +- **Web** — see the dedicated section below. + +## Web (WASM) + +> [!WARNING] +> - **Single-threaded (`nothread`) only.** On the Web the plugin runs without threads. The upside is that no cross-origin isolation (COOP/COEP) headers are required, so a plain HTTP server is enough to run an export. Build the extension with `threads=no`. +> - **WebAssembly SIMD is required.** The runtime is built with WebAssembly SIMD instructions and will **not run on browsers without SIMD support**. Treat SIMD support as a browser requirement for your distribution. +> - **GDExtension on the Web needs a dlink-enabled engine template.** The official Godot Web export templates do not support GDExtension libraries. You must supply an engine template built with `dlink_enabled=yes` and turn on **"Extensions Support"** in the export preset — otherwise the exported page fails with *"GDExtension libraries are not supported by this engine version."* See [Exporting Your Project → Web](workflow/export.md#web) for the steps. (The **custom module** variant embeds the code into the engine itself and does not need this.) + +## Playback Feature Constraints + +These come from the shared `libssruntime` and therefore apply regardless of build variant. + +> [!WARNING] +> - **`independent=true` parts (Instance / Effect) do not reverse or seek correctly.** An `independent=true` child runs on its own real-time clock, detached from the parent timeline. Parent **reverse playback** and **seeking** break it; only **forward** playback (including forward frame-skips) is correct. Prefer authoring without `independent=true` for animations that may be played in reverse or seeked. +> - **Seeking does not fire the events it skips over.** Jumping the playhead directly (e.g. setting the frame) does **not** emit the `UserData` / `Signal` / `Audio` events on the frames passed over — only the destination frame's events fire. If you need every intermediate event, advance the animation step by step instead of jumping. +> - **No reverse audio.** Sounds fire only while the animation advances forward in time. When the effective direction is backward (reverse direction, ping-pong return, or negative speed), audio events are skipped — audio cannot be played in reverse. +> - **Animation blending is same-`.ssab` only.** Cross-`.ssab` (cross-resource) blending is not supported, and every blended animation must assign the **same Cell to the same part**; mismatched Cells cause size / pivot mismatches that break the pose. diff --git a/docs/en/setup/build.md b/docs/en/setup/build.md index c48841f..26a6f63 100644 --- a/docs/en/setup/build.md +++ b/docs/en/setup/build.md @@ -166,6 +166,13 @@ If you want to debug the C++ code (`ss_player/`) of the plugin embedded as a cus To verify and debug whether the custom module or GDExtension works correctly in the exported application, using the headless export from the CLI is convenient. +> [!IMPORTANT] +> Common export pitfalls (all platforms): +> - **Build the exact `target` you export with.** An `editor` build alone is not enough — `--export-debug` needs the `template_debug` library and `--export-release` needs `template_release`. If those were never built, the export still "succeeds" but ships an empty/missing extension library (on macOS this surfaces as a `CodeSign: Invalid binary format` error on the embedded framework). +> - **The extension architecture is bounded by the runtime slices you have.** The GDExtension links `libssruntime` from `ss_player/runtime/libs//`; you can only build the architectures present there. For example, with an `arm64`-only macOS runtime you cannot produce a `universal` / `x86_64` extension — set the preset's `binary_format/architecture` to match (e.g. `arm64`). The engine template can still be `universal`; a single-arch extension just won't load on the missing arch. +> - **Enable ETC2/ASTC for `universal` / `arm64` / mobile exports.** Set `rendering/textures/vram_compression/import_etc2_astc=true` in the project (`project.godot` → `[rendering]`), otherwise the export aborts with *"Cannot export … with the ETC2/ASTC texture format disabled."* +> - **Export templates must match the editor version.** Setting `custom_template/debug` / `custom_template/release` bypasses the version check (this is how a template built from the bundled `godot/` source can be reused). Set **both** debug and release paths even for a debug-only export — Godot validates both and otherwise reports the release template as missing. + The following is the flow for building/installing templates and exporting a sample project. (The example below uses macOS) 1. **Build the runtime and templates** @@ -218,6 +225,40 @@ python3 -m http.server 8000 After starting the server, access `http://localhost:8000` in your browser to verify it works. (Since this plugin operates with `nothread` on the Web, it can be launched with a simple HTTP server without requiring special CORS headers.) +#### GDExtension on the Web (Extensions Support / `dlink`) + +The official Godot Web export templates do **not** support GDExtension libraries. If you export the **GDExtension** build variant for the Web with a stock template, the page fails at startup with: + +> GDExtension libraries are not supported by this engine version. Enable "Extensions Support" for your export preset and/or build your custom template with "dlink_enabled=yes". + +To load a GDExtension on the Web, you need an engine template built with dynamic linking enabled (`dlink_enabled=yes`). Build one from the bundled `godot/` source, matching the `threads` mode of your extension (this plugin ships `nothread`, so use `threads=no`): + +```bash +# Build dlink-enabled Web templates from source (nothreads) +cd godot +scons platform=web target=template_debug dlink_enabled=yes threads=no +scons platform=web target=template_release dlink_enabled=yes threads=no +# → godot/bin/godot.web.template_debug.wasm32.nothreads.dlink.zip +# → godot/bin/godot.web.template_release.wasm32.nothreads.dlink.zip +``` + +Then install the built templates so Godot can resolve them by name: + +```bash +./scripts/install-template.sh web +# installs → //web_nothreads_dlink_debug.zip +# web_nothreads_dlink_release.zip +``` + +Once these are installed, exporting only requires turning on **Extensions Support** in the Web preset — Godot auto-selects the matching `..._dlink_...` template by name, so no `custom_template` is needed. The preset side (from a plugin user's perspective) is covered in [Exporting Your Project → Web](../workflow/export.md#web). + +> If you would rather not install them into Godot's templates folder, you can instead point `custom_template/debug` / `custom_template/release` in the `Web` preset directly at the built `*.dlink.zip` files. + +A dlink template splits the engine into a small main module plus a large `godot.side.wasm`; after export you will see a corresponding `index.side.wasm` alongside `index.wasm`, which confirms the dlink template was used. + +> [!NOTE] +> `dlink` / *Extensions Support* is required only for the **GDExtension** build variant. The **custom module** variant compiles the plugin into the engine, so its Web template is the ordinary (non-`dlink`) `web_nothreads_{debug,release}.zip` produced by `release-web.sh` (via `build.sh`) and installed the same way — with no `dlink_enabled` and no *Extensions Support* in the preset. + ### Android Platform Export and Testing Android export templates are template APKs packaged by the engine's Gradle project. Unlike the desktop platforms, the template build therefore has three stages (runtime → per-ABI engine libraries → Gradle packaging) before `install-template.sh`. diff --git a/docs/en/workflow/export.md b/docs/en/workflow/export.md new file mode 100644 index 0000000..7f1283e --- /dev/null +++ b/docs/en/workflow/export.md @@ -0,0 +1,31 @@ +# Exporting Your Project + +Once your scene plays correctly in the editor, you export it like any other Godot project (**Project → Export…**). SpriteStudioPlayer runs in exported builds on every Godot target. There are only a few plugin-specific points to know. + +## General + +- **GDExtension variant** — the native library lives in your project's `addons/spritestudio/bin/`, and Godot bundles it into the export automatically. Desktop targets need nothing extra. +- **Custom module variant** — the plugin is compiled into the engine, so there is nothing plugin-specific to configure at export time. +- **Mobile / universal targets** — if an export stops with a message about the *ETC2/ASTC texture format being disabled*, enable **Project → Project Settings → Rendering → Textures → VRAM Compression → Import ETC2 ASTC**, then re-export. + +## Web + +Web builds have two plugin-specific requirements when you use the **GDExtension** variant. + +1. **Enable "Extensions Support" in the Web export preset.** + In the Export dialog, select your **Web** preset → **Options** → turn on **Extensions Support**. GDExtension libraries only load on the Web when the engine template supports dynamic linking, and this option tells Godot to use that template. + +2. **The dlink-enabled Web export templates must be installed.** + The stock Godot Web templates do not support GDExtension. You need the `web_nothreads_dlink_debug.zip` / `web_nothreads_dlink_release.zip` templates installed in your Godot export-templates folder. Building and installing them is an advanced step covered in the [Build Guide → GDExtension on the Web](../setup/build.md#web-platform-export-and-testing). Once they are in place, enabling **Extensions Support** is all the preset needs — Godot finds the right template automatically. + +> [!WARNING] +> If a Web build fails at startup with *"GDExtension libraries are not supported by this engine version…"*, one of the two requirements above is missing (Extensions Support is off, or the dlink templates are not installed). + +Additional notes for the Web: + +- The plugin runs **single-threaded (`nothread`)** on the Web, so leave **Thread Support** off in the preset. A plain HTTP server is enough to test the export — no special cross-origin (COOP/COEP) headers are required. +- A working GDExtension Web export produces an `index.side.wasm` next to `index.wasm`; its presence confirms the dlink template was used. +- The runtime uses **WebAssembly SIMD**, so the target browser must support it. + +> [!NOTE] +> The **custom module** variant needs none of the steps above — no *Extensions Support* and no dlink template — because the plugin is compiled into the engine. It still runs single-threaded on the Web, and (like every custom-module target) it uses **your own engine-built Web template**, which already contains the plugin, rather than a stock Godot template. That build/install flow is described in the [Build Guide](../setup/build.md). diff --git a/docs/ja/index.md b/docs/ja/index.md index 2fd8f2f..81e75b9 100644 --- a/docs/ja/index.md +++ b/docs/ja/index.md @@ -18,12 +18,14 @@ - [AnimationPlayer との連携](workflow/animation_player.md) - [アセットのインポートとエディタ連携](workflow/usage_asset_pipeline.md)(初回の `.sspj` インポートはこちら) - [スクリプト制御とイベント](workflow/usage_scripting.md) + - [プロジェクトのエクスポート](workflow/export.md) - **応用** - [CLI コンバートと自動化](workflow/import.md) - [パフォーマンスチューニングと高度な設定](workflow/tips.md) - **API リファレンス** - [SpriteStudioPlayer2D](api/player.md) - [リソース管理クラス](api/resource.md) +- [仕様と制約事項](limitations.md) - [v1.x からのマイグレーション](migration_from_v1.md) ## 主な機能 (Key Features) diff --git a/docs/ja/limitations.md b/docs/ja/limitations.md new file mode 100644 index 0000000..ee4f9fa --- /dev/null +++ b/docs/ja/limitations.md @@ -0,0 +1,34 @@ +# 仕様と制約事項 (Limitations & Scope) + +現在の SpriteStudio Player for Godot でアプリを配信する際に把握しておくべき制約と、プラットフォーム固有の注意点をまとめています。サポートしている機能については [主な機能](index.md#主な機能-key-features) および各ワークフローガイドを参照してください。 + +> [!NOTE] +> このドキュメントは随時更新されます。確認できた項目から追記しており、プラグインの進化に応じて記述や範囲が変わる場合があります。 + +## プラットフォームとエクスポート + +本プラグインは **GDExtension** と **カスタムモジュール** の2つのビルド形態で提供され、いずれも Godot の全ターゲットへエクスポートできます。ビルドと実行は **Windows / macOS** で継続的に確認しています。その他のターゲットも対応していますが、検証頻度は低めです。各プラットフォームのエクスポート手順は [ビルドガイド](setup/build.md) を参照してください。 + +プラットフォーム固有の注意点: + +- **macOS (GDExtension)** — `universal` ビルド(`arch=universal`)としてリリースされます。 +- **iOS** — macOS + Xcode が必要で、生成されるのは `template_debug` / `template_release` のみです(editor ターゲットはありません)。 +- **Android** — ランタイムは対応する ABI ディレクトリ(`arm64-v8a` / `armeabi-v7a` / `x86_64`)に配置されるネイティブライブラリとして同梱されます。実行する端末/エミュレータの ABI のみビルドすれば十分です。 +- **Web** — 下記の専用セクションを参照してください。 + +## Web (WASM) + +> [!WARNING] +> - **シングルスレッド(`nothread`)のみ対応。** Web ではスレッドなしで動作します。利点として、クロスオリジン分離(COOP/COEP)ヘッダーが不要なため、単純な HTTP サーバーでエクスポート成果物を動かせます。拡張は `threads=no` でビルドしてください。 +> - **WebAssembly SIMD が必須。** ランタイムは WebAssembly SIMD 命令を用いてビルドされており、**SIMD 非対応のブラウザでは動作しません**。配信先のブラウザ要件として SIMD 対応を前提としてください。 +> - **Web で GDExtension を使うには dlink 対応のエンジンテンプレートが必要。** 公式の Godot Web エクスポートテンプレートは GDExtension ライブラリに対応していません。`dlink_enabled=yes` でビルドしたエンジンテンプレートを用意し、エクスポートプリセットで **「Extensions Support」** を有効にする必要があります。これを行わないと、書き出したページが *「GDExtension libraries are not supported by this engine version.」* で失敗します。手順は [プロジェクトのエクスポート → Web](workflow/export.md#web) を参照してください。(**カスタムモジュール**形態はコードをエンジン本体へ組み込むため、この対応は不要です。) + +## 再生機能の制約 + +以下は共通の `libssruntime` に由来する挙動のため、ビルド形態に関わらず適用されます。 + +> [!WARNING] +> - **`independent=true` パーツ(Instance / Effect)は逆再生・シークで正しく動作しません。** `independent=true` の子は親のタイムラインから切り離され、独自のリアルタイム時計で進行します。親の**逆再生**と**シーク**では破綻し、正しく描画されるのは**順方向**再生(順方向のフレームスキップを含む)のみです。逆再生やシークを行う可能性のあるアニメーションでは `independent=true` を使わない構成を推奨します。 +> - **シークで飛ばしたフレームのイベントは発火しません。** 再生位置を直接ジャンプ(フレーム指定)した場合、通過したフレーム上の `UserData` / `Signal` / `Audio` イベントは発火せず、移動先フレームのイベントのみが発火します。中間イベントを漏れなく扱いたい場合は、ジャンプせずにアニメーションを逐次進めてください。 +> - **オーディオの逆再生は非対応。** 音はアニメーションが時間軸上を順方向に進むときのみ発火します。実質的な進行方向が逆(逆方向設定・ピンポンの復路・負の速度)のときは音声イベントがスキップされます(音声は逆再生できないため)。 +> - **アニメーションブレンドは同一 `.ssab` 内のみ。** `.ssab`(リソース)をまたぐブレンドは非対応で、ブレンドする全アニメーションは **同一パーツに同一 Cell を割り当てている** 必要があります。Cell が異なるとサイズ・pivot のミスマッチで pose が崩れます。 diff --git a/docs/ja/setup/build.md b/docs/ja/setup/build.md index 86aa396..526bd74 100644 --- a/docs/ja/setup/build.md +++ b/docs/ja/setup/build.md @@ -166,6 +166,13 @@ $env:PYTHONUTF8=1 開発したカスタムモジュールやGDExtensionが、ビルド後のアプリで正常に動作するか(エクスポートが成功するか)を確認・デバッグするには、CLIを用いたヘッドレスエクスポートが便利です。 +> [!IMPORTANT] +> エクスポート時の共通の注意点(全プラットフォーム): +> - **エクスポートする `target` を実際にビルドしておく。** `editor` ビルドだけでは不十分です。`--export-debug` は `template_debug` ライブラリを、`--export-release` は `template_release` を必要とします。これらを未ビルドのままだとエクスポートは「成功」しても、拡張ライブラリが空/欠落した状態で書き出されます(macOS では同梱 framework に対する `CodeSign: Invalid binary format` エラーとして表面化します)。 +> - **拡張のアーキテクチャは手元の runtime スライスに依存する。** GDExtension は `ss_player/runtime/libs//` の `libssruntime` をリンクするため、そこに存在するアーキテクチャしかビルドできません。例えば macOS の runtime が `arm64` のみの場合、`universal` / `x86_64` の拡張は作れません。プリセットの `binary_format/architecture` を合わせてください(例: `arm64`)。エンジンテンプレートは `universal` のままで構いません(単一アーキの拡張が、欠けているアーキでロードされないだけです)。 +> - **`universal` / `arm64` / モバイル向けは ETC2/ASTC を有効化する。** プロジェクトに `rendering/textures/vram_compression/import_etc2_astc=true` を設定してください(`project.godot` の `[rendering]`)。未設定だと *「ETC2/ASTC テクスチャフォーマットが無効なため … エクスポートできません」* でエクスポートが中断します。 +> - **エクスポートテンプレートはエディタのバージョンと一致が必要。** `custom_template/debug` / `custom_template/release` を指定するとこのバージョンチェックを回避できます(同梱の `godot/` ソースからビルドしたテンプレートを流用できるのはこのためです)。debug のみのエクスポートでも debug / release **両方** のパスを設定してください。Godot は両方を検証し、未設定だと release テンプレートが見つからないと報告します。 + 以下の流れで、手元でテンプレートをビルド・インストールし、サンプルプロジェクトをエクスポートします。(以下はmacOSの例です) 1. **ランタイムとテンプレートのビルド** @@ -213,6 +220,40 @@ python3 -m http.server 8000 サーバー起動後、ブラウザで `http://localhost:8000` にアクセスすると動作確認ができます。 (本プラグインは Web においては `nothread` での動作となるため、特殊なCORSヘッダーなしの単純なHTTPサーバーで起動可能です) +#### Web での GDExtension(Extensions Support / `dlink`) + +公式の Godot Web エクスポートテンプレートは GDExtension ライブラリに **対応していません**。**GDExtension** 形態を素のテンプレートで Web エクスポートすると、起動時に次のエラーで失敗します。 + +> GDExtension libraries are not supported by this engine version. Enable "Extensions Support" for your export preset and/or build your custom template with "dlink_enabled=yes". + +Web で GDExtension を読み込むには、動的リンクを有効にした(`dlink_enabled=yes`)エンジンテンプレートが必要です。同梱の `godot/` ソースから、拡張の `threads` モードに合わせてビルドします(本プラグインは `nothread` 版を提供するため `threads=no`)。 + +```bash +# dlink 対応の Web テンプレートをソースからビルド(nothreads) +cd godot +scons platform=web target=template_debug dlink_enabled=yes threads=no +scons platform=web target=template_release dlink_enabled=yes threads=no +# → godot/bin/godot.web.template_debug.wasm32.nothreads.dlink.zip +# → godot/bin/godot.web.template_release.wasm32.nothreads.dlink.zip +``` + +続いて、ビルドしたテンプレートをインストールし、Godot が名前で解決できるようにします。 + +```bash +./scripts/install-template.sh web +# インストール先 → //web_nothreads_dlink_debug.zip +# web_nothreads_dlink_release.zip +``` + +インストール後は、Web プリセットで **Extensions Support** を ON にするだけでエクスポートできます。Godot が名前一致で `..._dlink_...` テンプレートを自動選択するため、`custom_template` の指定は不要です。プリセット側の操作(利用者視点)は [プロジェクトのエクスポート → Web](../workflow/export.md#web) を参照してください。 + +> Godot のテンプレートフォルダにインストールしたくない場合は、代わりに `Web` プリセットの `custom_template/debug` / `custom_template/release` にビルドした `*.dlink.zip` を直接指定することもできます。 + +dlink テンプレートはエンジンを小さなメインモジュールと大きな `godot.side.wasm` に分割します。エクスポート後に `index.wasm` と並んで `index.side.wasm` が出力されていれば、dlink テンプレートが使われた証拠です。 + +> [!NOTE] +> `dlink` / *Extensions Support* が必要なのは **GDExtension** 形態のみです。**カスタムモジュール** 形態はプラグインをエンジンにコンパイルするため、その Web テンプレートは `release-web.sh`(内部で `build.sh`)が生成する通常の(非 `dlink`)`web_nothreads_{debug,release}.zip` で、同じ手順でインストールします。`dlink_enabled` もプリセットの *Extensions Support* も不要です。 + ### Androidプラットフォームのエクスポートと動作確認 Android のエクスポートテンプレートは、エンジンの Gradle プロジェクトでパッケージされるテンプレートAPKです。そのためデスクトップ系と異なり、`install-template.sh` の前にテンプレートのビルドが3段階(ランタイム → ABIごとのエンジンライブラリ → Gradleパッケージ)になります。 diff --git a/docs/ja/workflow/export.md b/docs/ja/workflow/export.md new file mode 100644 index 0000000..85cbd72 --- /dev/null +++ b/docs/ja/workflow/export.md @@ -0,0 +1,31 @@ +# プロジェクトのエクスポート + +エディタ上でシーンが正しく再生できたら、あとは通常の Godot プロジェクトと同じ手順でエクスポートします(**プロジェクト → エクスポート…**)。SpriteStudioPlayer はすべての Godot ターゲットのエクスポート済みビルドで動作します。プラグイン固有の注意点はわずかです。 + +## 共通 + +- **GDExtension 形態** — ネイティブライブラリはプロジェクトの `addons/spritestudio/bin/` に含まれ、Godot が自動的にエクスポートへ同梱します。デスクトップ向けは追加設定不要です。 +- **カスタムモジュール形態** — プラグインはエンジンに組み込まれているため、エクスポート時にプラグイン固有の設定は不要です。 +- **モバイル / universal 向け** — *ETC2/ASTC テクスチャフォーマットが無効* という趣旨のメッセージでエクスポートが止まる場合は、**プロジェクト → プロジェクト設定 → レンダリング → テクスチャ → VRAM圧縮 → Import ETC2 ASTC** を有効にして再エクスポートしてください。 + +## Web + +**GDExtension** 形態で Web ビルドを行う場合、プラグイン固有の要件が2つあります。 + +1. **Web エクスポートプリセットで「Extensions Support」を有効にする。** + エクスポートダイアログで **Web** プリセット → **オプション** → **Extensions Support** を ON にします。GDExtension ライブラリは、エンジンテンプレートが動的リンクに対応している場合のみ Web で読み込まれます。このオプションが、そのテンプレートを使うよう Godot に指示します。 + +2. **dlink 対応の Web エクスポートテンプレートがインストールされている必要がある。** + 素の Godot Web テンプレートは GDExtension に対応していません。`web_nothreads_dlink_debug.zip` / `web_nothreads_dlink_release.zip` テンプレートを Godot のエクスポートテンプレートフォルダに導入しておく必要があります。これらのビルドと導入は上級者向けの手順で、[ビルドガイド → Web での GDExtension](../setup/build.md#webプラットフォームのエクスポートと動作確認) にまとめてあります。導入済みであれば、プリセット側は **Extensions Support** を ON にするだけで、Godot が適切なテンプレートを自動選択します。 + +> [!WARNING] +> Web ビルドが起動時に *「GDExtension libraries are not supported by this engine version…」* で失敗する場合、上記2つの要件のいずれかが欠けています(Extensions Support が OFF、または dlink テンプレートが未インストール)。 + +Web に関する補足: + +- 本プラグインは Web では **シングルスレッド(`nothread`)** で動作するため、プリセットの **Thread Support** は OFF のままにしてください。エクスポートの動作確認は単純な HTTP サーバーで十分で、特殊なクロスオリジン(COOP/COEP)ヘッダーは不要です。 +- 正常な GDExtension Web エクスポートでは `index.wasm` と並んで `index.side.wasm` が出力されます。これがあれば dlink テンプレートが使われた証拠です。 +- ランタイムは **WebAssembly SIMD** を利用するため、対象ブラウザが SIMD に対応している必要があります。 + +> [!NOTE] +> **カスタムモジュール** 形態では上記の手順はいずれも不要です(*Extensions Support* も dlink テンプレートも不要)。プラグインがエンジンにコンパイル済みのためです。ただし Web では同じくシングルスレッドで動作し、他の custom-module ターゲットと同様、素の Godot テンプレートではなく **自分でビルドしたエンジン入り Web テンプレート**(プラグインを含む)を使います。そのビルド/インストール手順は [ビルドガイド](../setup/build.md) を参照してください。 From 49876d0ad68dd2a2d5a5ac7eb437913436930062 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sun, 5 Jul 2026 16:12:19 +0900 Subject: [PATCH 3/5] fix iOS custom module build --- scripts/release-ios.sh | 18 ++++++++++++++++++ ss_player/SCsub | 6 +++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/scripts/release-ios.sh b/scripts/release-ios.sh index 2cc727f..7c4b125 100755 --- a/scripts/release-ios.sh +++ b/scripts/release-ios.sh @@ -16,6 +16,24 @@ for target in ${targets[@]}; do scripts/build.sh platform=ios arch=universal compiledb=no strip=yes target=${target} ios_simulator=yes done +# Assemble the simulator-universal archive. build.sh emits a per-arch simulator +# archive for each arch, but each is fat: libtool pulls in the whole fat +# libssruntime simulator slice (arm64+x86_64), so only the matching arch is +# "complete" (has the Godot objects too). Take the complete slice from each and +# lipo them into one clean arm64+x86_64 simulator library. +for target in ${targets[@]}; do + armsim="godot/bin/libgodot.ios.${target}.arm64.simulator.a" + x86sim="godot/bin/libgodot.ios.${target}.x86_64.simulator.a" + if [ -f "$armsim" ] && [ -f "$x86sim" ]; then + tmp_arm=$(mktemp -t ios_arm64sim).a + tmp_x86=$(mktemp -t ios_x86sim).a + lipo -thin arm64 "$armsim" -output "$tmp_arm" + lipo -thin x86_64 "$x86sim" -output "$tmp_x86" + lipo -create "$tmp_arm" "$tmp_x86" -output "godot/bin/libgodot.ios.${target}.simulator.universal.a" + /bin/rm -f "$tmp_arm" "$tmp_x86" + fi +done + # iOS requires .xcframework containing both device (arm64) and simulator (universal) binaries for target in ${targets[@]}; do if [ -f "godot/bin/libgodot.ios.${target}.arm64.a" ] && [ -f "godot/bin/libgodot.ios.${target}.simulator.universal.a" ]; then diff --git a/ss_player/SCsub b/ss_player/SCsub index 2f6ca00..2c4d99a 100644 --- a/ss_player/SCsub +++ b/ss_player/SCsub @@ -56,7 +56,11 @@ if env['target'] == 'editor': # missing source. Pass the static archive by full path instead. Other platforms # link it normally via -l from LIBPATH. if platform == "ios": - if env.get("ios_simulator", False): + # Godot's iOS detect.py declares BoolVariable(("simulator", "ios_simulator"), ...), + # so the flag is stored under env["simulator"] (the primary name). Reading the + # "ios_simulator" alias here always returns False, which would wrongly link the + # device slice into simulator builds. Honor "simulator" (with the alias as a fallback). + if env.get("simulator", env.get("ios_simulator", False)): slice_dir = "ios-arm64_x86_64-simulator" else: slice_dir = "ios-arm64" From 3d20fa1157d2672b58066862d1660a0f872d2d0b Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sun, 5 Jul 2026 16:42:56 +0900 Subject: [PATCH 4/5] fix iOS GDExtension Sample App bundle id --- SConstruct | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SConstruct b/SConstruct index a9076f2..16681b2 100644 --- a/SConstruct +++ b/SConstruct @@ -175,7 +175,10 @@ if platform in ["macos", "ios"]: plist_subst = { "${BUNDLE_LIBRARY}": file_name, "${BUNDLE_NAME}": "ssplayer-godot", - "${BUNDLE_IDENTIFIER}": "jp.co.cri-mw.spritestudio.ssplayer-godot.{}".format(env["target"]), + # CFBundleIdentifier allows only alphanumerics, '-' and '.', so sanitize the + # target name ("template_debug" -> "template-debug"); underscores make Xcode + # reject the embedded framework on iOS ("invalid CFBundleIdentifier"). + "${BUNDLE_IDENTIFIER}": "jp.co.cri-mw.spritestudio.ssplayer-godot.{}".format(env["target"].replace("_", "-")), "${BUNDLE_VERSION}": version, "${MIN_MACOS_VERSION}": "10.12", "${MIN_IOS_VERSION}": "12.0" From ddc714dde0ed99556ed11c2d57c604224740e7d6 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sun, 5 Jul 2026 16:49:45 +0900 Subject: [PATCH 5/5] update docs --- docs/en/setup/build.md | 40 ++++++++++++++++++++++++++++++++++++++++ docs/ja/setup/build.md | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/docs/en/setup/build.md b/docs/en/setup/build.md index 26a6f63..d3f2520 100644 --- a/docs/en/setup/build.md +++ b/docs/en/setup/build.md @@ -312,6 +312,46 @@ Android export templates are template APKs packaged by the engine's Gradle proje ``` The `dev_module` sample plays the `Knight_arrow` animation on `SpriteStudioPlayer2D` with autoplay, so a successful run renders the character on screen. +### iOS Platform Export and Testing + +iOS export requires **macOS with Xcode**. Godot generates an **Xcode project** (not a ready-to-run app) and then auto-runs `xcodebuild archive` for a device, which needs an Apple Developer account — so an **App Store Team ID must be set in the preset**, and the device-archive step fails without valid signing. For a quick, unsigned check, build the generated project for the **iOS Simulator** yourself. + +> [!IMPORTANT] +> **Self-built iOS templates do not bundle MoltenVK.** Godot's iOS engine is built with Vulkan, so the app binary hard-links `@rpath/MoltenVK.framework/MoltenVK` (confirm with `otool -L`). This is a property of the *engine build*, not the project's renderer — a GL Compatibility project links it too. The **official** Godot iOS templates ship `MoltenVK.xcframework`; the template produced by `release-ios.sh` does **not**. When testing a self-built template you must supply it yourself, or the app crashes at launch with `Library not loaded: @rpath/MoltenVK.framework/MoltenVK`. + +Simulator smoke-test of a self-built template (custom module shown; the GDExtension flow is identical with `dev_gdextension`): + +```bash +# 1. Export the Xcode project (Godot's device-archive step will fail on signing — that's expected) +mkdir -p bin_export/ios +./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless \ + --export-debug "iOS" "$(pwd)/bin_export/ios/dev_module.xcodeproj" || true + +# 2. Place MoltenVK where the Xcode project expects it (e.g. from the Vulkan SDK) +MVK="$HOME/VulkanSDK//iOS/lib/MoltenVK.xcframework" +cp -R "$MVK" bin_export/ios/MoltenVK.xcframework + +# 3. Build for the Simulator, unsigned +cd bin_export/ios +xcodebuild -project dev_module.xcodeproj -scheme dev_module \ + -sdk iphonesimulator -configuration Debug -derivedDataPath ./DerivedData \ + CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build +APP="DerivedData/Build/Products/Debug-iphonesimulator/dev_module.app" + +# 4. Embed MoltenVK into the app and ad-hoc re-sign (the simulator rejects the SDK's own signature) +cp -R "$MVK/ios-arm64_x86_64-simulator/MoltenVK.framework" "$APP/Frameworks/" +codesign --force --sign - "$APP/Frameworks/MoltenVK.framework" +codesign --force --sign - "$APP" + +# 5. Boot a simulator, install, launch, screenshot +DEV=$(xcrun simctl list devices available | grep -m1 -oE '\([0-9A-F-]{36}\)' | tr -d '()') +xcrun simctl boot "$DEV" && xcrun simctl install "$DEV" "$APP" +xcrun simctl launch "$DEV" com.crimw.devmodule +xcrun simctl io "$DEV" screenshot screen.png +``` + +> **Note:** The proper fix is to bundle `MoltenVK.xcframework` into the iOS template itself (`install-template.sh` / `misc/dist/apple_embedded_xcode`) so the export embeds and signs it automatically, matching the official templates. The manual steps above are only needed for **self-built** templates — end users on the official Godot editor and official export templates are unaffected. + ### GDExtension Export and Testing For GDExtensions (e.g., `dev_gdextension`), **rebuilding the engine itself or installing custom templates is unnecessary**. You can export as-is using the standard Godot editor and official export templates distributed by Godot. diff --git a/docs/ja/setup/build.md b/docs/ja/setup/build.md index 526bd74..3769687 100644 --- a/docs/ja/setup/build.md +++ b/docs/ja/setup/build.md @@ -307,6 +307,46 @@ Android のエクスポートテンプレートは、エンジンの Gradle プ ``` `dev_module` サンプルは `SpriteStudioPlayer2D` で `Knight_arrow` アニメーションを autoplay 再生するため、正常に動作すればキャラクターが画面に描画されます。 +### iOSプラットフォームのエクスポートと動作確認 + +iOS エクスポートには **macOS + Xcode** が必要です。Godot は **Xcode プロジェクト**(すぐ動くアプリではない)を生成し、続けて実機向けに `xcodebuild archive` を自動実行します。これには Apple Developer アカウントが必要なため、**プリセットに App Store Team ID の設定が必須**で、有効な署名が無いと実機 archive 段階で失敗します。署名なしで手早く確認するには、生成された Xcode プロジェクトを自分で **iOS シミュレータ**向けにビルドします。 + +> [!IMPORTANT] +> **自前ビルドの iOS テンプレートは MoltenVK を同梱しません。** Godot の iOS エンジンは Vulkan 有効でビルドされるため、アプリのバイナリが `@rpath/MoltenVK.framework/MoltenVK` を**ハードリンク**します(`otool -L` で確認可能)。これは*エンジンのビルド*の性質であり、プロジェクトのレンダラ設定とは無関係です(GL Compatibility のプロジェクトでもリンクされます)。**公式**の Godot iOS テンプレートは `MoltenVK.xcframework` を同梱しますが、`release-ios.sh` が生成するテンプレートは**同梱しません**。自前テンプレートで動作確認する場合は自分で供給する必要があり、無いと起動時に `Library not loaded: @rpath/MoltenVK.framework/MoltenVK` でクラッシュします。 + +自前テンプレートのシミュレータ動作確認(カスタムモジュールの例。GDExtension も `dev_gdextension` で同じ流れ): + +```bash +# 1. Xcode プロジェクトを生成(Godot の実機 archive 段階は署名で失敗するが想定内) +mkdir -p bin_export/ios +./godot/Godot.app/Contents/MacOS/Godot --path ./examples/dev_module/ --headless \ + --export-debug "iOS" "$(pwd)/bin_export/ios/dev_module.xcodeproj" || true + +# 2. Xcode プロジェクトが期待する場所へ MoltenVK を配置(例: Vulkan SDK から) +MVK="$HOME/VulkanSDK//iOS/lib/MoltenVK.xcframework" +cp -R "$MVK" bin_export/ios/MoltenVK.xcframework + +# 3. シミュレータ向けに署名なしでビルド +cd bin_export/ios +xcodebuild -project dev_module.xcodeproj -scheme dev_module \ + -sdk iphonesimulator -configuration Debug -derivedDataPath ./DerivedData \ + CODE_SIGNING_ALLOWED=NO CODE_SIGNING_REQUIRED=NO build +APP="DerivedData/Build/Products/Debug-iphonesimulator/dev_module.app" + +# 4. MoltenVK をアプリに埋め込み、ad-hoc 署名し直す(simulator は SDK 由来の署名を拒否するため) +cp -R "$MVK/ios-arm64_x86_64-simulator/MoltenVK.framework" "$APP/Frameworks/" +codesign --force --sign - "$APP/Frameworks/MoltenVK.framework" +codesign --force --sign - "$APP" + +# 5. シミュレータを起動してインストール・起動・スクショ +DEV=$(xcrun simctl list devices available | grep -m1 -oE '\([0-9A-F-]{36}\)' | tr -d '()') +xcrun simctl boot "$DEV" && xcrun simctl install "$DEV" "$APP" +xcrun simctl launch "$DEV" com.crimw.devmodule +xcrun simctl io "$DEV" screenshot screen.png +``` + +> **Note:** 本来の解決策は、iOS テンプレート自体(`install-template.sh` / `misc/dist/apple_embedded_xcode`)に `MoltenVK.xcframework` を同梱し、エクスポート時に自動で埋め込み・署名させて公式テンプレートと同等にすることです。上記の手動手順が要るのは**自前ビルド**のテンプレートの場合のみで、公式 Godot エディタ+公式エクスポートテンプレートを使う一般利用者には影響しません。 + ### GDExtension のエクスポートと動作確認 GDExtension(例: `dev_gdextension`)の場合、**エンジン本体の再ビルドやカスタムテンプレートのインストールは不要**です。Godot公式が配布している標準のGodotエディタとエクスポートテンプレートを使用して、そのままエクスポートが可能です。