Sign in

Pixel - GameDev

@pxlheart.co.uk
1.9K followers 89 following 393 posts

• 20 / Gender-Evil {They/Them} • Co-founder and co-director of @5leaf.games • Games educator • Occasional composer • 100% human work only • Professional Idiot Tier VIII • Funny sometimes patreon.com/PixelGameDev

PostsRepliesMedia
Pixel - GameDev @pxlheart.co.uk · 04/08/2026
Spent multiple hours on VC making... This... #TFC #TheFreakCircus #Pierrot #Clown #Clowns #PixelArt #Art
0101
Pixel - GameDev @pxlheart.co.uk · 21/05/2026
Spent 5 hours refactoring the dialogue system. Dialogue can now just be written as plain-text either in the CSV or Excel sheet. Automatically grabs translation strings, character portraits, voices etc. With temp caching too for ✨performance✨ It's 2am I'm going to bed blehh #IndieGameDev #GodotEngine
Excerpt from the localisation Excel sheet:

DIALOGUE_test0	->   Hello!
DIALOGUE_test1	->   Neutral {REDACTED}: [color=red]…
DIALOGUE_test2	->   Angry {REDACTED}: [speed=100]I am [color=red]RED[/color] because I'm[wait=0.5][speed=2][color=red][shake] angry…
DIALOGUE_test3	->   Neutral {REDACTED}: [sound=PLACEHOLDER_family_guy.wav,0.5,2]I am expositioning
1102
Pixel - GameDev @pxlheart.co.uk · 04/03/2026
Semester 2 group project prototype demo complete, after much crashing out. Now to work on other things for a bit before turning this into a full game. Blehh #indiegamedev #gamedev #MadeWithUnity #lowpoly #retro
Main menu of the game project "Kryos", by Kryos Krew. 2 buttons are labelled "PLAY" and "QUIT", with a Tarot card collage in the background, surrounded by fog and particles.Starting room of the game; the protagonist's filthy bedroom. Trash, pizza slices, and pizza boxes is/are scattered everywhere. A UI element at the bottom denotes the empty inventory, and another in the bottom right displays the current objective/tasks.First cinematic of the game. A sleazy job recruiter "Kenneth" asks "Would this face ever deceive you?"

His face really looks like it would deceive you.The first "puzzle" of the game, where the player is tasked with flipping the switches on a breaker to power up the building.
2142
Pixel - GameDev @pxlheart.co.uk · 19/02/2026
2nd semester of Uni, this is the first room of our group project! #indiegamedev #gamedev #MadeWithUnity #Blockbench
Screenshot from the Unity Editor showing a messy, dirty bedroom with pizza boxes, pizza slices, and trash everywhere.
1173
Pixel - GameDev @pxlheart.co.uk · 23/01/2026
"Chopped up Sr Pelo"
PxlHeartDev committed now
020
Pixel - GameDev @pxlheart.co.uk · 23/01/2026
Would @srpelo.bsky.social get mad at me if I chopped up his voice from ENA and turned it into a UTDR-esque dialogue voice text thingy. #indiegamedev #gamedev #godotengine
191
Pixel - GameDev @pxlheart.co.uk · 14/12/2025
Just finished up uni for the semester and I definitely *haven't* already lost my mind.
Wilson from House M.D. drawn in the style of that one Alastor render from Hazbin Hotel. It has the text "I too seek redemption"
030
Pixel - GameDev @pxlheart.co.uk · 27/11/2025
Started university about 11 weeks ago and as part of my course I've had to learn Unity. It's going pretty well so far. Decided to make a procedurally generated infinite racer. Here's the skybox shader! #indiegamedev #gamedev #unity #madewithunity
Cloudy sunset over the mountainsMoonset over the mountains with a star-speckled sky
0123
Pixel - GameDev @pxlheart.co.uk · 12/09/2025
New Twenty Øne Pilots album is FIRE!!! One Way/Days Lie Dormant is an instant favourite. I'm so giddy it's such a good album muehehehe
Screenshot of my last.fm profile showing that I listened to the entire Breach album (bottom to top, City Walls to Intentions)
030
Pixel - GameDev @pxlheart.co.uk · 05/09/2025
Me and a few others have been working on this ✨yuriful✨ masterpierece over in Canada
A wplace screenshot of an incomplete image of the Lumity kiss scene in S2E20 of The Owl House "Clouds on the Horizon"
071
Pixel - GameDev @pxlheart.co.uk · 05/09/2025
Nightmare of a thing to implement but got dragging and rotating inventory items working. As well as shape vertex generation and highlighting items and grid slots. #indiegamedev #gamedev #godotengine #2d
1223
Pixel - GameDev @pxlheart.co.uk · 27/08/2025
Been working on an inventory system teehee #indiegamedev #gamedev #godot #godotengine
A screenshot of a barebones inventory UI with some grid boxes.
There is a 3x3 grid, a 4x2 grid, and a 5x2 grid, stacked on top of each other vertically.
0121
Pixel - GameDev @pxlheart.co.uk · 20/07/2025
Wasted so much time today trying to figure out a way to test this stuff on the same computer blehhhh. Eh whatever, time doing is time learning. Made a couple of bug fixes in my endeavour anyway. #indiegamedev #gamedev #godotengine
A Git commit message, it reads:

