Skip to content

【WIP】Fix spine step#1176

Draft
JiepengTan wants to merge 2 commits intogoplus:devfrom
JiepengTan:pr_fix_spine_step
Draft

【WIP】Fix spine step#1176
JiepengTan wants to merge 2 commits intogoplus:devfrom
JiepengTan:pr_fix_spine_step

Conversation

@JiepengTan
Copy link
Contributor

No description provided.

@JiepengTan JiepengTan marked this pull request as draft January 23, 2026 09:57
@gemini-code-assist
Copy link

Summary of Changes

Hello @JiepengTan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces Spine animation support to the engine, enhancing the animation capabilities with advanced skeletal animations. It includes necessary code refactoring, configuration options, and integration with the physics engine to ensure collision boxes are correctly updated. The changes also include a new Spine manager to handle Spine-related functionalities.

Highlights

  • Spine Animation Support: Adds support for Spine animations, allowing for more advanced and flexible character animations.
  • Physics Integration with Spine: Integrates Spine animations with the physics engine, ensuring collision boxes are correctly updated.
  • Code Refactoring: Refactors the physics manager to physic manager, and introduces a Spine manager to handle Spine-related functionalities.
  • Configuration Options: Introduces new configuration options for Spine animations, such as atlas and skeleton file paths, default mix time, and animation name mappings.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Comment on lines +326 to +327
