Skip to content

Fix Godot rewrite: controls swapped, movement near-zero, no sprites#3

Open
Copilot wants to merge 12 commits into
masterfrom
copilot/rewrite-project-in-godot
Open

Fix Godot rewrite: controls swapped, movement near-zero, no sprites#3
Copilot wants to merge 12 commits into
masterfrom
copilot/rewrite-project-in-godot

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 21, 2026

Three bugs made the game unplayable: arrow keys were miswired (right moved up, jump triggered on down), all physics ran at 1/60th speed due to px/frame constants in a px/s engine, and every object rendered as a colored rectangle.

Key bindings (project.godot)

Keycodes were off-by-one — move_right pointed at KEY_UP (4194320) and jump at KEY_DOWN (4194322):

  • move_right: 41943204194321 (KEY_RIGHT)
  • jump: 41943224194320 (KEY_UP)

Physics speed (Player.gd, BouncyCreation.gd, room scenes)

GML velocity is px/frame; Godot's move_and_slide() uses px/s and multiplies by delta internally. All constants scaled accordingly, and delta now flows into gravity and acceleration calls:

# Before (GML px/frame copied verbatim)
const MAX_SPEED = 10.0
const GRAVITY   = 0.8
velocity.y += GRAVITY  # delta ignored

# After
const MAX_SPEED = 600.0   # 10 × 60
const GRAVITY   = 2880.0  # 0.8 × 60²
velocity.y += GRAVITY * delta

Bounce force (-25-1500) and moving-block speeds in room scenes fixed on the same basis.

Sprites (godot/assets/sprites/, scene files)

36 PNGs copied from the GameMaker sprites/ tree with clean names. Every ColorRect placeholder replaced:

Scene Before After
Player.tscn ColorRect AnimatedSprite2Didle (3fr), walk (7fr), jump (2fr), slide (1fr)
Enemy.tscn ColorRect AnimatedSprite2D — 2-frame idle
Diamond.tscn ColorRect AnimatedSprite2D — 10-frame spin @ 12 fps
SolidCreation / BouncyCreation ColorRect Sprite2D (creation block; bouncy tinted red)
RoomWarp.tscn ColorRect Sprite2D
Room backgrounds solid ColorRect sky / cloud / city Sprite2D layers

Player.gd drives animation state via a new _update_animation() method and uses flip_h for facing instead of scale.x.


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: LloydNicholson <34131158+LloydNicholson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/LloydNicholson/sluggers/sessions/67343453-c259-4acc-a29f-4ecc6c0684aa
Copilot AI changed the title [WIP] Rewrite entire project in Godot Rewrite Sluggers in Godot 4 Mar 21, 2026
Copilot AI requested a review from LloydNicholson March 21, 2026 11:51
@LloydNicholson LloydNicholson marked this pull request as ready for review March 21, 2026 12:18
Co-authored-by: LloydNicholson <34131158+LloydNicholson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/LloydNicholson/sluggers/sessions/7f017197-065a-4a15-a75c-360717168ee9
Copilot AI changed the title Rewrite Sluggers in Godot 4 Fix Godot rewrite: controls swapped, movement near-zero, no sprites Mar 21, 2026
Copilot AI requested a review from LloydNicholson March 21, 2026 12:45
Copy link
Copy Markdown
Owner

@LloydNicholson LloydNicholson left a comment

Choose a reason for hiding this comment

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

The assets are now loading and movement feels better but the scene is too small compared to the player. None of the enemies are moving but I have a feeling it's because of th scene size

Copilot AI and others added 3 commits March 21, 2026 13:05
…enemy-movement

Expand rooms to 2× viewport width and add enemy patrol movement
Copilot AI and others added 2 commits March 21, 2026 13:26
…nd HUD

Co-authored-by: LloydNicholson <34131158+LloydNicholson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/LloydNicholson/sluggers/sessions/1c3d6d65-a1df-4278-883d-64b69a95b255
…-and-ai

Improve platforming feel, add player health/respawn, enemy chase AI, rooms 2–4, and HUD rebuild
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes several gameplay-breaking issues in the Godot 4 rewrite by correcting input mappings, converting physics constants to Godot’s px/s + delta-based integration, and replacing placeholder visuals with imported sprite assets (plus adding HUD/Pause UI scenes).