PxlHeartDev committed now

More multiplayer set up
Made it so packets aren't read if not in a lobby
Fixed lobby member not being appended to list
Fixed a size check on lobby_members list
Added some error checks to read_p2p_packet()
Made packet types an enum/int instead of string
Removed unnecessary "steam_id" key from packets, they are already sent in the packet header
Did some additional code cleanup in steam.gd
Connected player join signal to the spawner
Fixed player camera active check
Fixed player packet receiving (added matching id check)
Fixed player mesh instance uniqueness
Added a function to clear the player list when the player leaves the game in game_menu.gd

8 files changed. +73, -37 lines changed
1122
Pixel - GameDev @pxlheart.co.uk · 19/07/2025
The woes of spending many hours building a uid system only to realise you've programmed yourself into a corner and it would've been so much easier from the beginning to just use Steam IDs on their own. I'm not crying, you are. #indiegamedev #gamedev #godotengine #godotsteam
Some GDScript, it reads:

# It's at this point I realise how stupidly convoluted I made this
func quit_game() -> void:
	for i in range(1, len(ids)):
		destroy_id(ids.keys()[i])
0211
Pixel - GameDev @pxlheart.co.uk · 16/07/2025
Bubble from TADC going "blehhhh"
010
Pixel - GameDev @pxlheart.co.uk · 16/07/2025
Yeah I'm going to bed it's nearly 4:30am blehhhhhh #indiegamedev #gamedev #godotengine
A Git commit, it reads:

PxlHeartDev committed 2 minutes ago
Various changes and additions
Updated settings Button focus theme
Added a kick button icon
Added a muted mic button icon
Added a Steam button icon
Added Global "online.tscn" and added class "ID" for managing online IDs in a generalised fashion
Added empty child node "Steam" to online.tscn for later user
Updated a number of functions to use the new generalised ID instead of just an int
Removed some references to "Steam"
Added global "voice_manager.tscn" for managing player voice communcation, currently not complete
Made advanded_audio_3d.tscn reach target faster
Added some exported node references across various scripts
Went through many scene files and scripts and fixed and added appropriate focus neighbours
Added default focussed nodes to menus when they open

Added localisation strings for:
GENERIC.volume

31 fles changed. +480, -43 lines changed
192
Pixel - GameDev @pxlheart.co.uk · 16/07/2025
Like this is a really specific case for the player management panels but the code just feels so bulky. Probably just me though. Balatro is thousands of if statements tbf
Some Godot function declarations, they read:

func set_top_neighbour(node: Node) -> void:
	slider.focus_neighbor_top = node.get_path()

func set_bottom_neighbour(node: Node) -> void:
	mute_button.focus_neighbor_bottom = node.get_path()
	kick_button.focus_neighbor_bottom = node.get_path()
	steam_button.focus_neighbor_bottom = node.get_path()
	steam_button.focus_neighbor_right = node.get_path()
	steam_button.focus_next = node.get_path()
010
Pixel - GameDev @pxlheart.co.uk · 16/07/2025
I decided to generalise online IDs to save myself headache later. Also just a good practice in data management. It's been a while since I've written important data-driven systems. It's not likely I'll get the chance to go multiplatform, but it's nice to have the option. #indiegamedev #godotengine
A Godot class declaration, it reads:

class ID:
	enum Platform {
		STEAM,
		XBOX,
		PS,
	}
	
	var platform: Platform
	var id: Variant
	var username: String
	
	func _init(
			_plat: Platform = Platform.STEAM,
			_id: Variant = 0,
	) -> void:
		platform = _plat
		id = _id
		match platform:
			Platform.STEAM:
				# TODO Query Steam for name
				pass
			Platform.XBOX:
				# TODO Query Xbox for name
				pass
			Platform.PS:
				# TODO Query PSN for name
				pass
		username = "Test Name"
050
Pixel - GameDev @pxlheart.co.uk · 15/07/2025
Buttons... #indiegamedev #gamedev #godotengine #ui
Player control panel with player name "Test Name 0",
a volume slider, mute button, kick button, and a steam button.
1171
Pixel - GameDev @pxlheart.co.uk · 14/07/2025
Song (menu) that might play (will show) when you fight Sans (press escape). #indiegamedev #gamedev #godotengine #ui
A simple game menu GUI.

A left band has a title "Game Menu", and three buttons "Resume", "Settings", and "Quit".
The "Settings" button is highlighted in blue along with a long blue horizontal bar to indicate it is hovered.

