Claude-skill-registry godot-clean-conflicts

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/godot-clean-conflicts" ~/.claude/skills/majiayu000-claude-skill-registry-godot-clean-conflicts && rm -rf "$T"
manifest: skills/data/godot-clean-conflicts/SKILL.md
source content

Clean Conflicting Operations

Core Principle

One source of truth per property. Conflicting operations create undefined behavior and debugging nightmares.

What This Skill Does

Finds patterns like:

# player.gd
func _ready():
    position = Vector2(100, 100)  # Code sets position
    # BUT: .tscn also has position = Vector2(200, 200)
    # CONFLICT: Which position wins?

func _process(delta):
    rotation += delta  # Animation system ALSO modifying rotation
    # CONFLICT: Animation vs code control

Resolves to clear ownership:

# player.gd
# Position is set in .tscn (editor owns position)
# Rotation is controlled by animation (animation owns rotation)

func _process(delta):
    # Rotation conflict removed
    pass

Detection Patterns

Identifies:

Property Conflicts

  • Same property set in code (_ready) and editor (.tscn)
  • Same property modified in _process and _physics_process
  • Property controlled by animation AND code simultaneously

Signal Conflicts

  • Same signal connected multiple times
  • Duplicate lambda connections
  • Signal connect without checking is_connected()

Physics Conflicts

  • RigidBody with code-controlled position (conflicts with physics)
  • CharacterBody with physics_process AND animation control
  • Conflicting collision layers/masks (code vs editor)

Animation Conflicts

  • AnimationPlayer and code both modifying same property
  • Multiple AnimationPlayers controlling same nodes
  • Tween and animation competing for control

When to Use

You're Debugging Unexpected Behavior

Properties have wrong values and you don't know why.

You're Experiencing Race Conditions

Sometimes works, sometimes doesn't (timing-dependent).

You're Seeing Duplicate Events

Signal fires twice, actions happen multiple times.

You're Fighting the Physics Engine

Code tries to control physics body directly.

Process

  1. Scan - Find conflicting operations across code and scenes
  2. Analyze - Determine which operation should own each property
  3. Resolve - Apply conflict resolution strategy
  4. Document - Add comments explaining ownership
  5. Validate - Ensure behavior is now deterministic
  6. Commit - Git commit per conflict resolution

Example Transformations

Conflict 1: Position Set in Both Code and Editor

Before (Conflict):

# enemy.gd
func _ready():
    position = Vector2(500, 300)  # Code says here

# enemy.tscn
[node name="Enemy" type="CharacterBody2D"]
position = Vector2(100, 100)  # Editor says here
# RESULT: Confusing! Editor shows one place, game uses another

After (Resolved - Editor Wins):

# enemy.gd
func _ready():
    # Position is set in scene file for editor visibility
    pass

# enemy.tscn
[node name="Enemy" type="CharacterBody2D"]
position = Vector2(500, 300)  # Updated to match intended position
# RESULT: What You See Is What You Get

Conflict 2: Duplicate Signal Connections

Before (Conflict):

# ui.gd
func _ready():
    button.pressed.connect(_on_button_pressed)

func setup_ui():
    button.pressed.connect(_on_button_pressed)  # CONNECTED AGAIN!
    # RESULT: _on_button_pressed fires TWICE per click

After (Resolved):

# ui.gd
func _ready():
    if not button.pressed.is_connected(_on_button_pressed):
        button.pressed.connect(_on_button_pressed)

func setup_ui():
    # Connection already exists, skip
    pass
# RESULT: Fires exactly once per click

Conflict 3: Animation vs Code Control

Before (Conflict):

# player.gd
func _process(delta):
    sprite.rotation += delta * rotation_speed  # Code controls rotation

# player.tscn has AnimationPlayer controlling sprite.rotation
# RESULT: Jittery rotation, both systems fighting

After (Resolved - Animation Wins):

# player.gd
func _process(delta):
    # Rotation is controlled by animation system
    # Code can trigger animations: animation_player.play("rotate")
    pass

# AnimationPlayer has full control of sprite.rotation
# RESULT: Smooth animation, clear ownership

Conflict 4: Physics Body Position Control

Before (Conflict):

# enemy.gd
extends RigidBody2D

func _physics_process(delta):
    position = target_position  # CONFLICT with physics engine!
    # Physics engine wants to control position
    # Code also tries to control position
    # RESULT: Jittery movement, physics fighting code

After (Resolved - Use Correct Body Type):

# enemy.gd
extends CharacterBody2D  # Changed to CharacterBody for code control

func _physics_process(delta):
    position = target_position  # Now appropriate for CharacterBody
    # CharacterBody2D is designed for code-controlled movement
    # RESULT: Smooth movement, no conflict

Alternative Resolution (Keep RigidBody):

# enemy.gd
extends RigidBody2D

func _physics_process(delta):
    # Use forces instead of direct position control
    apply_force((target_position - position) * force_strength)
    # Work WITH physics engine, not against it
    # RESULT: Realistic physics-based movement

Conflict Resolution Strategies

1. Editor Wins (Position/Rotation/Scale)

Move code-defined values to .tscn for editor visibility.

2. Code Wins (Dynamic State)

Remove editor values when code needs full control.

3. Animation Wins (Animated Properties)

Code triggers animations, doesn't modify properties directly.

4. Physics Wins (RigidBody)

Use forces/impulses instead of direct property control.

5. One-Time Initialization

Establish clear pattern: editor for initial, code for changes.

What Gets Created

  • Conflict resolution documentation
  • Comments explaining ownership decisions
  • Updated code removing conflicts
  • Updated .tscn files with correct values
  • Git commits per conflict type resolved

Smart Analysis

Detects conflict severity:

  • Critical - Causes crashes or data corruption
  • High - Causes incorrect behavior
  • Medium - Causes performance issues
  • Low - Causes confusion but works

Prioritizes resolution:

  1. Critical conflicts first
  2. High-impact conflicts
  3. Performance conflicts
  4. Clarity conflicts

Integration

Works with:

  • godot-sync-static-positions - Resolves position conflicts specifically
  • godot-split-scripts - Separation helps prevent conflicts
  • godot-refactor (orchestrator) - Runs as part of full refactoring

Safety

  • Each resolution strategy validated
  • Behavior preserved or intentionally changed with approval
  • Rollback on validation failure
  • Original code preserved in git history

When NOT to Use

Don't "fix" if:

  • Intentional override pattern (editor default, code overrides)
  • Temporary value (code initializes, then releases control)
  • State machine pattern (different modes own property at different times)
  • Animation blending (intentional property sharing)

Not all conflicts are bugs - some are architectural patterns.

Common Conflicts

Conflict TypeSymptomResolution
Position in _ready + .tscnWrong position in gameEditor wins (move to .tscn)
Duplicate signal connectionEvent fires multiple timesCheck is_connected() first
Animation + code rotationJittery animationAnimation wins (remove code)
RigidBody position controlPhysics glitchesUse forces instead
_process + _physics_processInconsistent behaviorChoose one based on need

Benefits

  • Predictability - Behavior is deterministic
  • Debuggability - Clear ownership makes issues obvious
  • Performance - No redundant operations
  • Maintainability - Clear patterns for future changes
  • WYSIWYG - Editor preview matches game behavior

Documentation Added

For each resolution, adds comments like:

# Position is controlled by .tscn (editor-visible)
# Rotation is controlled by AnimationPlayer "idle"
# Scale is controlled by code (dynamic resizing)

Clear ownership = clear code.

godot-clean-conflicts — OpenSkillIndex