Changes:

  • Corrects key bindings in project.godot and adds runtime rebinding support (InputManager + PauseMenu Controls page).
  • Updates player/object movement code and room-scene platform/enemy tuning to use px/s and apply delta correctly.
  • Replaces placeholder visuals across core scenes with AnimatedSprite2D/Sprite2D assets; adds HUD and PauseMenu scenes.

Reviewed changes

Copilot reviewed 34 out of 70 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
godot/scenes/ui/PauseMenu.tscn Adds multi-page pause menu scene structure (main/settings/audio/etc.).
godot/scenes/ui/PauseMenu.gd Pause menu logic, navigation, audio/graphics handlers, and key rebinding input flow.
godot/scenes/ui/HUD.tscn Adds HUD layout (stats panel + respawn overlay).
godot/scenes/ui/HUD.gd HUD bindings to GameState signals for reactive UI updates.
godot/scenes/rooms/Room0.tscn Rebuilds Room0 with backgrounds, entities, warps, camera limits, and UI instances.
godot/scenes/rooms/Room1.tscn Rebuilds Room1 layout/tuning and adds UI/camera instances.
godot/scenes/rooms/Room2.tscn Adds Room2 with midground layers, platforms, enemies, warps, UI/camera.
godot/scenes/rooms/Room3.tscn Adds Room3 with cloud layers, moving platforms, enemies, warps, UI/camera.
godot/scenes/rooms/Room4.tscn Adds Room4 gauntlet layout with moving platforms/enemies, warps, UI/camera.
godot/scenes/player/Player.tscn Replaces placeholder player visuals with AnimatedSprite2D + frames.
godot/scenes/player/Player.gd Player movement/state machine updated for px/s + delta, plus animation/facing updates.
godot/scenes/objects/SolidCreation.tscn Solid creation block now uses a sprite and collision.
godot/scenes/objects/SolidCreation.gd Adds group tagging for player-created solids.
godot/scenes/objects/Solid.tscn Adds solid terrain tile scene with sprite and collision.
godot/scenes/objects/RoomWarp.tscn Room warp now uses sprite + collision shape.
godot/scenes/objects/RoomWarp.gd Scene transition logic on player enter.
godot/scenes/objects/MovingBlock.tscn Moving platform scene (still uses ColorRect visual).
godot/scenes/objects/MovingBlock.gd Delta-based horizontal shuttling logic.
godot/scenes/objects/Enemy.tscn Enemy now uses AnimatedSprite2D and health label.
godot/scenes/objects/Enemy.gd Patrol/chase logic with stomp/damage handling.
godot/scenes/objects/Diamond.tscn Diamond now uses AnimatedSprite2D spin animation.
godot/scenes/objects/Diamond.gd Diamond collection increments GameState.diamonds.
godot/scenes/objects/DeathArea.tscn Adds death-zone area and collision.
godot/scenes/objects/DeathArea.gd Kills player (instant_kill if available) / reload fallback.
godot/scenes/objects/BouncyCreation.tscn Bouncy creation block uses sprite tint + collision.
godot/scenes/objects/BouncyCreation.gd Bounce-on-contact behavior using px/s force.
godot/scenes/camera/GameCamera.tscn Adds camera scene with script.
godot/scenes/camera/GameCamera.gd Lerp-follow camera clamped to room limits.
godot/project.godot Fixes input mappings and sets project/run configuration for Godot rewrite.
godot/autoloads/InputManager.gd Adds action labels + runtime rebinding helpers.
godot/autoloads/GameState.gd Adds global singleton state, signals, pause/timer/resources/health tracking.
godot/assets/sprites/s_solid.png Imported sprite asset.
godot/assets/sprites/s_room_warp.png Imported sprite asset.
godot/assets/sprites/s_player_walk_6.png Imported sprite asset.
godot/assets/sprites/s_player_walk_5.png Imported sprite asset.
godot/assets/sprites/s_player_walk_4.png Imported sprite asset.
godot/assets/sprites/s_player_walk_3.png Imported sprite asset.
godot/assets/sprites/s_player_walk_2.png Imported sprite asset.
godot/assets/sprites/s_player_walk_1.png Imported sprite asset.
godot/assets/sprites/s_player_walk_0.png Imported sprite asset.
godot/assets/sprites/s_player_slide.png Imported sprite asset.
godot/assets/sprites/s_player_jump_1.png Imported sprite asset.
godot/assets/sprites/s_player_jump_0.png Imported sprite asset.
godot/assets/sprites/s_player_idle_2.png Imported sprite asset.
godot/assets/sprites/s_player_idle_1.png Imported sprite asset.
godot/assets/sprites/s_player_idle_0.png Imported sprite asset.
godot/assets/sprites/s_mg_silhoette.png Imported sprite asset.
godot/assets/sprites/s_mg_city.png Imported sprite asset.
godot/assets/sprites/s_mg.png Imported sprite asset.
godot/assets/sprites/s_fg.png Imported sprite asset.
godot/assets/sprites/s_enemy_1.png Imported sprite asset.
godot/assets/sprites/s_enemy_0.png Imported sprite asset.
godot/assets/sprites/s_diamond_9.png Imported sprite asset.
godot/assets/sprites/s_diamond_8.png Imported sprite asset.
godot/assets/sprites/s_diamond_7.png Imported sprite asset.
godot/assets/sprites/s_diamond_6.png Imported sprite asset.
godot/assets/sprites/s_diamond_5.png Imported sprite asset.
godot/assets/sprites/s_diamond_4.png Imported sprite asset.
godot/assets/sprites/s_diamond_3.png Imported sprite asset.
godot/assets/sprites/s_diamond_2.png Imported sprite asset.
godot/assets/sprites/s_diamond_1.png Imported sprite asset.
godot/assets/sprites/s_diamond_0.png Imported sprite asset.
godot/assets/sprites/s_creation_block.png Imported sprite asset.
godot/assets/sprites/s_bg_sky.png Imported sprite asset.
godot/assets/sprites/s_bg_clouds_front.png Imported sprite asset.
godot/assets/sprites/s_bg_clouds_behind.png Imported sprite asset.
godot/assets/sprites/s_bg.png Imported sprite asset.
godot/assets/README.md Documents expected asset structure (now partially outdated).
godot/.gitignore Adds Godot/editor + export artifact ignores.
README.md Expands repo documentation for the Godot rewrite and controls.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +138 to +152
[node name="MoveLeftBtn" type="Button" parent="Menu/ControlsPage"]
layout_mode = 2
text = "Move Left: Left"
metadata/_action = "move_left"