The right side of the menu has a label that says "The game is NOT paused" in the top corner.
Below that is a title reading "Players" and a number of control panels that read "Test Name 0", "Test Name 1", etc. with horizontal sliders beneath each of them.
0101
Pixel - GameDev @pxlheart.co.uk · 10/07/2025
Control rebinding menu! #indiegamedev #gamedev #godotengine
A settings menu
Contents:

Title label reading "Control Bindings".
Button labelled "Reset to defaults".
Note reading "If you use a different keyboard layout other than QWERTY (UK), these keys may be inaccurate".
Section label reading "Movement Keys".
A number of pairs of labels and buttons (respectively) reading;
"Forward", "W".
"Backward", "S".
"Left", "A".
"Right", "D".
"Jump", "Space".
"Crouch", "Shift".
"Sprint", "Ctrl".
Section label "Action Keys".
Label/Button pair "Interact", "E".
Section label "Miscellaneous Controls".
Label/Button pair "Pause/Back", "Escape". This one is tinted red, as it can not be rebound.
1192
Pixel - GameDev @pxlheart.co.uk · 16/06/2025
Decided to make a small demo of the template (soon to be Dead Air) so far. It shows off: Main menu Settings menu (language, audio, video) Custom hover tooltips Stamina/sprinting Audio occlusion muffling Health & Vignette effects Injured state #indiegamedev #godotengine #ui #3d
0101
Pixel - GameDev @pxlheart.co.uk · 15/06/2025
Working on audio pooling atm and the mesh debug system is pretty cool #indiegamedev #godotengine #3d #audio
A simple 3D scene showing a boombox.
6 debug spheres are visible spaced around it, indicating a sound has played there.GDScript snippet, it reads:

func play_sound(sound: String, pos: Vector3, custom_dist = -1.0) -> void:
	# Sound exists, play from pool
	if sound in sounds.keys():
		var sound_obj := sounds[sound]
		var player := sound_obj.get_player()
		player.position = pos
		if custom_dist != -1.0:
			player.max_distance = custom_dist
		player.play()
		if debug:
			draw(pos, player.max_distance)
	# Sound not found
	else:
		push_warning("Sound %s cannot be played, never pooled" % sound)
081
Pixel - GameDev @pxlheart.co.uk · 14/06/2025
Both Audio and Video tabs are now complete (for what I want for now), things are coming together! #indiegamedev #godotengine #ui
A GitHub commit message, it reads:

PxlHeartDev committed now

Input/Output device & LPF & Oher minor changes
Updated custom tooltip panel alpha and increased its horizontal size for better readability
Updated config.gd to use 2 different functions for initial setting and then updating
Added output and input device selectors to Audio Settings
Added Reduce High (low pass filter) to Audio Settings

Added localisation strings for:
GENERIC.on
GENERIC.off
SETTINGS.audio.reduce_high.off.desc
SETTINGS.audio.reduce_high.weak
SETTINGS.audio.reduce_high.weak.desc
SETTINGS.audio.reduce_high.medium
SETTINGS.audio.reduce_high.medium.desc
SETTINGS.audio.reduce_high.strong
SETTINGS.audio.reduce_high.strong.desc
SETTINGS.audio.reduce_high.vstrong
SETTINGS.audio.reduce_high.vstrong.desc
SETTINGS.audio.reduce_high.tooltip

Updated localisation strings for:
SETTINGS.audio.reduce_high.desc
SETTINGS.video.display (was pasted incorrectly)

12 files changed, +320 -101 lines changedAudio settings tab, it has:
"Audio Settings" title
Button readingh "Reset to defaults"
6 volume sliders
Output & Input device dropdowns
"Reduce high frequencies" dropdownVideo settings tab, it has:
"Video Settings" title
"Reset to defaults" button
"Screen Size" dropdown
"Display" dropdown
"Max FPS" slider
"VSync" dropdown
"Gamma" slider
031
Pixel - GameDev @pxlheart.co.uk · 13/06/2025
More chicanery #indiegamedev #godotengine #ui #3d
A GitHub commit message, it reads:

PxlHeartDev committed now

More settings menu chicanery
Added "bip.wav" sound to the volume sliders
Added custom tooltip scene for settings tooltips
Added gamma to config
Added working gamma slider to Video Settings
Fixed a bug with settings menu scroll buttons not storing the right position when the list was previously scrolled
Made volume sliders fade towards target rather than stepping

Updated localisation strings for:
SETTINGS.video.vsync.tooltip
SETTINGS.video.gamma.desc

16 files changed, +181 -21 lines changedBasic world scene, in the ui is a healthbar and a stamina bar.
The scene shows a mostly flat plane with a few elevations.
The gamma is set to 0.5, so the scene is mostly darkened.Same scene as before, but with the gamma set to 1.5.
The whole world is a lot brighter, maybe because it has you in it :D
051
Pixel - GameDev @pxlheart.co.uk · 12/06/2025
Language switcher babyyyy #indiegamedev #godotengine #ui
A GitHub commit message, it reads:

