Skip to content
godot-fix-positions logo

Godot Fix Positions Orchestrator

godot-fix-positions

Use when Godot project has position conflicts between editor (.tscn) and code (.gd), camera-following backgrounds, or runtime positions don't match editor preview. Orchestrates all 3 position sync mini-skills: sync-static-positions, sync-camera-positions, and sync-parallax. Each operation targets...

SKILL.md

Full skill instructions

Godot Fix Positions Orchestrator

This orchestrator runs 3 position sync mini-skills in sequence. For individual operations, invoke mini-skills directly.

Core Principle: What You See Is What You Get (WYSIWYG)

Iron Law: Editor preview must match runtime behavior. No surprises.

This skill automatically detects and resolves position conflicts between editor-defined positions (.tscn files) and code-defined positions (.gd files). It handles static conflicts, camera-following backgrounds, parallax layers, and player-relative positioning.


UPON INVOCATION - START HERE

When this skill is invoked, IMMEDIATELY execute the following sequence:

1. Verify Godot Project (5 seconds)

# Check if this is a Godot project
ls project.godot 2>/​dev/​null && echo "✓ Godot project detected" || echo "✗ Not a Godot project"

If NOT a Godot project:

  • Inform user this skill only works on Godot projects
  • Ask if they want to navigate to the correct directory
  • STOP here

If IS a Godot project:

  • Proceed to step 2

2. Begin Phase 1: Detection & Analysis (AUTOMATIC)

Do NOT ask "What would you like me to do?" - Start analyzing immediately.

Execute these commands in parallel:

# Detect static position conflicts
find . -name "*.gd" -exec grep -l "position\s*=" {} \; | head -20

# Find camera-following patterns
grep -rn "position\s*=.*camera\|position\s*=.*player" --include="*.gd" . | head -20

# Find parallax backgrounds
find . -name "*parallax*.tscn" -o -name "*background*.tscn" | head -10

# Count potential conflicts
find . -name "*.gd" -exec grep -c "^\s*position\s*=" {} + | awk '{s+=$1} END {print s}'

3. Present Findings (30 seconds)

Show the user:

=== Editor Position Sync Analysis ===

Project: [project name from project.godot]

Conflicts detected:
- Static position assignments: X
- Camera-following elements: X
- Parallax backgrounds: X
- Player-relative positioning: X

Total: X position conflicts found

Sync includes:
✓ Detect editor vs code position conflicts
✓ Smart classification (intentional vs conflict)
✓ Camera-aware positioning
✓ Multiple sync strategies
✓ Git commit per operation
✓ Auto-rollback on test failure

Would you like me to:
1. Proceed with automatic sync (recommended)
2. Show detailed breakdown first
3. Cancel

4. Wait for User Choice

  • If 1 (Proceed): Start Phase 2 immediately
  • If 2 (Details): Show detailed file-by-file breakdown, then offer to proceed
  • If 3 (Cancel): Exit skill

CRITICAL: Do NOT stop after loading the skill. Do NOT ask "What would you like me to do?" Start with step 1 immediately.


When to Use This Skill

Use this skill when you detect ANY of these symptoms:

Static Position Conflicts:

  • position = Vector2(x, y) in _ready() or _init()
  • Editor shows one position, runtime shows different position
  • Nodes appear in wrong locations when game starts
  • Visual debugging reveals position mismatches

Camera-Following Elements:

  • Backgrounds that follow camera position
  • UI elements that track player
  • Parallax layers with camera sync
  • position = camera.position patterns

Player-Relative Positioning:

  • Nodes positioned relative to player
  • position = player.position + offset patterns
  • Elements that track player movement
  • Camera-relative UI elements

Editor Preview Mismatch:

  • "It looks right in the editor but wrong at runtime"
  • "The background jumps when the game starts"
  • "My UI elements are in the wrong place"
  • "Camera-following nodes don't preview correctly"

Decision Flowchart

User mentions position issues
    ↓
Is it editor vs runtime mismatch?
    ↓ YES                    ↓ NO
Use this skill              Different issue
    ↓
Run Phase 1: Detection
    ↓
Conflicts found?
    ↓ YES                    ↓ NO
Run Phases 2-3              Document clean state

The Three Phases

Phase 1: Detection & Analysis (Automatic)

Purpose: Detect position conflicts and classify them intelligently.

