From 6d4f603687b9b0ca1b1404ad10a5c37e9f4cd456 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sat, 20 Jun 2026 01:40:37 +0900 Subject: [PATCH 1/5] ci: automate GitHub release on tags --- .github/workflows/extension.yml | 44 ++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 14 deletions(-) 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 From afacb81944931ae4af6dfa4c725c6a4247146532 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sat, 20 Jun 2026 01:44:01 +0900 Subject: [PATCH 2/5] feat: add community templates based on SDK and basic JA localization --- .github/ISSUE_TEMPLATE/bug_report.yml | 80 ++++++++++ .github/ISSUE_TEMPLATE/config.yml | 8 + .github/ISSUE_TEMPLATE/feature_request.yml | 39 +++++ .github/PULL_REQUEST_TEMPLATE.md | 21 +++ CHANGELOG.md | 20 +++ CODE_OF_CONDUCT.md | 62 ++++++++ CONTRIBUTING.md | 164 +++++++++++++++++++++ SUPPORT.md | 56 +++++++ examples/dev_gdextension/node_2d.tscn | 14 ++ examples/dev_gdextension/project.godot | 2 - examples/dev_module/node_2d.tscn | 29 ++++ examples/dev_module/project.godot | 2 - ss_player/register_types.cpp | 3 + ss_player/ss_translation.cpp | 73 +++++++++ ss_player/ss_translation.h | 7 + 15 files changed, 576 insertions(+), 4 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 SUPPORT.md create mode 100644 examples/dev_gdextension/node_2d.tscn create mode 100644 ss_player/ss_translation.cpp create mode 100644 ss_player/ss_translation.h diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..3d72686 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,80 @@ +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: target_engine + attributes: + label: Target Engine / 組み込み先のエンジン + description: Unity, Unreal Engine, Web/JS, Custom C++ Engine, etc. / Unity、Unreal Engine、Webブラウザ、独自のC++エンジンなど。 + validations: + required: true + + - type: input + id: sdk_version + attributes: + label: SDK Version / SDK のバージョン + description: e.g. v7.0.0-alpha01 or commit hash. / バージョンタグ(v7.0.0-alpha01等)、またはコミットハッシュ。 + validations: + required: true + + - type: input + id: environment + attributes: + label: OS / Compiler / Rust Version + description: OS version, Rust version, compiler info. / OS バージョン、Rust のバージョン、コンパイラの情報など。 + placeholder: e.g. macOS Sonoma, Rust 1.77 + validations: + required: true + + - type: textarea + id: additional_context + attributes: + label: Additional Context & Minimal Code / 補足情報・最小再現コード + description: Add any other context or code snippets that reproduce the issue. / その他、不具合に関する補足情報や、不具合が発生する呼び出し部分のコードを記載してください。 + + - 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/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..308db00 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,164 @@ +# 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 the high-performance and portable nature of this SDK, all code contributions must adhere to the following core principles: + +- **Strict `no_std` Compliance:** The core runtime (`Godot Plugin`, `libssab`, `libssinterpolate`) must remain `#![no_std]`. We do not allow dependencies on `std` or any platform-specific libraries that break portability. +- **Zero-Allocation in Playback Hot Path:** Dynamic memory allocation (heap allocation) is strictly prohibited during the animation playback loop. All necessary memory must be pre-allocated or provided by the caller. +- **Performance over Convenience:** We prioritize runtime execution speed and memory efficiency over "easy-to-use" helper functions if they introduce overhead. +- **SIMD-Friendly Design:** Data structures (especially in `ssab`) must be designed with SIMD (f32x4) vectorization in mind. Prefer columnar layouts and flat arrays. +- **Stateless Brain (Separation of Concerns):** The runtime (Brain) calculates states but must not have knowledge of the rendering engine (Body). Keep the interface primitive and deterministic. +- **Explicit over Implicit:** Avoid "magic" or hidden behaviors. Code should be predictable, traceable, and explicit in its intent. + +### Reporting Bugs +If you find a bug, please open an issue and include: +- A clear, descriptive title. +- Steps to reproduce the issue. +- Your environment (OS, Rust version, target platform). +- 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.* + +### Suggesting Enhancements +If you have an idea, please open an issue to discuss it before starting work. + +### Pull Requests +1. Fork the repository and create your branch from `main`. +2. Ensure your code follows the existing style and conventions. +3. Add tests for any new features or bug fixes. +4. Ensure all tests pass (`cargo test`). +5. Update documentation if necessary (READMEs, Doc comments). +6. Submit a Pull Request with a clear description of the changes. + +## Development Environment + +### Prerequisites +- [Rustup](https://rustup.rs/) (Stable channel) +- [FlatBuffers compiler](https://google.github.io/flatbuffers/) (Required if modifying `.fbs` files) +- [cbindgen](https://github.com/mozilla/cbindgen) (For C-API header generation) + +### Build and Test +```bash +# Build the entire workspace +cargo build --release + +# Run all tests +cargo test + +# Run the converter CLI for verification +cargo run -p ssconverter-cli -- +``` + +## Coding Standards + +### Rust Guidelines +- Use `rustfmt` to format your code: `cargo fmt`. +- Check for common mistakes with `clippy`: `cargo clippy`. +- Follow [Idiomatic Rust](https://github.com/mre/idiomatic-rust) practices. + +### FFI and C-API +Since this SDK provides C-compatible interfaces (`ssruntime`, `ssconverter`), please pay attention to: +- **Binary Compatibility**: Avoid breaking changes to the C-API unless absolutely necessary. +- **Header Generation**: Ensure the C++ headers are regenerated and verified if you modify FFI functions. +- **Memory Management**: Clearly document who owns the memory across the FFI boundary. + +--- +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) を参照してください。 + +## 貢献する方法 + +### 技術的制約と設計原則 +本 SDK の高いパフォーマンスとポータビリティを維持するため、すべてのコード貢献は以下の核心的な原則に従う必要があります。 + +- **厳格な `no_std` 遵守:** コアランタイム (`Godot Plugin`, `libssab`, `libssinterpolate`) は `#![no_std]` を維持しなければなりません。ポータビリティを損なう `std` やプラットフォーム依存のライブラリへの依存は許可されません。 +- **再生パスでのゼロ・アロケーション:** アニメーションの再生ループ(ホットパス)内での動的なメモリ割り当て(ヒープ確保)は厳禁です。必要なメモリはすべて事前確保するか、呼び出し側から提供される必要があります。 +- **便利さよりもパフォーマンス:** オーバーヘッドを導入するような「使いやすいヘルパー関数」よりも、実行速度とメモリ効率を常に優先します。 +- **SIMD フレンドリーな設計:** データ構造(特に `ssab`)は、SIMD (f32x4) によるベクトル化を念頭に設計される必要があります。カラム指向のレイアウトやフラットな配列を優先してください。 +- **ステートレスな Brain(関心の分離):** ランタイム(Brain)は状態の計算に徹し、レンダリングエンジン(Body)に関する知識を持ってはなりません。インターフェースはプリミティブかつ決定論的(Deterministic)に保ってください。 +- **暗黙的より明示的:** 「マジック」や隠れた挙動を避けてください。コードは意図が明示的であり、予測可能でトレース可能である必要があります。 + +### バグの報告 +バグを発見した場合は、Issue を作成し、以下の情報を含めてください: +- 簡潔で分かりやすいタイトル +- 再現手順 +- 実行環境(OS、Rust バージョン、ターゲットプラットフォーム) +- 期待される動作と実際の動作 + +*注: バグ再現のために非公開の `.sspj` プロジェクトデータ等を提供いただける場合は、公開 Issue には添付せず、[SUPPORT.md](./SUPPORT.md) に記載のヘルプセンターをご利用ください。* + +### 機能の提案 +SDK を改善するアイデアがある場合は、開発を始める前に Issue を作成して内容を議論しましょう。 + +### プルリクエスト +1. リポジトリをフォークし、`main` ブランチから作業用ブランチを作成してください。 +2. 既存のスタイルや規約に従ってコードを記述してください。 +3. 新しい機能やバグ修正には、対応するテストを追加してください。 +4. すべてのテストがパスすることを確認してください (`cargo test`)。 +5. 必要に応じてドキュメント (README やコメント) を更新してください。 +6. 変更内容を明確に記載したプルリクエストを送信してください。 + +## 開発環境のセットアップ + +### 前提条件 +- [Rustup](https://rustup.rs/) (Stable チャンネル) +- [FlatBuffers コンパイラ](https://google.github.io/flatbuffers/) (`.fbs` ファイルを変更する場合に必要) +- [cbindgen](https://github.com/mozilla/cbindgen) (C-API ヘッダー生成に必要) + +### ビルドとテスト +```bash +# ワークスペース全体のビルド +cargo build --release + +# すべてのテストを実行 +cargo test + +# コンバーター CLI を実行して動作確認 +cargo run -p ssconverter-cli -- +``` + +## コーディング規約 + +### Rust のガイドライン +- `rustfmt` を使用してフォーマットを統一してください: `cargo fmt` +- `clippy` を使用して一般的なミスをチェックしてください: `cargo clippy` +- [慣用的な Rust](https://github.com/mre/idiomatic-rust) (Idiomatic Rust) のプラクティスに従ってください。 + +### FFI と C-API +この SDK は C 互換インターフェースを提供しているため、以下の点に注意してください: +- **バイナリ互換性**: 避けられない場合を除き、C-API の破壊的変更は避けてください。 +- **ヘッダー生成**: FFI 関数を変更した場合は、C++ ヘッダーが正しく更新・検証されていることを確認してください。 +- **メモリ管理**: FFI 境界を越えてデータをやり取りする場合、メモリの所有権を明確にドキュメント化してください。 + +--- +本プロジェクトへの貢献は、プロジェクトの [LICENSE.md](./LICENSE.md) に同意したものとみなされます。 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/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 From f42bae4db7106231a5c651297cb6b742153b2c39 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sat, 20 Jun 2026 01:46:41 +0900 Subject: [PATCH 3/5] docs: adapt CONTRIBUTING.md and bug report template for Godot workflows --- .github/ISSUE_TEMPLATE/bug_report.yml | 23 ++--- CONTRIBUTING.md | 136 +++++++++++--------------- 2 files changed, 69 insertions(+), 90 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 3d72686..f1d91f6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -38,35 +38,36 @@ body: required: true - type: input - id: target_engine + id: godot_version attributes: - label: Target Engine / 組み込み先のエンジン - description: Unity, Unreal Engine, Web/JS, Custom C++ Engine, etc. / Unity、Unreal Engine、Webブラウザ、独自のC++エンジンなど。 + 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: sdk_version + id: plugin_version attributes: - label: SDK Version / SDK のバージョン - description: e.g. v7.0.0-alpha01 or commit hash. / バージョンタグ(v7.0.0-alpha01等)、またはコミットハッシュ。 + 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: OS / Compiler / Rust Version - description: OS version, Rust version, compiler info. / OS バージョン、Rust のバージョン、コンパイラの情報など。 - placeholder: e.g. macOS Sonoma, Rust 1.77 + 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 & Minimal Code / 補足情報・最小再現コード - description: Add any other context or code snippets that reproduce the issue. / その他、不具合に関する補足情報や、不具合が発生する呼び出し部分のコードを記載してください。 + 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: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 308db00..15f84a1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,66 +14,55 @@ Please refer to [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md). ## How Can I Contribute? ### Technical Constraints & Guiding Principles -To maintain the high-performance and portable nature of this SDK, all code contributions must adhere to the following core principles: +To maintain high performance and native integration with Godot Engine, please adhere to the following principles: -- **Strict `no_std` Compliance:** The core runtime (`Godot Plugin`, `libssab`, `libssinterpolate`) must remain `#![no_std]`. We do not allow dependencies on `std` or any platform-specific libraries that break portability. -- **Zero-Allocation in Playback Hot Path:** Dynamic memory allocation (heap allocation) is strictly prohibited during the animation playback loop. All necessary memory must be pre-allocated or provided by the caller. -- **Performance over Convenience:** We prioritize runtime execution speed and memory efficiency over "easy-to-use" helper functions if they introduce overhead. -- **SIMD-Friendly Design:** Data structures (especially in `ssab`) must be designed with SIMD (f32x4) vectorization in mind. Prefer columnar layouts and flat arrays. -- **Stateless Brain (Separation of Concerns):** The runtime (Brain) calculates states but must not have knowledge of the rendering engine (Body). Keep the interface primitive and deterministic. -- **Explicit over Implicit:** Avoid "magic" or hidden behaviors. Code should be predictable, traceable, and explicit in its intent. +- **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 open an issue and include: +If you find a bug, please use the provided Issue Templates. Include: - A clear, descriptive title. -- Steps to reproduce the issue. -- Your environment (OS, Rust version, target platform). +- 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.* -### Suggesting Enhancements -If you have an idea, please open an issue to discuss it before starting work. - ### Pull Requests -1. Fork the repository and create your branch from `main`. -2. Ensure your code follows the existing style and conventions. -3. Add tests for any new features or bug fixes. -4. Ensure all tests pass (`cargo test`). -5. Update documentation if necessary (READMEs, Doc comments). -6. Submit a Pull Request with a clear description of the changes. +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 -- [Rustup](https://rustup.rs/) (Stable channel) -- [FlatBuffers compiler](https://google.github.io/flatbuffers/) (Required if modifying `.fbs` files) -- [cbindgen](https://github.com/mozilla/cbindgen) (For C-API header generation) +- Godot Engine 4.x +- A C++ compiler (GCC, Clang, or MSVC) +- Python 3 and SCons -### Build and Test -```bash -# Build the entire workspace -cargo build --release +### Build the Plugin +To compile the Godot Extension, use the provided build scripts: -# Run all tests -cargo test +**macOS / Linux:** +```bash +./scripts/build-extension.sh +``` -# Run the converter CLI for verification -cargo run -p ssconverter-cli -- +**Windows:** +```powershell +.\scripts\build-extension.ps1 ``` -## Coding Standards +Once built, open the `examples/Ringo` project in the Godot Editor to verify your changes. -### Rust Guidelines -- Use `rustfmt` to format your code: `cargo fmt`. -- Check for common mistakes with `clippy`: `cargo clippy`. -- Follow [Idiomatic Rust](https://github.com/mre/idiomatic-rust) practices. +## Coding Standards -### FFI and C-API -Since this SDK provides C-compatible interfaces (`ssruntime`, `ssconverter`), please pay attention to: -- **Binary Compatibility**: Avoid breaking changes to the C-API unless absolutely necessary. -- **Header Generation**: Ensure the C++ headers are regenerated and verified if you modify FFI functions. -- **Memory Management**: Clearly document who owns the memory across the FFI boundary. +### 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). @@ -99,66 +88,55 @@ SSPlayerForGodot にご関心をお寄せいただき、ありがとうござい ## 貢献する方法 ### 技術的制約と設計原則 -本 SDK の高いパフォーマンスとポータビリティを維持するため、すべてのコード貢献は以下の核心的な原則に従う必要があります。 +Godot Engineとのネイティブな統合と高いパフォーマンスを維持するため、以下の原則に従ってください。 -- **厳格な `no_std` 遵守:** コアランタイム (`Godot Plugin`, `libssab`, `libssinterpolate`) は `#![no_std]` を維持しなければなりません。ポータビリティを損なう `std` やプラットフォーム依存のライブラリへの依存は許可されません。 -- **再生パスでのゼロ・アロケーション:** アニメーションの再生ループ(ホットパス)内での動的なメモリ割り当て(ヒープ確保)は厳禁です。必要なメモリはすべて事前確保するか、呼び出し側から提供される必要があります。 -- **便利さよりもパフォーマンス:** オーバーヘッドを導入するような「使いやすいヘルパー関数」よりも、実行速度とメモリ効率を常に優先します。 -- **SIMD フレンドリーな設計:** データ構造(特に `ssab`)は、SIMD (f32x4) によるベクトル化を念頭に設計される必要があります。カラム指向のレイアウトやフラットな配列を優先してください。 -- **ステートレスな Brain(関心の分離):** ランタイム(Brain)は状態の計算に徹し、レンダリングエンジン(Body)に関する知識を持ってはなりません。インターフェースはプリミティブかつ決定論的(Deterministic)に保ってください。 -- **暗黙的より明示的:** 「マジック」や隠れた挙動を避けてください。コードは意図が明示的であり、予測可能でトレース可能である必要があります。 +- **Godotのパラダイムを優先:** `Node2D` や `CanvasItem` API、シグナルなど、Godotの標準的な機能を積極的に活用してください。独自の実装を行うよりもGodotの設計に委ねることを優先します。 +- **再生パスのパフォーマンス:** 再生中の毎フレームごとの動的なメモリ確保(ヒープアロケーション)は避けてください。Rustランタイムから提供される描画バッチ情報を直接 `RenderingServer` に渡すように実装されています。 +- **SDKの分離:** コアのアニメーション計算ロジックは `SpriteStudio-SDK` サブモジュール(Rust)に存在します。アルゴリズムやコアロジックの修正はSDK側のリポジトリへ、Godot特有の実装は `ss_player/` へ行ってください。 ### バグの報告 -バグを発見した場合は、Issue を作成し、以下の情報を含めてください: +バグを発見した場合は、Issue テンプレートを使用して以下の情報を含めてください: - 簡潔で分かりやすいタイトル - 再現手順 -- 実行環境(OS、Rust バージョン、ターゲットプラットフォーム) +- 利用している Godot のバージョンとOS - 期待される動作と実際の動作 *注: バグ再現のために非公開の `.sspj` プロジェクトデータ等を提供いただける場合は、公開 Issue には添付せず、[SUPPORT.md](./SUPPORT.md) に記載のヘルプセンターをご利用ください。* -### 機能の提案 -SDK を改善するアイデアがある場合は、開発を始める前に Issue を作成して内容を議論しましょう。 - ### プルリクエスト -1. リポジトリをフォークし、`main` ブランチから作業用ブランチを作成してください。 -2. 既存のスタイルや規約に従ってコードを記述してください。 -3. 新しい機能やバグ修正には、対応するテストを追加してください。 -4. すべてのテストがパスすることを確認してください (`cargo test`)。 -5. 必要に応じてドキュメント (README やコメント) を更新してください。 -6. 変更内容を明確に記載したプルリクエストを送信してください。 +1. リポジトリをフォークし、`develop` ブランチから作業用ブランチを作成してください。 +2. 既存のGodot C++規約に従ってコードを記述してください。 +3. `examples/` ディレクトリ内のサンプルプロジェクトを実行し、動作確認を行ってください。 +4. `develop` ブランチに向けて、変更内容を明確に記載したプルリクエストを送信してください。 ## 開発環境のセットアップ ### 前提条件 -- [Rustup](https://rustup.rs/) (Stable チャンネル) -- [FlatBuffers コンパイラ](https://google.github.io/flatbuffers/) (`.fbs` ファイルを変更する場合に必要) -- [cbindgen](https://github.com/mozilla/cbindgen) (C-API ヘッダー生成に必要) +- Godot Engine 4.x +- C++ コンパイラ (GCC, Clang, MSVC のいずれか) +- Python 3 および SCons -### ビルドとテスト -```bash -# ワークスペース全体のビルド -cargo build --release +### ビルド方法 +提供されているスクリプトを使用してGDExtensionをコンパイルします。 -# すべてのテストを実行 -cargo test +**macOS / Linux:** +```bash +./scripts/build-extension.sh +``` -# コンバーター CLI を実行して動作確認 -cargo run -p ssconverter-cli -- +**Windows:** +```powershell +.\scripts\build-extension.ps1 ``` -## コーディング規約 +ビルド完了後、Godotエディタで `examples/Ringo` プロジェクトなどを開き、変更内容をテストしてください。 -### Rust のガイドライン -- `rustfmt` を使用してフォーマットを統一してください: `cargo fmt` -- `clippy` を使用して一般的なミスをチェックしてください: `cargo clippy` -- [慣用的な Rust](https://github.com/mre/idiomatic-rust) (Idiomatic Rust) のプラクティスに従ってください。 +## コーディング規約 -### FFI と C-API -この SDK は C 互換インターフェースを提供しているため、以下の点に注意してください: -- **バイナリ互換性**: 避けられない場合を除き、C-API の破壊的変更は避けてください。 -- **ヘッダー生成**: FFI 関数を変更した場合は、C++ ヘッダーが正しく更新・検証されていることを確認してください。 -- **メモリ管理**: FFI 境界を越えてデータをやり取りする場合、メモリの所有権を明確にドキュメント化してください。 +### 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) に同意したものとみなされます。 From 7af47791eb71a275d1c72dae160a0068d5a1c479 Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sat, 20 Jun 2026 01:54:45 +0900 Subject: [PATCH 4/5] docs: add build-runtime step to CONTRIBUTING.md --- CONTRIBUTING.md | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 15f84a1..7bc2efd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,15 +43,23 @@ If you find a bug, please use the provided Issue Templates. Include: - Python 3 and SCons ### Build the Plugin -To compile the Godot Extension, use the provided build scripts: +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 ``` @@ -117,15 +125,23 @@ Godot Engineとのネイティブな統合と高いパフォーマンスを維 - Python 3 および SCons ### ビルド方法 -提供されているスクリプトを使用してGDExtensionをコンパイルします。 +提供されているスクリプトを使用して、まず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 ``` From 01d369901ebf8c86c4fed92a57c3187ece6d8f6c Mon Sep 17 00:00:00 2001 From: Naruto TAKAHASHI Date: Sat, 20 Jun 2026 01:58:47 +0900 Subject: [PATCH 5/5] docs: add GDScript control sample project to examples --- README.ja.md | 5 ++- README.md | 1 + examples/Scripting/.ssplayer_sources.cfg | 9 ++++ examples/Scripting/Main.gd | 52 ++++++++++++++++++++++++ examples/Scripting/Ringo.tscn | 22 ++++++++++ examples/Scripting/icon.svg | 3 ++ examples/Scripting/icon.svg.import | 43 ++++++++++++++++++++ examples/Scripting/project.godot | 27 ++++++++++++ 8 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 examples/Scripting/.ssplayer_sources.cfg create mode 100644 examples/Scripting/Main.gd create mode 100644 examples/Scripting/Ringo.tscn create mode 100644 examples/Scripting/icon.svg create mode 100644 examples/Scripting/icon.svg.import create mode 100644 examples/Scripting/project.godot 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/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" + +