PxlHeartDeb committed now

Language selector & VSync
Made settings tab animate towards target scroll position of clicked tab, rather than instant switching
Fixed scroll positions sometimes not setting on first opening of settings
Made scroll wheel no longer work on volume sliders and fps slider

Added Language tab
Added language switcher dropdown

Added VSync to Video Settings tab
 - Enabling VSync uncaps FPS
 - VSync preference saves to config
 - Added tooltip

Added fps and current locale to Debug

Removed localisation string for:
SETTINGS.video.vsync.desc

Added localisation strings for:
GENERIC.disabled
GENERIC.enabled
SETTINGS.video.fps.vsync
SETTINGS.video.vsync.disabled.desc
SETTINGS.video.vsync.enabled.desc
SETTINGS.video.vsync.adaptive
SETTINGS.video.vsync.adaptive.desc
SETTINGS.video.vsync.tooltip

15 files changed, +238 -26 lines changedSettings tab.
Title: Language
Contains a dropdown reading "English", with a small down arrow on the far right.Opened language dropdown reading:
ENGLISH
FRENCH | FRANÇAIS
SPANISH | ESPAÑOL
GERMAN | DEUTSCH
ITALIAN | ITALIANO
PORTUGUESE | PORTUGUÊS (BR)
PORTUGUESE | PORTUGUÊS (PT)
RUSSIAN | РУССКИЙ
GREEK | ΕΛΛΗΝΙΚΑ
TURKISH | TÜRKÇE
DANISH | DANSK
NORWEGIAN (NB) | NORSK BOKMÅL
SWEDISH | SVENSKA
DUTCH | NEDERLANDS
POLISH | POLSKI
FINNISH | SUOMI
JAPANESE | 日本語
SIMPLIFIED CHINESE | 简体中文
...
It gets cut off at the bottom
081
Pixel - GameDev @pxlheart.co.uk · 10/06/2025
Started chipping away at the Video Settings panel :p And of course, fully savable to config and localisable :D #indiegamdev #godotengine #ui
A section of the settings menu.
Some title text that says "Video Settings".
A button that reads "Reset to defaults".
A dropdown box labelled "Screen Size", with option "Fullscreen Borderless" selected.
A dropdown box labelled "Display", with option "Display" selected.
A HSlider labelled "Max FPS", set to "Unlimited".Same settings section as before, but;
"Screen Size" is now set to "1920x1080".
"Display" now reads "Not in fullscreen mode", and is tinted red.The "Screen Size" dropdown was clicked, showing a PopupMenu containing, "960x540", "1920x1080", "2880x1620", "Fullscreen", and "Fullscreen Borderless" as options.Localisation document showing translation strings for:

SETTINGS.video.title
SETTINGS.video.button
SETTINGS.video.screen_size
SETTINGS.video.screen_size.desc
SETTINGS.video.screen_size.fullscreen
SETTINGS.video.screen_size.fullscreen_borderless
SETTINGS.video.display
SETTINGS.video.display.desc
SETTINGS.video.display.not_fullscreen
SETTINGS.video.fps
SETTINGS.video.fps.desc
SETTINGS.video.fps.unlimited
SETTINGS.video.vsync
SETTINGS.video.vsync.desc
SETTINGS.video.gamma
SETTINGS.video.gamma.desc

Fully localised in English, also incompletely localised in 27 other languages
120
Pixel - GameDev @pxlheart.co.uk · 05/06/2025
This just in: Local idiot codes until 5am. Lives to regret it. #indiegamedev #godotengine #ui
A GitHub commit message, it reads:

PxlHeartDev committed now

Settings menu & Localisation setup
Added Config singleton, allows for easily setting and getting values in the user config file
Added version (indev_0.0.1) to project.godot

Added Control theme for settings
Fixed some mouse filters in the main menu
Added the settings menu settings.tscn and settings.gd
Added inheritable settings_tab.tscn and settings_tab.gd
Added audio settings tab audio.tscn
Added base instantiable volume_slider.tscn and volume_slider.gd
Added volume sliders for the audio busses to audio.tscn
Added settings.tscn to ui_manager.tscn

Made ui_manager.tscn inherit from Control instead of Node
Added show/hide settings menu functions to ui_manager.gd

Renamed some audio busses for ease
Added "Menu_SFX" audio bus
Added "s_escape_pressed" signal to Player.tscn and added appropriate emittance
Made game_ui.tscn hide or show as appropriate on escape pressed
Added functionality to _on_settings() in main_menu.gd

Added Localisation.xlsm to External
Added Localisation.csv to Project
Added translation strings for:
 - Menu buttons
 - Generic strings (Are you sure?, Default*, Yes, No, Confirm)
 - Settings reset & confirmation*
 - Language title and button
 - Audio title and button
 - Audio volume sliders*
 - Audio volume slider descriptions*
 - Audio in/output device*
 - Audio apply blanket LPF*
 - Video title and button
 - Controls title and button
 - Accessibility title and button^