[node name="MoveRightBtn" type="Button" parent="Menu/ControlsPage"]
layout_mode = 2
text = "Move Right: Right"
metadata/_action = "move_right"

[node name="JumpBtn" type="Button" parent="Menu/ControlsPage"]
layout_mode = 2
text = "Jump: Up"
metadata/_action = "jump"

Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

The Controls page buttons declare metadata/_action, but there are no pressed signal connections to call _on_rebind_button_pressed(action). Either connect each button’s pressed to a handler that reads the _action metadata, or wire them up in _ready().

Copilot uses AI. Check for mistakes.
Comment thread godot/assets/README.md Outdated
- `s_bg` / `s_bg_sky` / `s_bg_clouds_behind` / `s_bg_clouds_front` – parallax layers
- `s_fg` / `s_mg` / `s_mg_city` / `s_mg_silhoette` – foreground / midground layers

Until sprites are imported, all scenes use `ColorRect` placeholder visuals.
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

This assets README still states that “Until sprites are imported, all scenes use ColorRect placeholder visuals”, but this PR adds and wires up many sprites. Update/remove that line so the documentation reflects the current state.

Suggested change
Until sprites are imported, all scenes use `ColorRect` placeholder visuals.
Some scenes may still use simple `ColorRect` placeholder visuals where sprites have not yet been imported or wired up.

Copilot uses AI. Check for mistakes.
Comment thread README.md
Comment on lines +37 to +50
│ │ ├── Diamond.* # Collectible gem
│ │ ├── MovingBlock.* # Horizontally-shuttling platform
│ │ ├── Enemy.* # Hazard that restarts the level on contact
│ │ ├── DeathArea.* # Kill-zone (pits, spikes)
│ │ └── RoomWarp.* # Teleport trigger between rooms
│ ├── ui/
│ │ ├── HUD.* # Timer / diamond / creations display
│ │ └── PauseMenu.* # Multi-page pause menu (audio/difficulty/graphics/controls)
│ ├── camera/
│ │ └── GameCamera.* # Lerp-follow camera
│ └── rooms/
│ ├── Room0.tscn # Level 1
│ └── Room1.tscn # Level 2
└── assets/
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