Steps:

  1. Scan Project Files
# Find all Godot script files
find . -name "*.gd" -type f

# Find all scene files
find . -name "*.tscn" -type f
  1. Detect Position Assignments

Scan for position-setting patterns:

# Static position assignments
grep -rn "position\s*=\s*Vector2(" --include="*.gd" .

# Camera-following patterns
grep -rn "position\s*=.*camera" --include="*.gd" .

# Player-following patterns
grep -rn "position\s*=.*player" --include="*.gd" .

# Parallax patterns
grep -rn "ParallaxBackground\|ParallaxLayer" --include="*.gd" .
  1. Parse .tscn Files for Positions

Extract position properties from scenes:

# Find position declarations in .tscn files
grep -rn "^position\s*=\s*Vector2(" --include="*.tscn" .
  1. Intelligent Classification

For each detected position assignment, classify as:

  • CONFLICT: Static position in _ready() differs from .tscn
  • INTENTIONAL_DYNAMIC: Camera/​player following (skip)
  • INTENTIONAL_ANIMATION: Tweens/​animations (skip)
  • PROCESS_ASSIGNMENT: Every-frame in _process() (critical warning)

Classification Logic:

def classify_position_assignment(context):
    # Context = 30 lines around assignment

    # SKIP: Animation/​tween
    if "tween" in context or "create_tween" in context:
        return "INTENTIONAL_ANIMATION"

    # SKIP: Camera following
    if "camera.position" in context or "get_viewport().get_camera" in context:
        return "INTENTIONAL_DYNAMIC"

    # SKIP: Player following
    if "player.position" in context or "target.position" in context:
        return "INTENTIONAL_DYNAMIC"

    # CRITICAL: Every frame assignment
    if "_process(" in context:
        return "PROCESS_ASSIGNMENT"

    # CONFLICT: Static assignment in _ready
    if "_ready(" in context and "Vector2(" in line:
        return "CONFLICT"

    return "UNKNOWN"
  1. Create Conflict Manifest

Generate a priority-ordered list:

FileNodeEditor PositionCode PositionClassificationSync Strategy
background.gdBackground(0, 0)camera.positionDYNAMICDocument intent
enemy.gdEnemy(500, 300)(100, 150)CONFLICTCode → Editor
ui_label.gdLabel(10, 10)(50, 50)CONFLICTEditor → Code

Phase 1 Output:

  • ✓ All position assignments detected
  • ✓ Conflicts classified intelligently
  • ✓ Manifest table generated
  • ✓ Ready for synchronization

Phase 2: Position Synchronization (Three Strategies)

Process conflicts in priority order: Critical → Conflicts → Dynamic

CRITICAL - After Each Operation:

  1. Git commit the changes
  2. Run automatic validation test
  3. If test fails: Auto-revert and report error
  4. If test passes: Continue automatically to next conflict
  5. No user prompt unless test fails or user confirmation needed

Automatic Testing Procedure:

# Quick validation test (runs after each git commit)
echo "Running validation test..."
godot --headless --quit-after 5 project.godot 2>&1 | tee test_output.log

# Check for errors
if grep -q "ERROR\|SCRIPT ERROR\|Parse Error" test_output.log; then
    echo "⚠️  Tests failed - reverting operation"
    git reset --hard HEAD~1
    echo "❌ Operation reverted. Error details:"
    grep "ERROR\|SCRIPT ERROR\|Parse Error" test_output.log
    # STOP and report to user
else
    echo "✓ Tests passed - continuing"
    rm test_output.log
    # CONTINUE to next operation automatically
fi
Strategy A: Code → Editor Sync

Target: Static position conflicts where code position should be editor position

When to use:

  • Code position is intentional final position
  • Editor preview should match runtime
  • Position set once in _ready() and never changes

Process:

  1. Detect Conflict
# Example: enemy.gd sets position in _ready()
grep -A5 "_ready" enemy.gd

Example code:

# enemy.gd
func _ready():
    position = Vector2(100, 150)  # Conflict with .tscn

Example .tscn:

[node name="Enemy" type="CharacterBody2D"]
position = Vector2(500, 300)  # Different from code
  1. Update .tscn File

Parse and update:

# Read .tscn file
with open("enemy.tscn") as f:
    content = f.read()