*String is not fully localised in all 28 languages
^Translation is not 101% accurate

Change bus of test_boombox.tscn's AudioStreamPlayer3D

31 files changed. +719, -12 lines changedAn editor preview of the settings menu.
On the left a title reads "MENU.settings", with 6 buttons below it reading "SETTINGS.language.button",  "SETTINGS.audio.button",  "SETTINGS.video.button",  "SETTINGS.controls.button",  "SETTINGS.accessibility.button",  and "MENU.back" respectively.
On the right is another panel with a title "SETTINGS.audio.title", a button that reads "SETTINGS.reset_defaults", and six HSliders that all read "Master"The in-game view of the settings menu.
On the left a title reads "Settings", with 6 buttons below it reading "Language", "Audio", "Video", "Controls", "Accessiblity", and "Back" respectively.
On the right is another panel with a title "Audio Settings", a button that reads "Reset to defaults", and six HSliders that are labelled "Master Volume", "Player Voice Volume", "World Music Volume", "Other Music Volume", "Game SFX Volume", and "Menu SFX Volume" respectively.
A simple game scene can be scene faintly behind the translucent back panel of the settings menu.
A boombox can be seen playing funky tunes.
283
Pixel - GameDev @pxlheart.co.uk · 02/06/2025
He only knows how to play one song #indiegamedev #godotengine #3d #music
A low poly boombox on a blueprint-esque floor
061
Pixel - GameDev @pxlheart.co.uk · 27/05/2025
Oh my goodness it's been yonks since I've posted anything game dev (sorry!) Recently I've been working on putting together a template for myself for first person games, latest on the chopping block was the game UI: Health bar and vignettes! #indiegamedev #godotengine #3d #ui
A test game scene, a ramp and door are visible but most of the frame is a plane into the horizon, the ground has a sample "blueprinty" dimensions measurement texture.
Note the light green health bar in the bottom left and the yellow stamina bar on the bottom right. A crosshair is also visible in the centre of the screen.
No vignette is visible.Same scene as before.
The health bar is now a orangey red, and is around 40% full.
A very subtle red vignette creeps in the corners of the screen.Same scene as before.
Health bar is now a deep red, at around 10%.
A noticeable dark red vignette seeps in the corners and sides of the screen.A GitHub commit message, it reads:

PxlHeartDev commited 7 minutes ago

Health bar

Added a health bar to the game UI to indicate current player health
Added "s_max_changed" signal to Comp_Health
Attached signals between player health component and UI health bar
Added gradient to health bar; green at 100% health, yellow at 75%, orange at 50%, red at 25%, to dark red when close at 0%. Linearly interpolated
Coloured the stamina bar yellow
Added setters to health and max_health in Comp_Health
Comp_Health now emits changed signals in _ready()
Changed how "s_changed" is emitted in Comp_Health, it's now emitted in the setter rather than called in damage(), die(), and full_heal()
Made "injured" and "seriously injured" thresholds into bools in Comp_Health set in the setter, rather than checking each frame
Adjusted threshold for "seriously injured" multiplier
Injured and seriously injured multiplier now also affects jump height
Renamed some variables for clarity relating to the game UI stamina bar
Current player health now dictates the base damage vignette level. Vignette level is interpolated from weak (-1.5) at 50% health to strong (0.5) at 0% health, -1.5 at any health above 50%
Reworked damage flash to now offset from the base vignette level, again derived from health percent
0101
Pixel - GameDev @pxlheart.co.uk · 24/05/2025
Oh so that's what I've been doing when blacked out. #indiegamedev #godotengine
Steam profile overview showing "Godot Engine" at 667 hours played
0111
Pixel - GameDev @pxlheart.co.uk · 13/02/2025
Some pretty neat things going on for my academy game. Procedurally generated ice texture and world (w/ caves) Took a few iterations but I like how spaghetti the caves are. #indiegamedev #gamedev #godotengine #2d #procgen
An image of an early test of procedural world generation.
The sky is a plain solid grey colour.
The ground is made of a procedurally generated ice texture.
Where there _is_ ice, a light blue is used.
Where the isn't ice in the ground, i.e. where there are caves, the blue colour is dimmed and darkened.
Spaghetti-like caves sprawl through the ice, connecting to each other and breaking through the surface too.
0133
Pixel - GameDev @pxlheart.co.uk · 06/02/2025
I LOVE DITHERING!!!
010
Pixel - GameDev @pxlheart.co.uk · 06/02/2025
Did somebody say early version of a dialogue box? #indiegamedev #gamedev #godotengine
A screenshot of the Godot 2D editor.
In the bottom of the screen is a dialogue box with a picture of Dr. Coomer (Half-Life) on the left, with text to the right reading:
"Hellou, Guordoun!
This is a second line, Gordon!
Look Gordon, third line! We can use these for big paragraphs! AAAAHHHH HELP ME!
I'm thirsty!"
Above the dialogue box is two buttons reading "Option 1" and "Option 2".
1152
Pixel - GameDev @pxlheart.co.uk · 04/02/2025
T'isn't very much, but I thought I'd post an early prototype of the main menu of the game I'm working on for a game dev academy I'm taking part in: #indiegamedev #gamedev #godotengine
A video game main menu, on the right 60% of the screen is an image of Neptune with Triton covering a portion of it.
On the top left is a grey redacted square reading "You don't get to know the game's title yet, buffoon"
Below that is three buttons, from top to bottom:
PLAY, highlighted red and slightly further right than the other two buttons.
SETTINGS, grey and unhighlighted. 
QUIT, grey and unhighlighted. 