README’s project structure comments are now out of date: it says Enemy.* “restarts the level on contact”, but the new Enemy.gd applies damage/knockback and supports stomping. Also, the room list shows only Room0/Room1 even though Room2–Room4 are added.

Copilot uses AI. Check for mistakes.
Comment on lines +27 to +31
var diamonds: int = 0:
set(value):
diamonds = value
diamonds_changed.emit(diamonds)

Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

The diamonds property setter assigns to diamonds inside its own setter, which will recurse indefinitely in GDScript. Use the implicit field variable (or a separate backing variable) when setting the stored value, then emit the signal.

Copilot uses AI. Check for mistakes.
Comment on lines +55 to +63
func _process(delta: float) -> void:
if is_paused:
return
seconds += delta
if seconds >= 60.0:
seconds -= 60.0
minutes += 1
timer_updated.emit(minutes, int(seconds))

Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

timer_updated is only emitted when a full minute elapses. As a result, HUD timer text will not update during the minute. Consider emitting when the displayed second changes (e.g., track last emitted int(seconds)), or emit every frame and let the HUD format it.

Copilot uses AI. Check for mistakes.
Comment on lines +104 to +120
func _on_master_volume_changed(value: float) -> void:
GameState.master_volume = value
AudioServer.set_bus_volume_db(
AudioServer.get_bus_index("Master"), linear_to_db(value))


func _on_music_volume_changed(value: float) -> void:
GameState.music_volume = value
AudioServer.set_bus_volume_db(
AudioServer.get_bus_index("Music"), linear_to_db(value))


func _on_sound_volume_changed(value: float) -> void:
GameState.sound_volume = value
AudioServer.set_bus_volume_db(
AudioServer.get_bus_index("Sounds"), linear_to_db(value))

Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

Audio bus names "Music" and "Sounds" are assumed to exist, but the repo changes don’t include an audio bus layout defining them. If those buses aren’t present at runtime, get_bus_index() returns -1 and set_bus_volume_db() will error/no-op. Consider shipping a default_bus_layout.tres with these buses or guarding against missing buses (fallback to "Master").

Copilot uses AI. Check for mistakes.
Comment on lines +34 to +38
var creations_remaining: int = 5:
set(value):
creations_remaining = value
creations_changed.emit(creations_remaining)

Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

Same recursion issue as diamonds: the creations_remaining setter assigns to creations_remaining inside its own setter, causing infinite recursion. Use field (or a backing variable) before emitting creations_changed.

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +44
var player_stamina: int = 4:
set(value):
player_stamina = clampi(value, 0, max_player_stamina)
health_changed.emit(player_stamina, max_player_stamina)
var max_player_stamina: int = 4
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

The player_stamina setter assigns to player_stamina inside its own setter, which will recurse. Use field = clampi(value, 0, max_player_stamina) (or a backing variable) before emitting health_changed.

Copilot uses AI. Check for mistakes.
Comment on lines +74 to +83
func pause() -> void:
is_paused = true
get_tree().paused = true
paused.emit()


func resume() -> void:
is_paused = false
get_tree().paused = false
resumed.emit()
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

pause() sets get_tree().paused = true, but the pause menu/UI nodes need to be configured to keep processing input while paused (e.g., process_mode = PROCESS_MODE_ALWAYS). Without that, users may be unable to interact with the PauseMenu to resume or change settings.

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +29
[node name="ResumeButton" type="Button" parent="Menu/MainPage"]
layout_mode = 2
text = "Resume"

[node name="SettingsButton" type="Button" parent="Menu/MainPage"]
layout_mode = 2
text = "Settings"

[node name="QuitButton" type="Button" parent="Menu/MainPage"]
layout_mode = 2
text = "Quit"
Copy link

Copilot AI Mar 21, 2026

Choose a reason for hiding this comment

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

These Buttons are defined but there are no signal connections in the scene file (no [connection] entries), and PauseMenu.gd doesn’t currently connect their pressed signals in _ready(). As-is, Resume/Settings/Quit won’t trigger any of the _on_*_pressed() handlers.

Copilot uses AI. Check for mistakes.
Co-authored-by: LloydNicholson <34131158+LloydNicholson@users.noreply.github.com>
Agent-Logs-Url: https://github.com/LloydNicholson/sluggers/sessions/13e748d7-103d-4e85-8ddf-14055db550d4
…ents-in-pr-3

[WIP] Fix all unresolved comments in pull request #3
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.

3 participants