# Find and replace position line
content = re.sub(
    r'position = Vector2\([^)]+\)',
    'position = Vector2(100, 150)',
    content
)

# Write back
with open("enemy.tscn", "w") as f:
    f.write(content)
  1. Update .gd File

Remove static assignment, add comment:

# enemy.gd
func _ready():
    # Position moved to .tscn for editor visibility
    # Was: position = Vector2(100, 150)
    pass
  1. Git Commit
git add enemy.tscn enemy.gd
git commit -m "Sync: Move enemy position from code to editor (.tscn)

- Updated enemy.tscn position to Vector2(100, 150)
- Removed static position assignment from enemy.gd
- Editor now matches runtime position"
  1. Run automatic test (see Phase 2 header for test procedure)

Success criteria:

  • .tscn position matches intended runtime position
  • Code assignment removed
  • Comment documents change
  • Behavior unchanged

Strategy B: Editor → Code Sync

Target: Position should be set in code, remove .tscn position

When to use:

  • Position is calculated/​dynamic
  • .tscn position is arbitrary/​wrong
  • Code position is source of truth

Process:

  1. Keep Code Assignment

Code already correct:

func _ready():
    position = Vector2(100, 150)  # Correct position
  1. Reset .tscn to Default

Update .tscn to neutral position:

[node name="Enemy" type="CharacterBody2D"]
# position removed (defaults to Vector2(0, 0))

Or explicitly set to origin:

position = Vector2(0, 0)
  1. Add Documentation

Add comment explaining:

func _ready():
    # Position set in code (not in .tscn)
    # Editor shows (0,0), runtime shows calculated position
    position = Vector2(100, 150)
  1. Git Commit
git commit -m "Sync: Keep enemy position in code, reset editor

- Removed position from enemy.tscn (defaults to origin)
- Kept code position assignment
- Runtime position calculated in _ready()"
  1. Run automatic test

Strategy C: Camera-Aware Positioning (SPECIAL)

Target: Backgrounds, parallax layers, camera-following elements

When to use:

  • Background follows camera
  • Parallax layers
  • Player-relative UI elements
  • Dynamic camera positioning

Special Case - User's Background Issue:

Problem: Background positioned at (0, 0) in editor, but follows camera at runtime, causing confusion during level design.

Solution:

  1. Detect Camera-Following Pattern
# background.gd
func _process(delta):
    position = camera.position  # Follows camera
  1. Calculate Expected Editor Position

Find typical camera start position:

# Search for camera or player spawn position
grep -rn "camera.*position\|player.*position" --include="*.tscn" .

Example: Camera starts at (512, 300)

  1. Update .tscn to Camera Start Position
[node name="Background" type="Sprite2D"]
position = Vector2(512, 300)  # Camera start position
  1. Document Camera-Relative Behavior
# background.gd
func _process(delta):
    # EDITOR NOTE: Position in .tscn shows camera start position
    # for accurate level design preview. At runtime, follows camera.
    position = camera.position
  1. Create Editor Preview Tool (Optional)

Generate editor plugin to show camera bounds:

# addons/​camera_preview/​camera_preview.gd
@tool
extends EditorPlugin

func _enter_tree():
    # Draw camera bounds in editor
    pass

Result:

  • Editor shows realistic preview
  • Background appears at expected camera position
  • Level design is accurate
  • Runtime behavior unchanged
  1. Git Commit
git commit -m "Sync: Camera-aware background positioning

- Updated background.tscn to camera start position
- Added documentation for camera-following behavior
- Editor now shows accurate runtime preview"
  1. Run automatic test

Success criteria:

  • Editor preview shows realistic camera view
  • Runtime behavior unchanged
  • Level design is accurate
  • Documentation explains dynamic behavior

Phase 3: Verification & Reporting

Purpose: Ensure synchronization succeeded without regressions.

Steps:

  1. Open project in Godot
godot --editor project.godot
  1. Visual verification
  • Open synced scenes in editor
  • Compare editor positions with manifest
  • Verify positions match expected
  1. Runtime verification
# Run main scene for 10 seconds
godot --quit-after 10 project.godot
  1. Check for conflicts
# Re-run detection to verify all conflicts resolved
grep -rn "position\s*=\s*Vector2(" --include="*.gd" . | wc -l
  1. Generate Report
=== Position Sync Complete ===

Conflicts resolved: X
- Code → Editor: X
- Editor → Code: X
- Camera-aware: X