In the bottom left is the credits, censored for my privacy. "GDA 2025" is still visible.
1133
Pixel - GameDev @pxlheart.co.uk · 22/12/2024
Ye, that might change things a bit, but the general premise is the same, you can add on from here. This is code from an older project, can't guarantee it will work plug & play for you, code also in alt. I modified this from a tutorial, tried to find it for you but couldn't, there's lots on YT tho.
class_name ControlSettings
extends MarginContainer

@onready var inputButton: 	PackedScene = preload("res://scenes/menus/settings/input_button.tscn")
@export var actionList: 	VBoxContainer

var isRemapping: 		bool = false
var actionToRemap: 		String = ""
var buttonReference: 	Button = null

var remappableActions: Dictionary = {
	"moveRight": "Move Right",
	"moveLeft": "Move Left",
	"interact": "Interact",
}

func isWeb() -> void:
	$Controls/ScrollContainer/Default/Pause/Input.text = "P"

func loadBinds(keybindings: Dictionary) -> void:
	for action: String in keybindings.keys():
		InputMap.action_erase_events(action)
		InputMap.action_add_event(action, keybindings[action])
	createActionList()func createActionList() -> void:
	for item: Button in actionList.get_children():
		item.queue_free()
	
	for action: String in remappableActions:
		var button: 		Button = inputButton.instantiate()
		var actionLabel: 	Label = button.find_child("Action")
		var inputLabel: 	Label = button.find_child("Input")
		
		actionLabel.text = remappableActions[action]
		
		var events: Array[InputEvent] = InputMap.action_get_events(action)
		if events.size() >  0:
			inputLabel.text = events[0].as_text().trim_suffix(" (Physical)")
		else:
			inputLabel.text = ""
		
		actionList.add_child(button)
		
		button.pressed.connect(_start_rebind.bind(button, action))

func _start_rebind(button: Button, action: String) -> void:
	if !isRemapping:
		isRemapping = true
		actionToRemap = action
		buttonReference = button
		button.find_child("Input").text = "Rebinding..."func _input(event: InputEvent) -> void:
	if isRemapping:
		if (event is InputEventKey or event is InputEventMouseButton) and event.pressed:
			if event is InputEventMouseButton and event.double_click:
				event.double_click = false
			if event is InputEventKey and (event.keycode == KEY_ESCAPE or event.keycode == KEY_P):
				updateActionList(buttonReference, InputMap.action_get_events(actionToRemap)[0])
			else:
				InputMap.action_erase_events(actionToRemap)
				InputMap.action_add_event(actionToRemap, event)
				updateActionList(buttonReference, event)
			
			isRemapping = false
			actionToRemap = ""
			buttonReference = null
			
			accept_event()

func updateActionList(button: Button, event: InputEvent) -> void:
	button.find_child("Input").text = event.as_text().trim_suffix(" (Physical)")


func _reset() -> void:
	InputMap.load_from_project_settings()
	createActionList()Two screenshots of the Godot 2D editor

Image 1:
Scene Tree:
MarginContainer: Controls
- VBoxContainer: Controls / Has script
-- Label: Title
-- Label: Hint
-- ScrollContainer: ScrollContainer
--- VBoxContainer: Default
---- Label: Default
---- HBoxContainer: Pause / Has collapsed children
---- HBoxContainer: Grab / Has collapsed children
---- Label: Bindable
---- VBoxContainer: ActionList
----- Button: InputButton / Instantiated scene
---- Button: Reset / Has signal

Scene as seen:
Controls
Click an action to rebind
Default:
Pause ----- Escape / P
Grab/Target ----- Left Mouse Button
Bindable:
A button reading "Action Name ----- Input Key"
A buttonr reading "Reset to defaults"
A scrollbar is on the right

Image 2:
Scene Tree:
Button: InputButton
- MarginContainer: MarginContainer
-- HBoxContainer: HBoxContainer
--- Label: Action
--- Control: Control
--- Label: Input

