diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..f1d91f6
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,81 @@
+name: Bug Report / バグ報告
+description: Create a report to help us improve SSPlayerForGodot. / 不具合の報告
+title: "[Bug]: "
+labels: ["bug"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thank you for reporting a bug! / 不具合の報告ありがとうございます!
+ Please provide as much information as possible to help us investigate. / 調査をスムーズに行うため、可能な限り詳細な情報を提供してください。
+
+ - type: textarea
+ id: description
+ attributes:
+ label: Description / 不具合の内容
+ description: A clear and concise description of what the bug is. / どのような不具合が発生しているか、簡潔に説明してください。
+ validations:
+ required: true
+
+ - type: textarea
+ id: reproduction
+ attributes:
+ label: Steps to Reproduce / 再現手順
+ description: Steps to reproduce the behavior. / 不具合を再現させるための手順を詳しく書いてください。
+ placeholder: |
+ 1. Open '...'
+ 2. Run '...'
+ 3. See error
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected_behavior
+ attributes:
+ label: Expected Behavior / 期待される動作
+ description: A clear and concise description of what you expected to happen. / 本来どのような動作を期待していたか説明してください。
+ validations:
+ required: true
+
+ - type: input
+ id: godot_version
+ attributes:
+ label: Godot Version / Godotのバージョン
+ description: What version of Godot are you using? / ご利用のGodotのバージョンを記載してください。
+ placeholder: e.g. 4.6.0-stable
+ validations:
+ required: true
+
+ - type: input
+ id: plugin_version
+ attributes:
+ label: Plugin Version / プラグインのバージョン
+ description: What version of this plugin are you using? (e.g., v1.0.0 or commit hash). / 利用している本プラグインのバージョンタグ(v1.0.0等)、またはコミットハッシュ。
+ validations:
+ required: true
+
+ - type: input
+ id: environment
+ attributes:
+ label: Operating System / OS
+ description: What OS are you developing on? / 開発を行っているOS。
+ placeholder: e.g. Windows 11 / macOS 14 / Ubuntu 22.04
+ validations:
+ required: true
+
+ - type: textarea
+ id: additional_context
+ attributes:
+ label: Additional Context & Error Logs / 補足情報・エラーログ
+ description: Add any other context or paste relevant error messages from the Godot output console here. / その他、不具合に関する補足情報や、Godotのコンソールに出力されたエラーメッセージを記載してください。
+
+ - type: markdown
+ attributes:
+ value: |
+ ---
+ **🚨 WARNING / 警告 🚨**
+ **DO NOT** attach proprietary `.sspj` project files or sensitive data to this public issue.
+ If you need to share reproduction data, please submit it privately via the [Help Center](https://www.webtech.co.jp/help/ja/spritestudio7/inquiries/ssplayer_tool/).
+
+ **絶対に** 機密情報や非公開の `.sspj` プロジェクトデータをここに添付しないでください。
+ 再現データの提供が必要な場合は、[公式ヘルプセンター](https://www.webtech.co.jp/help/ja/spritestudio7/inquiries/ssplayer_tool/)から非公開で送信してください。
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 0000000..b23c945
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,8 @@
+blank_issues_enabled: false
+contact_links:
+ - name: 💬 SpriteStudio Community / コミュニティ (使い方や質問)
+ url: https://spritestudio.jp/community/
+ about: Please ask general questions about how to use the SDK here. / SDKの使い方などの一般的なご質問はこちらのコミュニティをご利用ください。
+ - name: 🔒 Private Inquiries & Data Submission / 非公開でのご相談・データ送付
+ url: https://www.webtech.co.jp/help/ja/spritestudio7/inquiries/ssplayer_tool/
+ about: Use this for private inquiries or when sending sensitive reproduction data. / 非公開での相談や、再現データの送付が必要な場合は公式ヘルプセンターをご利用ください。
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 0000000..614184c
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,39 @@
+name: Feature Request / 機能要望
+description: Suggest an idea for this project. / 新機能や改善のアイデアを提案する
+title: "[Feature]: "
+labels: ["enhancement"]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thank you for suggesting a feature! / 機能のご提案ありがとうございます!
+
+ - type: textarea
+ id: problem
+ attributes:
+ label: Is your feature request related to a problem? / その要望は、何か困っていることに関連していますか?
+ description: A clear and concise description of what the problem is. / どのような課題や不便さがあるか、詳しく説明してください。
+ placeholder: |
+ I'm always frustrated when [...]
+ validations:
+ required: true
+
+ - type: textarea
+ id: solution
+ attributes:
+ label: Describe the solution you'd like / 実現したい解決策
+ description: A clear and concise description of what you want to happen. / どのような機能や動作を期待しているか説明してください。
+ validations:
+ required: true
+
+ - type: textarea
+ id: alternatives
+ attributes:
+ label: Describe alternatives you've considered / 他に検討した代替案
+ description: A clear and concise description of any alternative solutions or features you've considered. / 他に検討した解決策があれば記載してください。
+
+ - type: textarea
+ id: additional_context
+ attributes:
+ label: Additional Context / 補足情報
+ description: Add any other context or screenshots about the feature request here. / その他、機能に関する補足情報やスクリーンショットがあれば記載してください。
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..5a080ea
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,21 @@
+## Description
+
+Please include a summary of the changes and the related issue. Please also include relevant motivation and context.
+
+Fixes # (issue)
+
+## Type of change
+
+- [ ] Bug fix (non-breaking change which fixes an issue)
+- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
+- [ ] This change requires a documentation update
+
+## Checklist:
+
+- [ ] My code follows the style guidelines of this project
+- [ ] I have performed a self-review of my code
+- [ ] I have commented my code, particularly in hard-to-understand areas
+- [ ] I have made corresponding changes to the documentation
+- [ ] My changes generate no new warnings
+- [ ] Any dependent changes have been merged and published in downstream modules
diff --git a/.github/workflows/extension.yml b/.github/workflows/extension.yml
index 53f3021..c1ec785 100644
--- a/.github/workflows/extension.yml
+++ b/.github/workflows/extension.yml
@@ -1,5 +1,8 @@
name: release gdextension
on:
+ push:
+ tags:
+ - 'v*'
workflow_dispatch:
inputs:
godot_version:
@@ -15,6 +18,7 @@ on:
description: "Target Godot API version"
env:
+ GODOT_VERSION: ${{ inputs.godot_version || '4.6' }}
LANG: en_US.UTF-8
LC_ALL: en_US.UTF-8
PYTHONIOENCODING: utf8
@@ -105,14 +109,14 @@ jobs:
- name: build Linux
if: matrix.platform == 'linux'
run: |
- ./scripts/release-gdextension-linux.sh api_version=${{ inputs.godot_version }}
+ ./scripts/release-gdextension-linux.sh api_version=${{ env.GODOT_VERSION }}
- name: build macOS
if: matrix.platform == 'macos'
env:
DEV_ID_APPLICATION: ${{ secrets.DEV_ID_APPLICATION }}
run: |
- ./scripts/release-gdextension-macos.sh api_version=${{ inputs.godot_version }}
+ ./scripts/release-gdextension-macos.sh api_version=${{ env.GODOT_VERSION }}
for f in ./bin/macos/*.framework
do
@@ -124,7 +128,7 @@ jobs:
env:
DEV_ID_APPLICATION: ${{ secrets.DEV_ID_APPLICATION }}
run: |
- ./scripts/release-gdextension-ios.sh api_version=${{ inputs.godot_version }}
+ ./scripts/release-gdextension-ios.sh api_version=${{ env.GODOT_VERSION }}
# iOS ships XCFrameworks (device + simulator); sign the frameworks inside each slice.
for f in ./bin/ios/*.xcframework/*/*.framework
@@ -135,13 +139,13 @@ jobs:
- name: build Android
if: matrix.platform == 'android'
run: |
- ./scripts/release-gdextension-android.sh api_version=${{ inputs.godot_version }}
+ ./scripts/release-gdextension-android.sh api_version=${{ env.GODOT_VERSION }}
- name: build Windows
if: matrix.platform == 'windows'
shell: pwsh
run: |
- ./scripts/release-gdextension-windows.ps1 api_version=${{ inputs.godot_version }}
+ ./scripts/release-gdextension-windows.ps1 api_version=${{ env.GODOT_VERSION }}
Remove-Item -Recurse -Force ./bin/windows/*.exp
Remove-Item -Recurse -Force ./bin/windows/*.lib
@@ -149,7 +153,7 @@ jobs:
- name: build Web
if: matrix.platform == 'web'
run: |
- ./scripts/release-gdextension-web.sh api_version=${{ inputs.godot_version }}
+ ./scripts/release-gdextension-web.sh api_version=${{ env.GODOT_VERSION }}
- id: commit
uses: pr-mpt/actions-commit-hash@v4
@@ -157,7 +161,7 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
- name: extension-${{ inputs.godot_version }}-${{ matrix.platform }}-${{ steps.commit.outputs.short }}
+ name: extension-${{ env.GODOT_VERSION }}-${{ matrix.platform }}-${{ steps.commit.outputs.short }}
path: bin/
if-no-files-found: error
@@ -185,19 +189,31 @@ jobs:
cp ../misc/spritestudio.gdextension addons/spritestudio/
cp ../LICENSE.md addons/spritestudio/
- mv extension-${{ inputs.godot_version }}-android-${{ steps.commit.outputs.short }}/android addons/spritestudio/bin/
- mv extension-${{ inputs.godot_version }}-ios-${{ steps.commit.outputs.short }}/ios addons/spritestudio/bin/
- mv extension-${{ inputs.godot_version }}-macos-${{ steps.commit.outputs.short }}/macos addons/spritestudio/bin/
- mv extension-${{ inputs.godot_version }}-web-${{ steps.commit.outputs.short }}/web addons/spritestudio/bin/
- mv extension-${{ inputs.godot_version }}-windows-${{ steps.commit.outputs.short }}/windows addons/spritestudio/bin/
- mv extension-${{ inputs.godot_version }}-linux-${{ steps.commit.outputs.short }}/linux addons/spritestudio/bin/
+ mv extension-${{ env.GODOT_VERSION }}-android-${{ steps.commit.outputs.short }}/android addons/spritestudio/bin/
+ mv extension-${{ env.GODOT_VERSION }}-ios-${{ steps.commit.outputs.short }}/ios addons/spritestudio/bin/
+ mv extension-${{ env.GODOT_VERSION }}-macos-${{ steps.commit.outputs.short }}/macos addons/spritestudio/bin/
+ mv extension-${{ env.GODOT_VERSION }}-web-${{ steps.commit.outputs.short }}/web addons/spritestudio/bin/
+ mv extension-${{ env.GODOT_VERSION }}-windows-${{ steps.commit.outputs.short }}/windows addons/spritestudio/bin/
+ mv extension-${{ env.GODOT_VERSION }}-linux-${{ steps.commit.outputs.short }}/linux addons/spritestudio/bin/
rm -rf ../output
mkdir -p ../output
mv addons ../output/
+
+ # Create a ZIP file for GitHub Release
+ cd ../output
+ zip -r ssplayer-godot-extension-${{ env.GODOT_VERSION }}.zip addons/
- name: Upload final release package
uses: actions/upload-artifact@v7
with:
- name: ssplayer-godot-extension-${{ inputs.godot_version }}-${{ steps.commit.outputs.short }}
+ name: ssplayer-godot-extension-${{ env.GODOT_VERSION }}-${{ steps.commit.outputs.short }}
path: output
+
+ - name: Create GitHub Release
+ if: startsWith(github.ref, 'refs/tags/v')
+ uses: softprops/action-gh-release@v2
+ with:
+ files: output/ssplayer-godot-extension-${{ env.GODOT_VERSION }}.zip
+ draft: true
+ generate_release_notes: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..cf29ab0
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,20 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+
+## [7.0.0-alpha01] - 2026-0X-XX
+
+### Added
+- **Initial Public Release**: SpriteStudio 7 SDK (`ssconverter-cli` + `Godot Plugin`).
+- **Core Runtime**: Engine-agnostic, `#![no_std]` brain with zero-math integration and SIMD (f32x4) state computation.
+- **Features**: Supports Mesh Deformation, Particles (SSEE), Instances, and SS7.1 parts (Skew, 9-Slice, Shape).
+- **Integrations**: C-API and Web (WASM) ready.
+- **Custom Allocator Injection**: `custom_alloc` feature lets game engines / consoles supply their own allocator and abort handler via `ss_custom_alloc` / `ss_custom_free` / `ss_custom_abort` C symbols — no wrapper crate required.
+- **Documentation**: Overhauled bilingual (EN/JA) README and contribution guidelines.
+
+### Known Limitations
+- Text/Font Bitmap rendering pending validation.
+- macOS/iOS binaries are not yet code-signed.
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..27c0790
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,62 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+We as members, contributors, and leaders pledge to make participation in our community a harassment-free experience for everyone, regardless of age, body size, visible or invisible disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, or sexual identity and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming, diverse, inclusive, and healthy community.
+
+## Our Standards
+Examples of behavior that contributes to a positive environment for our community include:
+- Demonstrating empathy and kindness toward other people
+- Being respectful of differing opinions, viewpoints, and experiences
+- Giving and gracefully accepting constructive feedback
+- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience
+- Focusing on what is best not just for us as individuals, but for the overall community
+
+Examples of unacceptable behavior include:
+- The use of sexualized language or imagery, and unwelcome sexual attention or advances
+- Trolling, insulting or derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or email address, without their explicit permission
+- Other conduct which could reasonably be considered inappropriate in a professional setting
+- Pressuring others through repeated, demanding, or coercive communications
+
+## Scope
+
+This Code of Conduct applies within all project spaces — including but not limited to GitHub Issues, Pull Requests, Discussions, and any communication between participants in this open-source project.
+
+---
+
+## 行動規範 (Code of Conduct) - 日本語訳
+
+### 私たちの約束
+私たちは、年齢、身体の大きさ、身体的・精神的な障害、民族性、性徴、性自認や性表現、経験レベル、教育水準、社会経済的地位、国籍、容姿、人種、階級、肌の色、宗教、性的自認や性的指向に関わらず、すべての人がハラスメントのない経験を共有できるコミュニティを作ることを約束します。
+
+私たちは、オープンで、歓迎され、多様で、包摂的で、健全なコミュニティに貢献する方法で行動し、交流することを約束します。
+
+### 私たちの基準
+ポジティブな環境を作るための行動例:
+- 他者に対して共感と思いやりを持って接する
+- 異なる意見や視点、経験を尊重する
+- 建設的なフィードバックを行い、また潔く受け入れる
+- 自らの過ちに責任を持ち、影響を受けた人々に謝罪し、その経験から学ぶ
+- 個人の利益だけでなく、コミュニティ全体にとって最善なことに焦点を当てる
+
+許容されない行動例:
+- 性的な言葉や画像の使用、および不適切な性的関心やアプローチ
+- 荒らし、侮辱的・軽蔑的なコメント、および個人的・政治的な攻撃
+- 公開・非公開を問わないハラスメント行為
+- 明示的な許可なく、住所やメールアドレスなどの他者の個人情報を公開すること
+- 専門的な場において不適切と合理的にみなされるその他の行為
+- 他者に対する、威圧的・要求的、または執拗な働きかけによる圧力
+
+### 適用範囲
+
+本行動規範は、本プロジェクトに関わるすべての場 ―― GitHub Issues、Pull Request、Discussions、および本オープンソースプロジェクトの参加者間のすべてのコミュニケーション ―― に適用されます。
+
+---
+
+## Enforcement
+The project maintainers are responsible for clarifying and enforcing our standards of acceptable behavior and will take appropriate and fair corrective action in response to any behavior that they deem inappropriate, threatening, offensive, or harmful.
+
+Issues or complaints may be reported privately to the maintainers or via the official **Help Center** link provided in `SUPPORT.md`.
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..7bc2efd
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,158 @@
+# Contributing to SSPlayerForGodot
+
+Thank you for your interest in contributing to SSPlayerForGodot! We welcome all kinds of contributions, including bug reports, feature requests, documentation improvements, and code contributions.
+
+## Table of Contents
+- [Code of Conduct](#code-of-conduct)
+- [How Can I Contribute?](#how-can-i-contribute)
+- [Development Environment](#development-environment)
+- [Coding Standards](#coding-standards)
+
+## Code of Conduct
+Please refer to [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md).
+
+## How Can I Contribute?
+
+### Technical Constraints & Guiding Principles
+To maintain high performance and native integration with Godot Engine, please adhere to the following principles:
+
+- **Godot Idioms First:** Use Godot's built-in systems (`Node2D`, `CanvasItem` API, Signals) instead of recreating them. Let Godot handle the tree and transforms.
+- **Performance in the Hot Path:** Avoid per-frame heap allocations during playback. Use the `DrawBatch` plans emitted by the runtime directly with Godot's `RenderingServer`.
+- **SDK Separation:** The core playback logic resides in the `SpriteStudio-SDK` submodule (Rust). Changes to core logic should be directed to the SDK repository, while Godot-specific integrations belong in `ss_player/`.
+
+### Reporting Bugs
+If you find a bug, please use the provided Issue Templates. Include:
+- A clear, descriptive title.
+- Steps to reproduce.
+- Your Godot version and OS.
+- Expected vs. actual behavior.
+
+*Note: If you need to send proprietary `.sspj` projects to reproduce the bug, please do not attach them to public issues. See [SUPPORT.md](./SUPPORT.md) for how to contact us privately.*
+
+### Pull Requests
+1. Fork the repository and create your branch from `develop`.
+2. Ensure your code follows the existing style and Godot conventions.
+3. Test your changes locally by running the sample projects in the `examples/` directory.
+4. Submit a Pull Request targeting the `develop` branch with a clear description of the changes.
+
+## Development Environment
+
+### Prerequisites
+- Godot Engine 4.x
+- A C++ compiler (GCC, Clang, or MSVC)
+- Python 3 and SCons
+
+### Build the Plugin
+To compile the Godot Extension, you must first build the Rust runtime from the SDK, and then compile the C++ extension using the provided build scripts:
+
+**macOS / Linux:**
+```bash
+# 1. Build the Rust runtime (Requires Rust installed)
+./scripts/build-runtime.sh
+
+# 2. Build the GDExtension
+./scripts/build-extension.sh
+```
+
+**Windows:**
+```powershell
+# 1. Build the Rust runtime (Requires Rust installed)
+.\scripts\build-runtime.ps1
+
+# 2. Build the GDExtension
+.\scripts\build-extension.ps1
+```
+
+Once built, open the `examples/Ringo` project in the Godot Editor to verify your changes.
+
+## Coding Standards
+
+### C++ Guidelines
+- Follow the [Godot Engine C++ style guide](https://docs.godotengine.org/en/stable/contributing/development/compiling/cpp_style_guide.html).
+- Use `clang-format` if available (`clang-format -i ss_player/*.{cpp,h}`).
+- Ensure safe handling of the Rust FFI objects (always release `SsState` and other handles to prevent memory leaks).
+
+---
+By contributing to this project, you agree that your contributions will be licensed under the project's [LICENSE.md](./LICENSE.md).
+
+
+
+
+---
+
+# SSPlayerForGodot への貢献について
+
+SSPlayerForGodot にご関心をお寄せいただき、ありがとうございます! バグ報告、機能提案、ドキュメントの改善、コードの提供など、あらゆる形での貢献を歓迎します。
+
+## 目次
+- [行動規範](#行動規範-1)
+- [貢献する方法](#貢献する方法-1)
+- [開発環境のセットアップ](#開発環境のセットアップ-1)
+- [コーディング規約](#コーディング規約-1)
+
+## 行動規範
+[CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) を参照してください。
+
+## 貢献する方法
+
+### 技術的制約と設計原則
+Godot Engineとのネイティブな統合と高いパフォーマンスを維持するため、以下の原則に従ってください。
+
+- **Godotのパラダイムを優先:** `Node2D` や `CanvasItem` API、シグナルなど、Godotの標準的な機能を積極的に活用してください。独自の実装を行うよりもGodotの設計に委ねることを優先します。
+- **再生パスのパフォーマンス:** 再生中の毎フレームごとの動的なメモリ確保(ヒープアロケーション)は避けてください。Rustランタイムから提供される描画バッチ情報を直接 `RenderingServer` に渡すように実装されています。
+- **SDKの分離:** コアのアニメーション計算ロジックは `SpriteStudio-SDK` サブモジュール(Rust)に存在します。アルゴリズムやコアロジックの修正はSDK側のリポジトリへ、Godot特有の実装は `ss_player/` へ行ってください。
+
+### バグの報告
+バグを発見した場合は、Issue テンプレートを使用して以下の情報を含めてください:
+- 簡潔で分かりやすいタイトル
+- 再現手順
+- 利用している Godot のバージョンとOS
+- 期待される動作と実際の動作
+
+*注: バグ再現のために非公開の `.sspj` プロジェクトデータ等を提供いただける場合は、公開 Issue には添付せず、[SUPPORT.md](./SUPPORT.md) に記載のヘルプセンターをご利用ください。*
+
+### プルリクエスト
+1. リポジトリをフォークし、`develop` ブランチから作業用ブランチを作成してください。
+2. 既存のGodot C++規約に従ってコードを記述してください。
+3. `examples/` ディレクトリ内のサンプルプロジェクトを実行し、動作確認を行ってください。
+4. `develop` ブランチに向けて、変更内容を明確に記載したプルリクエストを送信してください。
+
+## 開発環境のセットアップ
+
+### 前提条件
+- Godot Engine 4.x
+- C++ コンパイラ (GCC, Clang, MSVC のいずれか)
+- Python 3 および SCons
+
+### ビルド方法
+提供されているスクリプトを使用して、まずSDKからRustランタイムをビルドし、次にGDExtensionをコンパイルします。
+
+**macOS / Linux:**
+```bash
+# 1. Rustランタイムのビルド (Rust環境が必要です)
+./scripts/build-runtime.sh
+
+# 2. GDExtensionのビルド
+./scripts/build-extension.sh
+```
+
+**Windows:**
+```powershell
+# 1. Rustランタイムのビルド (Rust環境が必要です)
+.\scripts\build-runtime.ps1
+
+# 2. GDExtensionのビルド
+.\scripts\build-extension.ps1
+```
+
+ビルド完了後、Godotエディタで `examples/Ringo` プロジェクトなどを開き、変更内容をテストしてください。
+
+## コーディング規約
+
+### C++ のガイドライン
+- [Godot EngineのC++スタイルガイド](https://docs.godotengine.org/ja/stable/contributing/development/compiling/cpp_style_guide.html)に従ってください。
+- 可能であれば `clang-format` を使用してフォーマットを統一してください。
+- Rust FFI オブジェクトの安全な取り扱いに注意してください(メモリリークを防ぐため、`SsState` などのハンドルは必ず適切な release 関数を呼んで解放してください)。
+
+---
+本プロジェクトへの貢献は、プロジェクトの [LICENSE.md](./LICENSE.md) に同意したものとみなされます。
diff --git a/README.ja.md b/README.ja.md
index 6ccc736..0a9c814 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -53,8 +53,9 @@
[examples フォルダ](./examples/) に SDK のテストプロジェクトに基づいたサンプルプロジェクトがあります。
-- [Ringo](./examples/Ringo) — 「りんご」のテスト
-- [allAttributeV7](./examples/allAttributeV7) — 全属性の機能テスト
+- [Ringo](./examples/Ringo) — Ringo用のテスト
+- [Scripting](./examples/Scripting) — GDScriptを用いたアニメーション制御やシグナル受信のサンプル
+- [allAttributeV7](./examples/allAttributeV7) — 全アトリビュートの機能テスト
- [allPartsV7](./examples/allPartsV7) — 全パーツ種の機能テスト
- [overall](./examples/overall) — 総合的な機能テスト
- [overall_gdextension](./examples/overall_gdextension) — GDExtension 版での総合テスト
diff --git a/README.md b/README.md
index 29470ef..797c0ef 100644
--- a/README.md
+++ b/README.md
@@ -54,6 +54,7 @@ For the data-flow diagram, key features, supported versions, and more, see the *
Sample projects based on SDK test projects are available under the [examples folder](./examples/).
- [Ringo](./examples/Ringo) — Test for Ringo
+- [Scripting](./examples/Scripting) — GDScript example for controlling animations and signals
- [allAttributeV7](./examples/allAttributeV7) — Functional test for all attributes
- [allPartsV7](./examples/allPartsV7) — Functional test for all part types
- [overall](./examples/overall) — Comprehensive functional test
diff --git a/SUPPORT.md b/SUPPORT.md
new file mode 100644
index 0000000..3b721b7
--- /dev/null
+++ b/SUPPORT.md
@@ -0,0 +1,56 @@
+# Support Guide
+
+Thank you for using SSPlayerForGodot! We want to ensure you have the best experience possible. Please use the following channels to get help, report issues, or suggest improvements.
+
+## 🛠️ GitHub Issues (Public)
+For Bug Reports and Feature Requests, please use [GitHub Issues](https://github.com/cri-middleware/SSPlayerForGodot/issues). This is the best place for:
+- **Bug Reports**: If you've found a problem in the SDK.
+- **Feature Requests**: If you have ideas for new features or improvements.
+
+*Note: Please do NOT use GitHub Issues for questions about how to use the SDK. See the Help Center section below.*
+
+Before opening a new issue, please search existing issues to see if your topic has already been discussed.
+
+## ❓ Questions on How to Use the SDK
+If you have questions about how to use the SDK, need implementation advice, or want to share tips with other developers, please use our official community forum:
+
+👉 [**SpriteStudio Community**](https://spritestudio.jp/community/)
+
+## 🔒 Private Inquiries & Data Submission
+For private consultations, sensitive issue reports, sending large reproduction data (e.g., `.sspj` projects), or support with contractual guarantees, please use our official **Help Center**:
+
+👉 [**CRI Middleware Help Center (Inquiry Form)**](https://www.webtech.co.jp/help/en/spritestudio7/inquiries/ssplayer_tool/)
+
+*Note: For reproduction data, please use the file upload feature within the Help Center form.*
+
+---
+
+## 日本語でのサポート (Support in Japanese)
+
+SSPlayerForGodot をご利用いただきありがとうございます。ご質問や不具合の報告は、以下の窓口をご利用ください。
+
+### 🛠️ GitHub Issues (公開)
+不具合のご報告や新機能のご要望は [GitHub Issues](https://github.com/cri-middleware/SSPlayerForGodot/issues) へ投稿してください。
+- **不具合**: SDK の動作に問題がある場合。
+- **要望**: 新機能や改善のアイデアがある場合。
+
+*注: SDK の使い方に関するご質問は、GitHub Issues では受け付けておりません。以下のヘルプセンターをご利用ください。*
+
+投稿前に、同様の内容が既に報告されていないか、既存の Issue を検索してください。
+
+### ❓ 使い方のご質問
+SDK の使い方に関するご質問、実装の相談、または他の開発者との情報共有には、公式コミュニティをご利用ください。
+
+👉 [**SpriteStudio コミュニティ**](https://spritestudio.jp/community/)
+
+### 🔒 非公開でのお問い合わせ・データの送付
+非公開でのご相談、再現データ(`.sspj` プロジェクトなど)を送付いただく必要がある場合、または契約に基づくサポートが必要な場合は、公式の**ヘルプセンター**をご利用ください。
+
+👉 [**ヘルプセンター(お問い合わせフォーム)**](https://www.webtech.co.jp/help/ja/spritestudio7/inquiries/ssplayer_tool/)
+
+---
+
+### Company Info
+**CRI Middleware Co., Ltd.**
+[https://www.cri-mw.co.jp/](https://www.cri-mw.co.jp/)
+Copyright © CRI Middleware Co., Ltd.
diff --git a/examples/Scripting/.ssplayer_sources.cfg b/examples/Scripting/.ssplayer_sources.cfg
new file mode 100644
index 0000000..1bee6c7
--- /dev/null
+++ b/examples/Scripting/.ssplayer_sources.cfg
@@ -0,0 +1,9 @@
+[general]
+
+output_directory="res://ssab_generated"
+
+[ssab_sources]
+
+res://ssab_generated/Ringo/Ringo.ssqb="../../ss_player/SpriteStudio-SDK/tests/Ringo/Ringo.sspj"
+res://ssab_generated/Ringo/Ringo_tyu.ssab="../../ss_player/SpriteStudio-SDK/tests/Ringo/Ringo.sspj"
+res://ssab_generated/Ringo/Ringo.ssab="../../ss_player/SpriteStudio-SDK/tests/Ringo/Ringo.sspj"
diff --git a/examples/Scripting/Main.gd b/examples/Scripting/Main.gd
new file mode 100644
index 0000000..aa3e256
--- /dev/null
+++ b/examples/Scripting/Main.gd
@@ -0,0 +1,52 @@
+extends Node2D
+
+@onready var player = $Ringo
+@onready var label = $Label
+
+var anims = ["attack1", "walk", "wait"]
+var current_anim_index = 0
+
+func _ready() -> void:
+ # Connect to SpriteStudioPlayer2D signals
+ player.animation_finished.connect(_on_animation_finished)
+ # If the animation contains user data, you can catch it here:
+ # player.user_data.connect(_on_user_data)
+
+ play_current()
+ update_label()
+
+func _input(event: InputEvent) -> void:
+ # Change animation on Click or Enter
+ if event.is_action_pressed("ui_accept") or (event is InputEventMouseButton and event.pressed):
+ current_anim_index = (current_anim_index + 1) % anims.size()
+ play_current()
+ update_label()
+
+ # Flip horizontally on Right Arrow
+ elif event.is_action_pressed("ui_right"):
+ player.scale.x *= -1
+
+ # Adjust playback speed on Up/Down Arrows
+ elif event.is_action_pressed("ui_up"):
+ player.speed_scale += 0.5
+ update_label()
+ elif event.is_action_pressed("ui_down"):
+ player.speed_scale = max(0.1, player.speed_scale - 0.5)
+ update_label()
+
+func play_current() -> void:
+ var anim_name = anims[current_anim_index]
+ player.animation = anim_name
+ player.playing = true
+
+func update_label() -> void:
+ if label:
+ label.text = "--- SpriteStudioPlayer2D GDScript Example ---\n\n"
+ label.text += "Click or Press Enter: Change Animation\n"
+ label.text += "Up/Down Arrows: Change Speed\n"
+ label.text += "Right Arrow: Flip Horizontal\n\n"
+ label.text += "Current Animation: " + player.animation + "\n"
+ label.text += "Speed Scale: " + str(player.speed_scale) + "\n"
+
+func _on_animation_finished(anim_name: String) -> void:
+ print("Animation finished: ", anim_name)
diff --git a/examples/Scripting/Ringo.tscn b/examples/Scripting/Ringo.tscn
new file mode 100644
index 0000000..6be92c7
--- /dev/null
+++ b/examples/Scripting/Ringo.tscn
@@ -0,0 +1,22 @@
+[gd_scene load_steps=3 format=3 uid="uid://dxr71lkltwqb6"]
+
+[ext_resource type="SSABResource" uid="uid://cmjtnhtns0pal" path="res://ssab_generated/Ringo/Ringo.ssab" id="1_w6qk1"]
+[ext_resource type="Script" path="res://Main.gd" id="2_script"]
+
+[node name="Node2D" type="Node2D"]
+script = ExtResource("2_script")
+
+[node name="Ringo" type="SpriteStudioPlayer2D" parent="."]
+position = Vector2(400, 300)
+ssab = ExtResource("1_w6qk1")
+animation = "attack1"
+playing = true
+sub_frame_enabled = true
+
+[node name="Label" type="Label" parent="."]
+offset_left = 30.0
+offset_top = 30.0
+offset_right = 400.0
+offset_bottom = 200.0
+theme_override_colors/font_shadow_color = Color(0, 0, 0, 1)
+text = "Loading..."
diff --git a/examples/Scripting/icon.svg b/examples/Scripting/icon.svg
new file mode 100644
index 0000000..e45b398
--- /dev/null
+++ b/examples/Scripting/icon.svg
@@ -0,0 +1,3 @@
+
diff --git a/examples/Scripting/icon.svg.import b/examples/Scripting/icon.svg.import
new file mode 100644
index 0000000..da2f3f5
--- /dev/null
+++ b/examples/Scripting/icon.svg.import
@@ -0,0 +1,43 @@
+[remap]
+
+importer="texture"
+type="CompressedTexture2D"
+uid="uid://eu60vgjyqhbj"
+path="res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"
+metadata={
+"vram_texture": false
+}
+
+[deps]
+
+source_file="res://icon.svg"
+dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex"]
+
+[params]
+
+compress/mode=0
+compress/high_quality=false
+compress/lossy_quality=0.7
+compress/uastc_level=0
+compress/rdo_quality_loss=0.0
+compress/hdr_compression=1
+compress/normal_map=0
+compress/channel_pack=0
+mipmaps/generate=false
+mipmaps/limit=-1
+roughness/mode=0
+roughness/src_normal=""
+process/channel_remap/red=0
+process/channel_remap/green=1
+process/channel_remap/blue=2
+process/channel_remap/alpha=3
+process/fix_alpha_border=true
+process/premult_alpha=false
+process/normal_map_invert_y=false
+process/hdr_as_srgb=false
+process/hdr_clamp_exposure=false
+process/size_limit=0
+detect_3d/compress_to=1
+svg/scale=1.0
+editor/scale_with_editor_scale=false
+editor/convert_colors_with_editor_theme=false
diff --git a/examples/Scripting/project.godot b/examples/Scripting/project.godot
new file mode 100644
index 0000000..52023c3
--- /dev/null
+++ b/examples/Scripting/project.godot
@@ -0,0 +1,27 @@
+; Engine configuration file.
+; It's best edited using the editor UI and not directly,
+; since the parameters that go here are not all obvious.
+;
+; Format:
+; [section] ; section goes between []
+; param=value ; assign values to parameters
+
+config_version=5
+
+[animation]
+
+compatibility/default_parent_skeleton_in_mesh_instance_3d=true
+
+[application]
+
+config/name="Ringo"
+run/main_scene="res://Ringo.tscn"
+config/features=PackedStringArray("4.6", "GL Compatibility")
+config/icon="res://icon.svg"
+
+[rendering]
+
+renderer/rendering_method="gl_compatibility"
+renderer/rendering_method.mobile="gl_compatibility"
+
+
diff --git a/examples/dev_gdextension/node_2d.tscn b/examples/dev_gdextension/node_2d.tscn
new file mode 100644
index 0000000..0a5c269
--- /dev/null
+++ b/examples/dev_gdextension/node_2d.tscn
@@ -0,0 +1,14 @@
+[gd_scene format=3 uid="uid://41tstw2esic"]
+
+[ext_resource type="SSABResource" uid="uid://d20ahia4clv8b" path="res://ssab_generated/spr_00_00/00_spr_03_action_01_level3.ssab" id="1_wtcfe"]
+
+[node name="Node2D" type="Node2D" unique_id=1628321986]
+
+[node name="00_spr_03_action_01_level3" type="SpriteStudioPlayer2D" parent="." unique_id=1977491030]
+ssab = ExtResource("1_wtcfe")
+animation = "00_action_01_left"
+autoplay = true
+animation_section_end = 373
+cellmaps/spr_00_00_1 = null
+cellmaps/spr_00_00_0 = null
+position = Vector2(495, 347)
diff --git a/examples/dev_gdextension/project.godot b/examples/dev_gdextension/project.godot
index 0fe6ec2..4a80780 100644
--- a/examples/dev_gdextension/project.godot
+++ b/examples/dev_gdextension/project.godot
@@ -28,5 +28,3 @@ config/icon="res://icon.svg"
rendering_device/driver.windows="d3d12"
renderer/rendering_method="gl_compatibility"
renderer/rendering_method.mobile="gl_compatibility"
-
-
diff --git a/examples/dev_module/node_2d.tscn b/examples/dev_module/node_2d.tscn
index 67103fa..0dac34a 100644
--- a/examples/dev_module/node_2d.tscn
+++ b/examples/dev_module/node_2d.tscn
@@ -1,3 +1,32 @@
[gd_scene format=3 uid="uid://crm5d340adlbm"]
+[ext_resource type="SSABResource" uid="uid://ytqkeiphrsoe" path="res://ssab_generated/spr_00_00/00_spr_03_action_01_level3.ssab" id="1_wtcfe"]
+
[node name="Node2D" type="Node2D" unique_id=1299694310]
+
+[node name="00_spr_03_action_01_level3" type="SpriteStudioPlayer2D" parent="." unique_id=484315326]
+position = Vector2(145, 333)
+ssab = ExtResource("1_wtcfe")
+animation = "00_action_01_left"
+autoplay = true
+animation_section_end = 373
+cellmaps/spr_00_00_1 = null
+cellmaps/spr_00_00_0 = null
+
+[node name="00_spr_03_action_01_level4" type="SpriteStudioPlayer2D" parent="." unique_id=1636878478]
+position = Vector2(365, 337)
+ssab = ExtResource("1_wtcfe")
+animation = "00_action_01_left"
+autoplay = true
+animation_section_end = 373
+cellmaps/spr_00_00_1 = null
+cellmaps/spr_00_00_0 = null
+
+[node name="00_spr_03_action_01_level5" type="SpriteStudioPlayer2D" parent="." unique_id=379754707]
+position = Vector2(605, 350)
+ssab = ExtResource("1_wtcfe")
+animation = "00_action_01_left"
+autoplay = true
+animation_section_end = 373
+cellmaps/spr_00_00_1 = null
+cellmaps/spr_00_00_0 = null
diff --git a/examples/dev_module/project.godot b/examples/dev_module/project.godot
index de4592f..fb9413a 100644
--- a/examples/dev_module/project.godot
+++ b/examples/dev_module/project.godot
@@ -18,5 +18,3 @@ config/name="dev_module"
run/main_scene="res://node_2d.tscn"
config/features=PackedStringArray("4.6", "GL Compatibility")
config/icon="res://icon.svg"
-
-
diff --git a/ss_player/register_types.cpp b/ss_player/register_types.cpp
index 55dc6fd..3d63f75 100644
--- a/ss_player/register_types.cpp
+++ b/ss_player/register_types.cpp
@@ -35,6 +35,7 @@ static void editor_init_callback() {
#include "ss_player_node_2d.h"
#include "ss_part_attachment_2d.h"
#include "ssqb_resource.h"
+#include "ss_translation.h"
static SSABResourceFormatLoader *ssab_loader = nullptr;
static SSABResourceFormatSaver *ssab_saver = nullptr;
@@ -127,6 +128,7 @@ void unregister_ss_player_types() {
void initialize_ss_player_module(ModuleInitializationLevel level) {
if (level == MODULE_INITIALIZATION_LEVEL_SCENE) {
register_ss_player_types();
+ register_ss_translations();
}
#ifdef TOOLS_ENABLED
@@ -154,6 +156,7 @@ void initialize_ss_player_module(ModuleInitializationLevel level) {
void uninitialize_ss_player_module(ModuleInitializationLevel level) {
if (level == MODULE_INITIALIZATION_LEVEL_SCENE) {
unregister_ss_player_types();
+ unregister_ss_translations();
}
}
diff --git a/ss_player/ss_translation.cpp b/ss_player/ss_translation.cpp
new file mode 100644
index 0000000..afee477
--- /dev/null
+++ b/ss_player/ss_translation.cpp
@@ -0,0 +1,73 @@
+#include "ss_translation.h"
+
+#ifdef SPRITESTUDIO_GODOT_EXTENSION
+#include
+#include
+using namespace godot;
+#else
+#include "core/string/translation.h"
+#include "core/string/translation_server.h"
+#endif
+
+static Ref ja_translation;
+
+void register_ss_translations() {
+ ja_translation.instantiate();
+ ja_translation->set_locale("ja");
+
+ // Warnings in node 2d
+ ja_translation->add_message("Assign an SSABResource to the \"ssab\" property to play an animation.", "アニメーションを再生するには、\"ssab\" プロパティに SSABResource を割り当ててください。");
+ ja_translation->add_message("Select an animation in the \"animation\" property.", "\"animation\" プロパティでアニメーションを選択してください。");
+
+ // Dock strings
+ ja_translation->add_message("Add SpriteStudioPlayer2D", "SpriteStudioPlayer2Dを追加");
+ ja_translation->add_message("Open SSPJ", "SSPJを開く");
+ ja_translation->add_message("Reconvert", "再コンバート");
+ ja_translation->add_message("Output:", "出力先:");
+ ja_translation->add_message("Choose output directory", "出力先ディレクトリを選択");
+ ja_translation->add_message("Reset to default directory", "デフォルトにリセット");
+ ja_translation->add_message("Open in File Manager", "ファイルマネージャーで開く");
+ ja_translation->add_message("Drop SSPJ or a folder here\n(drag from your file manager)", "ここにSSPJまたはフォルダをドロップ\n(ファイルマネージャーからドラッグ)");
+ ja_translation->add_message("Recent SSPJs", "最近のSSPJ");
+ ja_translation->add_message("Clear recent SSPJ files", "履歴をクリア");
+ ja_translation->add_message("player:", "player:");
+ ja_translation->add_message("converter:", "converter:");
+ ja_translation->add_message("Import Error", "インポートエラー");
+ ja_translation->add_message("No .sspj files or folders found.\nPlease drop SpriteStudio project (.sspj) files or a folder containing them.", ".sspjファイルが見つかりません。\nSpriteStudioプロジェクト(.sspj)ファイル、またはそれを含むフォルダをドロップしてください。");
+ ja_translation->add_message("Reveal", "ファイルの場所を開く");
+ ja_translation->add_message("Remove from Recent", "履歴から削除");
+ ja_translation->add_message("No recent files. Drop a sspj above to start.", "履歴がありません。上の枠にSSPJをドロップして開始してください。");
+
+ // Importer
+ ja_translation->add_message("Import", "インポート");
+ ja_translation->add_message("No .sspj files were found in the dropped folder(s).", "ドロップされたフォルダ内に.sspjファイルが見つかりませんでした。");
+ ja_translation->add_message("Scan stopped", "スキャン停止");
+ ja_translation->add_message("The folder is very large, so scanning stopped early.\nFound %d .sspj file(s) so far.\n\nImport what was found, keep scanning, or stop?", "フォルダが大きすぎるため、スキャンを中断しました。\nこれまでに %d 個の.sspjファイルが見つかりました。\n\n見つかったものをインポートしますか?スキャンを続行しますか?");
+ ja_translation->add_message("Import found", "インポート");
+ ja_translation->add_message("Stop", "停止");
+ ja_translation->add_message("Keep scanning", "スキャン続行");
+ ja_translation->add_message("Some outputs already belong to a different SpriteStudio project and would be overwritten:\n\n", "一部の出力ファイルは別のSpriteStudioプロジェクトに属しており、上書きされます:\n\n");
+ ja_translation->add_message("\nOverwrite them anyway?", "\n上書きして続行しますか?");
+ ja_translation->add_message("Output name collision", "出力名の衝突");
+ ja_translation->add_message("Overwrite", "上書き");
+ ja_translation->add_message("Cancel", "キャンセル");
+ ja_translation->add_message("Some files failed to import.\n\n", "一部のファイルのインポートに失敗しました。\n\n");
+ ja_translation->add_message("\nPlease check the Output tab for details.", "\n詳細は出力タブを確認してください。");
+
+#ifdef SPRITESTUDIO_GODOT_EXTENSION
+ TranslationServer::get_singleton()->add_translation(ja_translation);
+#else
+ TranslationServer::get_singleton()->add_translation(ja_translation);
+#endif
+}
+
+void unregister_ss_translations() {
+ if (ja_translation.is_valid()) {
+#ifdef SPRITESTUDIO_GODOT_EXTENSION
+ TranslationServer::get_singleton()->remove_translation(ja_translation);
+#else
+ TranslationServer::get_singleton()->remove_translation(ja_translation);
+#endif
+ ja_translation.unref();
+ }
+}
diff --git a/ss_player/ss_translation.h b/ss_player/ss_translation.h
new file mode 100644
index 0000000..e6fd90c
--- /dev/null
+++ b/ss_player/ss_translation.h
@@ -0,0 +1,7 @@
+#ifndef SS_TRANSLATION_H
+#define SS_TRANSLATION_H
+
+void register_ss_translations();
+void unregister_ss_translations();
+
+#endif // SS_TRANSLATION_H