Files modified:
- X .tscn files updated
- X .gd files updated

Git commits created: X

All tests passing ✓
No regressions detected ✓
Editor preview matches runtime ✓

Supporting Files

This skill uses modular reference files:

  • position-detection-patterns.md: All grep patterns for position detection
  • sync-strategies.md: Detailed step-by-step procedures
  • camera-aware-positioning.md: Camera/​parallax handling
  • validation-tests.md: Testing procedures

Read these files for detailed implementation guidance.


Red Flags - STOP

These thoughts mean you're rationalizing away discipline:

RationalizationRealityFix
"This dynamic position is a conflict"Misclassification breaks behaviorUse intelligent classifier
"I'll sync all positions"Over-sync breaks intentional dynamic positioningOnly sync true conflicts
"Camera-following is a conflict"Wrong - it's intentionalSkip dynamic patterns
"I don't need to test this change"Untested = brokenAlways verify
"Close enough in editor"Iron Law has no exceptionsExact positions only
"I'll manually fix .tscn"Manual edits create errorsParse programmatically

Quick Reference: Conflict → Strategy

Conflict TypeDetectionStrategy
Static in _ready()position = Vector2() in _readyCode → Editor
Calculated positionposition = calc_spawn()Editor → Code
Camera-followingposition = camera.positionCamera-aware
Parallax layerParallaxLayer + scrollCamera-aware
Player-relativeposition = player.position + offsetDocument dynamic
Animation/​tweentween_property("position")SKIP (intentional)
Every frame (_process)position in _processCRITICAL warning

Camera-Aware Positioning - Special Features

For User's Background Use Case

Problem Statement:

  • Background layer positioned at (0, 0) in editor
  • At runtime, background follows camera: position = camera.position
  • Editor shows wrong position → confusing for level design
  • Need: Show correct position in BOTH editor and runtime

Solution:

  1. Detect Camera Start Position
# Find main camera or player spawn point
grep -rn "Camera2D\|player.*position" --include="*.tscn" .
  1. Calculate Editor Position
# Parse camera start position from main scene
camera_start = Vector2(512, 300)  # Example

# Set background .tscn to camera start
background_position = camera_start
  1. Update Background .tscn
[node name="Background" type="Sprite2D"]
position = Vector2(512, 300)  # Camera start (was 0, 0)
  1. Document Behavior
# background.gd
# EDITOR PREVIEW: Position set to camera start for accurate level design
# RUNTIME: Follows camera dynamically
func _process(delta):
    position = camera.position
  1. Create Parallax Handler (If Needed)

For ParallaxBackground nodes:

# parallax_background.gd
@export var camera_start_position := Vector2(512, 300)

func _ready():
    # Set initial scroll to camera start
    scroll_offset = camera_start_position

Result:

  • Editor shows background at camera start position
  • Level design is accurate
  • Runtime follows camera as intended
  • WYSIWYG achieved ✓

Execution Strategy

This skill runs fully automatically:

  1. User invokes skill on Godot project
  2. Phase 1: Scan and report findings
  3. User approves synchronization
  4. Phase 2: Execute all sync operations with commits
  5. Phase 3: Verify and report results

User input required:

  • Initial invocation
  • Approval after Phase 1 analysis
  • Strategy selection (if ambiguous)
  • Final verification check

Everything else is automatic:

  • Position conflict detection
  • Intelligent classification
  • .tscn file updates
  • Script modifications
  • Git commits
  • Testing

Success Criteria

Synchronization is complete when:

  • ✓ All static position conflicts resolved
  • ✓ Camera-following elements documented
  • ✓ Editor preview matches runtime positions
  • ✓ All scenes load without errors
  • ✓ Behavior identical to baseline
  • ✓ Visual appearance unchanged
  • ✓ Clean git history with descriptive commits

Integration with Other Skills

Works well with:

  • godot-refactoring: Refactor before position sync
  • Scene Hierarchy Cleaner: Organize backgrounds into groups
  • Scene Layout Organizer: Align after position sync

Best practice workflow:

  1. Run godot-refactoring (if needed)
  2. Run editor-position-sync
  3. Run scene-hierarchy-cleaner (if needed)
  4. Continue development

Remember: Editor preview is your source of truth for visual design. Runtime must match what you see in the editor. No surprises.

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View