Scene:
A long button with "Action Name" justified far left, and "Input Key" justified far right.
200
Pixel - GameDev @pxlheart.co.uk · 20/12/2024
I slapped some textures on this here fella and did some more work on the interactable pads Animations of the pads up on Patreon soon! #indiegamedev #gamedev #godotengine #3d
An image of a low-poly elevator with 9 (only 4 and bits of 2 more visible) pads on the inside, with rings hovering over them.
The elevator is textured with pixel art as if it is made of a number of metallic, bolted panels.
171
Pixel - GameDev @pxlheart.co.uk · 19/12/2024
Oh my god forgive me, I completely forgot. You can kinda ignore the ComponentManager system and access the parent node directly if you want, I just did it like this because of the way I like to structure things.
2 GDScript functions

Keep in mind that the var `ray` is a RayCast3D attached to the player camera.

var hoverTarget: Node3D = null:
	set(val):
		if (val == null or val != hoverTarget) and hoverTarget:
			if hoverTarget is Interact_Component:
				hoverTarget.unhovered()
			MainUI.intText("")
		hoverTarget = val

func doRay() -> void:
	hoverTarget = ray.get_collider()
	if ray.is_colliding():
		if hoverTarget is Interact_Component:
			hoverTarget.hovered()A GDScript class
class_name Interact_Component
extends Area3D

@export var manager: ComponentManager
@export var prompt = "Interact"

func _ready() -> void:
	if !manager:
		var p = get_parent() 
		if p is ComponentManager:
			manager = p
		if !p:
			print("Error, interact component has no manager set")

func hovered() -> void:
	MainUI.intText("[E] " + prompt)
	if manager.parent.has_method("hovered"):
		manager.parent.hovered()

func unhovered() -> void:
	if manager.parent.has_method("unhovered"):
		manager.parent.unhovered()

func interact(player: Player) -> void:
	print("I've been interacted with")
	if manager.parent.has_method("interact"):
		manager.parent.interact(player)A Godot Scene Tree
Node3D: ElevatorDock / Inherited, has script
- MeshInstance3D: pad
- MeshInstance3D: ring
- Node3D: Compnent Manager / Has script
-- Area3D Interact_Comp[onent] / Inherited, has script
--- CollisionShape3D: CollisionShape3DThe player model as seen in the editor. (A silly lil robot with a faux-CRT, glowing green face)
The camera is attached to the face/screen surface, with a blue ray coming out of it.
A red arrow label points to the ray, it says "Ray".
110
Pixel - GameDev @pxlheart.co.uk · 19/12/2024
A bit bare-bones atm, but I've started working on implementing interactable objects (and the game start sequence :o). Realising more and more every day how simultaneously easy and difficult it is to make a game. #indiegamedev #gamedev #godotengine #3d
A low-poly cylindrical room with 5 hexagonal pads on the floor, placed near the wall of each of the 9 interior faces (only 5 visible, as we are facing to the right) of the room.
The pads have thin lines coming out of them, debug shapes for a collider area.
In the centre of the screen is a prompt "[E] Interact".
In the top centre of the room (top left of the screen) is a light-source, causing circular light bands to propagate across the ceiling and along the walls.
There is a quantization and dithering post-processing effect applied to the whole screen, sans the text.
1163
Pixel - GameDev @pxlheart.co.uk · 17/12/2024
Oh... That's an abstract liminal dimension designed by a benevolent god for the express purpose of obliterating the minds of and bifurcating the sanity from the poor unfortunate souls blasphemous and driven enough to pursue justice for their celestial misdeeds...
Spongebob meme, fish guy looking at toilet. Distraught. Possibly anguish.
210
Pixel - GameDev @pxlheart.co.uk · 17/12/2024
Oh no
Silly lil fella. The eyes are at *very* different heights now
020
Pixel - GameDev @pxlheart.co.uk · 17/12/2024
I uhh... I messed something up since last I tested the eyes... #indiegamedev #gamedev #godotengine #3d
The same silly lil fella from before, but the "aura" of the scene is a little darker. Also the eyes are at different heights and looking apart.The same silly lil fella from before, but the "aura" of the scene is a little darker. Also the eyes are at different heights and looking inwards/cross-eyed.
1195
Pixel - GameDev @pxlheart.co.uk · 15/12/2024
Looks at you with my autistic eyes :3 #indiegamedev #gamedev #godotengine #3d
A screenshot of a robot with a faux-CRT face
The eyes are wide open, and the mouth is straight, like the yippee creatureA screenshot of a robot with a faux-CRT screen face.
The eyes are ovals, and the mouth makes a slight 3 curve.

Like :3
0292
Pixel - GameDev @pxlheart.co.uk · 15/12/2024
Procrastinated a lot of the day, have a screenshot of the language selection menu :p #indiegamedev #gamedev #godotengine #accessibility
A screen capture of the Settings screen.
On the left 20% of the screen is 6 buttons:
Audio
SETTINGS_video
SETTINGS_controls
SETTINGS_accessibility
A large gap
SETTING_language with a language icon
A small gap
Back