p.spineConfig = &spineAnimConfig{
Atlas: path.Join(baseDir, cfg.Atlas),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security: Path Traversal Vulnerability

The Spine configuration paths are joined without validation, allowing potential path traversal attacks. A malicious user could provide values like "../../../etc/passwd" in the JSON configuration.

Recommendation: Validate paths to prevent traversal:

// Validate and sanitize paths
atlasPath := filepath.Clean(cfg.Atlas)
skeletonPath := filepath.Clean(cfg.Skeleton)
if strings.Contains(atlasPath, "..") || strings.Contains(skeletonPath, "..") {
    log.Printf("Warning: Invalid path in Spine config for sprite %s", p.name)
    return
}
p.spineConfig = &spineAnimConfig{
    Atlas:      path.Join(baseDir, atlasPath),
    Skeleton:   path.Join(baseDir, skeletonPath),
    // ...
}

Comment on lines +119 to +141
// getDefaultTweenConfig returns default animation config for Spine mode
// when the animation exists in Spine but has no frame animation config
func (p *SpriteImpl) getDefaultTweenConfig() *aniConfig {
stepDuration := 0.01
turnToDuration := 1.0

// Use values from Spine config if available
if p.spineConfig != nil {
if p.spineConfig.StepDuration > 0 {
stepDuration = p.spineConfig.StepDuration
}
if p.spineConfig.TurnToDuration > 0 {
turnToDuration = p.spineConfig.TurnToDuration
}
}

return &aniConfig{
FrameFps: 25,
StepDuration: stepDuration,
TurnToDuration: turnToDuration,
Speed: 1,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Performance: Repeated aniConfig Allocation

This function creates a new aniConfig struct on every call, which happens frequently during Spine sprite movement (Step, Turn, TurnTo operations).

Recommendation: Cache the default config in SpriteImpl during initialization:

type SpriteImpl struct {
    // ...
    spineConfig       *spineAnimConfig
    defaultTweenCfg   *aniConfig  // Cache default config
}

func (p *SpriteImpl) initSpineConfig(...) {
    // ... existing code ...
    p.defaultTweenCfg = &aniConfig{
        FrameFps:       25,
        StepDuration:   p.spineConfig.StepDuration,
        TurnToDuration: p.spineConfig.TurnToDuration,
        Speed:          1,
    }
}

Comment on lines +185 to +187
type ISpineMgr interface {
ClearAllCaches()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation: Missing API Documentation

The new ISpineMgr interface lacks documentation explaining:

  • What the SpineMgr manages (Spine animation system resources)
  • When ClearAllCaches() should be called
  • The impact of clearing caches on performance

Please add godoc comments for this public API.

Comment on lines +258 to +259
SetSpineSkeleton(obj Object, atlas_path string, skeleton_path string, default_mix float64)
ClearSpineSkeleton(obj Object)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Documentation: Missing Method Documentation

The new Spine methods lack documentation. Please add:

// SetSpineSkeleton configures Spine skeletal animation for a sprite.
// Parameters:
//   - atlas_path: Path to the Spine atlas file
//   - skeleton_path: Path to the Spine skeleton file (.skel or .json)
//   - default_mix: Default animation transition blend time in seconds
SetSpineSkeleton(obj Object, atlas_path string, skeleton_path string, default_mix float64)

// ClearSpineSkeleton removes the Spine skeleton configuration from a sprite.
ClearSpineSkeleton(obj Object)

Comment on lines +276 to +284
// Spine animation configuration
type spineAnimConfig struct {
Atlas string `json:"atlas"` // atlas file path, e.g. "spine/spineboy.atlas"
Skeleton string `json:"skeleton"` // skeleton file path, e.g. "spine/spineboy-pro.skel"
DefaultMix float64 `json:"defaultMix"` // animation mix time, default 0.1
AnimMap map[string]string `json:"animMap"` // SPX animation name -> Spine animation name mapping
StepDuration float64 `json:"stepDuration"` // step animation duration factor, default 0.01
TurnToDuration float64 `json:"turnToDuration"` // turn animation duration for 360 degrees, default 1.0
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security: Missing Input Validation

Numeric parameters (DefaultMix, StepDuration, TurnToDuration) loaded from JSON lack validation. Users could provide extreme values (NaN, Infinity, negative numbers, very large values) that could cause:

  • Division by zero in animation calculations
  • Resource exhaustion through extremely long durations
  • Unexpected behavior with NaN propagation

Recommendation: Add validation in initSpineConfig():

if cfg.DefaultMix < 0 || math.IsNaN(cfg.DefaultMix) || math.IsInf(cfg.DefaultMix, 0) {
    log.Printf("Warning: Invalid DefaultMix value, using default")
    cfg.DefaultMix = 0.1
}
// Similar checks for StepDuration and TurnToDuration

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for Spine animations, which is a great addition. The changes are comprehensive, touching configuration, engine wrappers, FFI, and the sprite implementation itself. The new spineAnimConfig and the integration into the animation and physics systems seem well-thought-out. The use of helper functions like isSpineMode, getSpineAnimName, and hasAnimation effectively encapsulates Spine-specific logic, improving code clarity. The refactoring in sprite_transform.go to handle animations that might not have a config (pure Spine animations) by using a default tween config is a good defensive measure.

One significant issue I found is the widespread renaming of "Physics" to "Physic" (e.g., PhysicsMgr to PhysicMgr and IPhysicsMgr to IPhysicMgr). "Physics" is the correct term, and using it would improve clarity and consistency with standard game development terminology. I've added a comment with a suggestion to revert this change.

Overall, this is a solid contribution. Once the naming issue is addressed, it should be good to go.

navigationMgr enginewrap.NavigationMgrImpl
penMgr enginewrap.PenMgrImpl
physicsMgr enginewrap.PhysicsMgrImpl
physicMgr enginewrap.PhysicMgrImpl

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The renaming from physicsMgr to physicMgr seems to be a typo. The correct term is "Physics". For consistency and correctness, it should be physicsMgr. This change is propagated to many files (e.g. IPhysicsMgr to IPhysicMgr, SpxPhysics... to SpxPhysic...) and should be corrected throughout the codebase.

For example, Godot's servers are named PhysicsServer2D and PhysicsServer3D.

Suggested change
physicMgr enginewrap.PhysicMgrImpl
physicsMgr enginewrap.PhysicMgrImpl

NavigationMgr INavigationMgr
PenMgr IPenMgr
PhysicsMgr IPhysicsMgr
PhysicMgr IPhysicMgr

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The renaming from PhysicsMgr to PhysicMgr seems to be a typo. The correct term for the field of study is "Physics", so a manager for it should be named PhysicsMgr. This naming is also more consistent with conventions in game engines like Godot (e.g., PhysicsServer2D). This change is present in many files and should be corrected throughout the codebase for consistency and clarity.

Suggested change
PhysicMgr IPhysicMgr
PhysicsMgr IPhysicsMgr

}

type IPhysicsMgr interface {
type IPhysicMgr interface {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the PhysicMgr variable, the interface should be named IPhysicsMgr for correctness and consistency. "Physics" is the correct term.

Suggested change
type IPhysicMgr interface {
type IPhysicsMgr interface {

@xgopilot
Copy link
Contributor

xgopilot bot commented Jan 23, 2026

Code Review Summary

This PR implements Spine animation support with significant refactoring of animation and physics management. The implementation is well-structured overall with good separation of concerns. However, several noteworthy issues require attention:

Critical Issues

  • Security: Path traversal vulnerability in Spine config file paths (sprite_impl.go:326-327)
  • Security: Missing input validation for numeric parameters that could cause resource exhaustion

Performance Issues

  • Repeated vector allocations in animation loops causing GC pressure
  • Repeated aniConfig allocations in movement operations (recommend caching default config)

Code Quality

  • Direct field access without transform updates may cause rendering inconsistencies (gdspx.go)
  • Redundant hasAnim() function that should be removed

Documentation

  • Missing documentation for new public Spine API methods
  • Some inline comments could be clearer about the Spine initialization flow

Please review the inline comments for specific recommendations and fixes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant