Skip to content
Back to skills

Godot Fix Positions

ASecurity

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 specific position conflict types.

  • 666 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added February 8, 2026
developmentpythongobashnodetestingdebuggingrefactoringgitdocumentation

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill godot-fix-positions --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Godot Fix Positions?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Godot Fix Positions
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-godot-fix-positions/badge)](https://www.skillsdirectory.com/skills/majiayu000-godot-fix-positions)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: godot-fix-positions
version: 3.0.0
displayName: "Godot Position Sync Orchestrator"
description: >
  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 specific position conflict types.
author: "Asreonn"
license: MIT
category: game-development
type: agent
difficulty: beginner
audience: [developers, level-designers]
keywords:
  - godot
  - positions
  - editor-sync
  - camera
  - parallax
  - wysiwyg
  - level-design
  - godot4
platforms: [macos, linux, windows]
repository: https://github.com/asreonn/godot-superpowers
homepage: https://github.com/asreonn/godot-superpowers#readme
filesystem:
  read:
    - "${PROJECT_ROOT}/**/*.gd"
    - "${PROJECT_ROOT}/**/*.tscn"
    - "${PROJECT_ROOT}/project.godot"
  write:
    - "${PROJECT_ROOT}/**/*.gd"
    - "${PROJECT_ROOT}/**/*.tscn"
  deny:
    - "**/.env*"
    - "**/secrets*"
    - "**/*.key"
behavior:
  timeout: 300
  retry: 2
  cache: true
  interactive: true
use_cases:
  - "Node position set in _ready() doesn't match editor preview"
  - "Background follows camera but editor shows wrong position"
  - "Parallax layers jump when game starts"
  - "Want What You See Is What You Get in editor"
  - "Position conflicts making level design confusing"
  - "Need to sync all position types at once"
outputs: "Synced positions, updated .tscn files, clear ownership documentation, git commits per sync type"
requirements: "Git repository, Godot 4.x"
execution: "Automatic detection with user-approved sync strategies"
auto_rollback: "Yes - reverts on validation failure"
integration: "Orchestrates: godot-sync-static-positions, godot-sync-camera-positions, godot-sync-parallax"
---

# 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)

```bash
# 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:

```bash
# 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**
```bash
# Find all Godot script files
find . -name "*.gd" -type f

# Find all scene files
find . -name "*.tscn" -type f
```

2. **Detect Position Assignments**

Scan for position-setting patterns:

```bash
# 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" .
```

3. **Parse .tscn Files for Positions**

Extract position properties from scenes:

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

4. **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:**

```python
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"
```

5. **Create Conflict Manifest**

Generate a priority-ordered list:

| File | Node | Editor Position | Code Position | Classification | Sync Strategy |
|------|------|-----------------|---------------|----------------|---------------|
| background.gd | Background | (0, 0) | camera.position | DYNAMIC | Document intent |
| enemy.gd | Enemy | (500, 300) | (100, 150) | CONFLICT | Code → Editor |
| ui_label.gd | Label | (10, 10) | (50, 50) | CONFLICT | Editor → 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:**
```bash
# 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**
```bash
# Example: enemy.gd sets position in _ready()
grep -A5 "_ready" enemy.gd
```

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

Example .tscn:
```ini
[node name="Enemy" type="CharacterBody2D"]
position = Vector2(500, 300)  # Different from code
```

2. **Update .tscn File**

Parse and update:
```python
# 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)
```

3. **Update .gd File**

Remove static assignment, add comment:
```gdscript
# enemy.gd
func _ready():
    # Position moved to .tscn for editor visibility
    # Was: position = Vector2(100, 150)
    pass
```

4. **Git Commit**
```bash
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"
```

5. **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:
```gdscript
func _ready():
    position = Vector2(100, 150)  # Correct position
```

2. **Reset .tscn to Default**

Update .tscn to neutral position:
```ini
[node name="Enemy" type="CharacterBody2D"]
# position removed (defaults to Vector2(0, 0))
```

Or explicitly set to origin:
```ini
position = Vector2(0, 0)
```

3. **Add Documentation**

Add comment explaining:
```gdscript
func _ready():
    # Position set in code (not in .tscn)
    # Editor shows (0,0), runtime shows calculated position
    position = Vector2(100, 150)
```

4. **Git Commit**
```bash
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()"
```

5. **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**

```gdscript
# background.gd
func _process(delta):
    position = camera.position  # Follows camera
```

2. **Calculate Expected Editor Position**

Find typical camera start position:
```bash
# Search for camera or player spawn position
grep -rn "camera.*position\|player.*position" --include="*.tscn" .
```

Example: Camera starts at (512, 300)

3. **Update .tscn to Camera Start Position**

```ini
[node name="Background" type="Sprite2D"]
position = Vector2(512, 300)  # Camera start position
```

4. **Document Camera-Relative Behavior**

```gdscript
# 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
```

5. **Create Editor Preview Tool (Optional)**

Generate editor plugin to show camera bounds:

```gdscript
# 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

6. **Git Commit**
```bash
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"
```

7. **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**
```bash
godot --editor project.godot
```

2. **Visual verification**
- Open synced scenes in editor
- Compare editor positions with manifest
- Verify positions match expected

3. **Runtime verification**
```bash
# Run main scene for 10 seconds
godot --quit-after 10 project.godot
```

4. **Check for conflicts**
```bash
# Re-run detection to verify all conflicts resolved
grep -rn "position\s*=\s*Vector2(" --include="*.gd" . | wc -l
```

5. **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:

| Rationalization | Reality | Fix |
|----------------|---------|-----|
| "This dynamic position is a conflict" | Misclassification breaks behavior | Use intelligent classifier |
| "I'll sync all positions" | Over-sync breaks intentional dynamic positioning | Only sync true conflicts |
| "Camera-following is a conflict" | Wrong - it's intentional | Skip dynamic patterns |
| "I don't need to test this change" | Untested = broken | Always verify |
| "Close enough in editor" | Iron Law has no exceptions | Exact positions only |
| "I'll manually fix .tscn" | Manual edits create errors | Parse programmatically |

---

## Quick Reference: Conflict → Strategy

| Conflict Type | Detection | Strategy |
|--------------|-----------|----------|
| Static in _ready() | `position = Vector2()` in _ready | Code → Editor |
| Calculated position | `position = calc_spawn()` | Editor → Code |
| Camera-following | `position = camera.position` | Camera-aware |
| Parallax layer | ParallaxLayer + scroll | Camera-aware |
| Player-relative | `position = player.position + offset` | Document dynamic |
| Animation/tween | `tween_property("position")` | SKIP (intentional) |
| Every frame (_process) | position in _process | CRITICAL 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**
```bash
# Find main camera or player spawn point
grep -rn "Camera2D\|player.*position" --include="*.tscn" .
```

2. **Calculate Editor Position**
```python
# Parse camera start position from main scene
camera_start = Vector2(512, 300)  # Example

# Set background .tscn to camera start
background_position = camera_start
```

3. **Update Background .tscn**
```ini
[node name="Background" type="Sprite2D"]
position = Vector2(512, 300)  # Camera start (was 0, 0)
```

4. **Document Behavior**
```gdscript
# background.gd
# EDITOR PREVIEW: Position set to camera start for accurate level design
# RUNTIME: Follows camera dynamically
func _process(delta):
    position = camera.position
```

5. **Create Parallax Handler (If Needed)**

For ParallaxBackground nodes:
```gdscript
# 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.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.