On the right 80%:
TItle: Languages
Then some buttons:
ENGLISH (GB)
ENGLISH (US)
FRENCH | FRANÇAIS
SPANISH | ESPAÑOL
GERMAN | DEUTSCH
ITALIAN | ITALIANO
PORTUGUESE | PORTUGUÊS (BR)
PORTUGUESE | PORTUGUÊS (PT)
191
Pixel - GameDev @pxlheart.co.uk · 14/12/2024
I did a smart thing and now have my game on GitHub so if my laptop explodes I don't cry (too much) because it's all lost. Kind of annoyed though because I accidentally deleted my old diffs, but it's fine I guess :( #indiegamedev #gamedev #github
A GitHub repo:

PxlHeartDev
PxlHeartDev
Recommit
[censored]
 · 
Dec 14, 2024
History
addons/godotsteam
	
Recommit
	
Dec 14, 2024
assets
	
Recommit
	
Dec 14, 2024
globals/client
	
Recommit
	
Dec 14, 2024
scenes
	
Recommit
	
Dec 14, 2024
shaders
	
Recommit
	
Dec 14, 2024
themes
	
Recommit
	
Dec 14, 2024
.gitattributes
	
Initial commit
	
Dec 14, 2024
.gitignore
	
Initial commit
	
Dec 14, 2024
default_bus_layout.tres
	
Recommit
	
Dec 14, 2024
icon.svg
	
Recommit
	
Dec 14, 2024
icon.svg.import
	
Recommit
	
Dec 14, 2024
project.godot
	
Recommit
2132
Pixel - GameDev @pxlheart.co.uk · 12/12/2024
Hi chat, mostly refactoring for today. Although I did start making some flowcharts to keep me right. And I'm also gonna shamelessly promote my (empty) Discord, if you wanna ask questions about my game or game dev or just shoot the shit. I won't bite c: discord.gg/rXFtEAZ8Ek #indiegamedev #gamedev
A flowchart describing how a Multiplayer Game is made/joined.
On the left is a board separated from the chart reading "Game Storage".
Title: Game Flow
Column Card: Multiplayer Game
with the cards "Host", "Join", and "Friends". An arrow points to it from off-screen.
"Host" points to "Create a multiplayer Game" which points to "Load Game World".
"Host" points to "Load existing Game" which points to "Deserialize Game Data"
"Join" and "Friends" both point to "Retrieve existing Game" which points to "Deserialize Game Data".
"Deserialize Game Data" points to "Load Game World"
071
Pixel - GameDev @pxlheart.co.uk · 10/12/2024
Also the "Play" screen
010
Pixel - GameDev @pxlheart.co.uk · 10/12/2024
Don't know if I'm going to be able to fully localise the entire game from head to toe, but I've made a start on at least (most) of the main menu/starting screens. #indiegamedev #gamedev #godotengine #accessibility
1244
Pixel - GameDev @pxlheart.co.uk · 09/12/2024
And a cheeky lil bonus screenshot too of the error reporting
An error box, all in pixel font (Kubasta)

Big title: Oops!
Subtitle: An error occurred
Body: Steam client out of date
Button: OK
010
Pixel - GameDev @pxlheart.co.uk · 09/12/2024
Turns out the other day I kind of reinvented the wheel. Today I ported over my translations and text-resizing system to Godot's built-in Localisation system and it's much nicer and easier to work with in-engine, and to write new translations. #indiegamedev #gamedev #godot #accessibility
An excel sheet showing translation keys and values
Delimiter is comma, terminator is newline.

key,en_UK,en_US,fr_FR
MENU_play,PLAY,,JOUER
MENU_settings,SETTINGS,,OPTIONS
MENU_quit,QUIT,,QUITTER
MENU_host,HOST,,HÉBERGER
MENU_join,JOIN,,JOINDRE
MENU_back,BACK,,RETOUR
,,,
STEAM_connectAttempt,Attempting to connect to Steam,,
STEAM_connectSuccess,Successfully connected to Steam,,
STEAM_loggedIn,"Logged in as {name}, ID {id}",,
STEAM_err.unowned,User does not own the game,,
STEAM_err.unknown,Unknown failure,,
STEAM_err.connect,Unable to connect to Steam,,
STEAM_err.clientOutdated,Steam client out of date,,Fancy main menu screen, buttons are 3D objects in world. They are retro faux-CRT monitors; glowing green with scan lines. They read (respectively) "JOUER", "OPTIONS", and "QUITTER" in pixel font (Kubasta).A screenshot of the Godot inspector for a MeshInstance3D node
Section header: [Gear icon] localisable.gd
Property: Id Override / MENU_quit
Property: Do Rescale / On
Section header: [Box icon] MeshInstance3D
Property: Mesh / A TextMesh reading QUIT in pixel font (Kubasta)A debug output from Godot, it reads:

Attempting to connect to Steam
Successfully connected to Steam
Logged in as [censored], ID [censored]
2122