Godot Version
godot 4.3
Question
So i've been working on my ultimate tic tac toe game and I've been having an issue. When I start the game, I get (81) errors in the debugger:
and so on, but is there like any way that this error can be fixed without messing up the game/cells?
Here is a picture of my game for referencing:
Here is my miniboard.gd:
#miniboard.gd
extends Control
@export var tween_intensity: float
@export var tween_duration: float
const Cell = preload("res://Scenes/cell.tscn")
var current_player: String = "X"
var board: Array = []
var cells: Array = []
var is_game_end: bool = false
var focusable_cells: Array = []
var current_focus_index: int = 0
@onready var cells_container = $Cells
var small_board_wins = [] # Track wins for small boards
var overall_winner = "" # Track overall winner
var is_initialized = false # Track if the board is initialized
var stats: Dictionary = load_stats() # Load or initialize stats at the start
var active_board = -1 # Initialize with -1 to allow any board on the first move
var focusable_buttons: Array = []
var is_accept_button_processing: bool = false # Flag to track button state
var boards = []
const BOARD_SIZE = 3
const NUM_BOARDS = 9
@onready var winner_label = $WinnerLabel # General winner label
@onready var home_button = $CanvasLayer/Control/HomeTownButton # Reference to the HomeButton
@onready var rematch_button = $CanvasLayer/Control/RematchYourselfButton # Reference to the Rematch button
@onready var state_labels = [
$State1, $State2, $State3, $State4, $State5, $State6, $State7, $State8, $State9
]
@onready var x_playing_label = $XIsPlaying
@onready var o_playing_label = $OIsPlaying
# Declare the variable for your AudioStreamPlayer
var button5_click_player: AudioStreamPlayer = null # Reference to the AudioStreamPlayer for Button5
# Declare labels for each column
var x_win_labels = []
var o_win_labels = []
var tie_labels = [] # Array to hold tie labels for each column
# Function to save stats
func load_stats() -> Dictionary:
var file_path = "user://Stats.cfg"
if not FileAccess.file_exists(file_path):
print("Stats file does not exist. Initializing with default values.")
return {
"Ultimate_Tic_Tac_Toe_Yourself_Won": 0,
"Ultimate_Tic_Tac_Toe_Yourself_Lost": 0,
"Ultimate_Tic_Tac_Toe_AI_Won": 0,
"Ultimate_Tic_Tac_Toe_AI_Lost": 0,
"Simple_Tic_Tac_Toe_AI_Won": 0,
"Simple_Tic_Tac_Toe_Won": 0,
"Simple_Tic_Tac_Toe_AI_Lost": 0,
"Simple_Tic_Tac_Toe_Lost": 0
}
var file = FileAccess.open(file_path, FileAccess.READ)
if file:
var local_stats = {} # Renamed the local variable
while not file.eof_reached():
var line = file.get_line().strip_edges()
var parts = line.split("=")
if parts.size() == 2:
local_stats[parts[0]] = int(parts[1]) # Convert the value to an int
file.close()
return local_stats # Return the renamed variable
else:
print("Failed to open file for reading.")
return {}
func save_stats(new_stats: Dictionary) -> void:
var file_path = "user://Stats.cfg"
var file = FileAccess.open(file_path, FileAccess.WRITE)
if file:
for key in new_stats.keys():
var line = key + "=" + str(new_stats[key]) # Create the line for each key-value pair
file.store_line(line) # Store the line in the file
file.close()
else:
print("Failed to open file for writing.")
func _ready():
if has_node("CanvasLayer/Control/FPS_COUNTER_MINIBOARD"):
$CanvasLayer/Control/FPS_COUNTER_MINIBOARD.add_to_group("fps_counters")
$CanvasLayer/Control/FPS_COUNTER_MINIBOARD.visible = FpsManager.fps_enabled
for label in state_labels:
label.visible = false
if is_initialized: # Prevent re-initialization
return
is_initialized = true # Mark as initialized
stats = load_stats() # Load existing stats
# Initialize AudioStreamPlayer reference and set the sound stream
button5_click_player = $Button5ClickPlayer # Make sure this node exists in the scene
button5_click_player.stream = load("res://Sounds/click.ogg") # Set the path to your sound file
cells.clear()
create_game_board()
setup_buttons()
boards.clear()
small_board_wins = [null, null, null, null, null, null, null, null, null]
winner_label.visible = false
home_button.visible = false
rematch_button.visible = false
_connect_button($CanvasLayer/Control/RematchYourselfButton, "_on_RematchYourself_pressed")
_connect_button($CanvasLayer/Control/HomeTownButton, "_on_HomeTown_pressed")
_connect_button($CanvasLayer/Control/ResetGameButton, "_on_ResetGame_pressed")
$CanvasLayer/Control/RematchYourselfButton.disabled = false
$CanvasLayer/Control/HomeTownButton.disabled = false
$CanvasLayer/Control/ResetGameButton.disabled = false
# Initialize board array
for _i in range(NUM_BOARDS):
var board_array = []
for _j in range(BOARD_SIZE * BOARD_SIZE):
board_array.append("")
boards.append(board_array)
assert(boards.size() == NUM_BOARDS, "Boards not properly initialized")
assert(current_player in ["X", "O"], "Current player not properly set")
assert(active_board in range(-1, NUM_BOARDS), "Active board not properly set")
# Initialize labels for each column
for i in range(1, 10):
var x_label = get_node("XWinLabelColumn" + str(i))
var o_label = get_node("OWinLabelColumn" + str(i))
var tie_label = get_node("ItsATieLabelColumn" + str(i))
if x_label and o_label and tie_label:
x_win_labels.append(x_label)
o_win_labels.append(o_label)
tie_labels.append(tie_label)
x_win_labels[i - 1].visible = false
o_win_labels[i - 1].visible = false
tie_labels[i - 1].visible = false
else:
print("One or more labels not found for column: ", i)
# Add specific buttons to focusable buttons
focusable_buttons.append_array([rematch_button, home_button, $CanvasLayer/Control/RematchYourselfButton])
for button in focusable_buttons:
button.focus_mode = Control.FOCUS_ALL
x_playing_label.visible = true
o_playing_label.visible = false
if not $CanvasLayer/Control/ResetGameButton.is_connected("pressed", Callable(self, "_on_ResetGame_pressed")):
$CanvasLayer/Control/ResetGameButton.connect("pressed", Callable(self, "_on_ResetGame_pressed"))
# Center the main container
var main_container = Control.new()
main_container.name = "MainContainer"
main_container.set_anchors_preset(Control.PRESET_CENTER)
add_child(main_container)
# Create a MarginContainer to add some padding
var margin_container = MarginContainer.new()
margin_container.add_theme_constant_override("margin_top", 50)
margin_container.add_theme_constant_override("margin_left", 50)
margin_container.add_theme_constant_override("margin_right", 50)
margin_container.add_theme_constant_override("margin_bottom", 50)
main_container.add_child(margin_container)
# Create the grid for the boards
var board_grid = GridContainer.new()
board_grid.columns = 3
board_grid.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
board_grid.size_flags_vertical = Control.SIZE_SHRINK_CENTER
margin_container.add_child(board_grid)
# Create the 9 small boards
for i in range(NUM_BOARDS):
var board_container = create_small_board(i)
board_grid.add_child(board_container)
# Add separators between boards
if i % 3 != 2 and i < 6: # Add vertical separators except after the last column
var v_sep = VSeparator.new()
v_sep.custom_minimum_size.x = 4
board_grid.add_child(v_sep)
if i < 6 and i % 3 == 2: # Add horizontal separators after each row except the last
var h_sep = HSeparator.new()
h_sep.custom_minimum_size.y = 4
board_grid.add_child(h_sep)
# Add placeholder nodes to maintain grid alignment
if i < 5: # Don't add after the last row
for _j in range(2): # Add two placeholder separators
var placeholder = Control.new()
placeholder.custom_minimum_size.x = 4
board_grid.add_child(placeholder)
func create_game_board():
cells.clear()
var main_container = Control.new()
main_container.name = "MainGameBoard"
main_container.set_anchors_preset(Control.PRESET_CENTER)
main_container.size_flags_horizontal = Control.SIZE_SHRINK_CENTER
main_container.size_flags_vertical = Control.SIZE_SHRINK_CENTER
add_child(main_container)
var margin_container = MarginContainer.new()
margin_container.add_theme_constant_override("margin_top", 365)
margin_container.add_theme_constant_override("margin_bottom", 20)
margin_container.add_theme_constant_override("margin_left", 300)
margin_container.add_theme_constant_override("margin_right", 20)
main_container.add_child(margin_container)
var board_grid = GridContainer.new()
board_grid.columns = 3
board_grid.add_theme_constant_override("h_separation", 100)
board_grid.add_theme_constant_override("v_separation", 50)
margin_container.add_child(board_grid)
for i in range(NUM_BOARDS):
var board_container = create_small_board(i)
board_grid.add_child(board_container)
# Add separators between boards
for i in range(NUM_BOARDS - 1):
if i % 3 == 2: # After every third board (except the last row)
var h_separator = HSeparator.new()
h_separator.custom_minimum_size.y = 5
board_grid.add_child(h_separator)
elif i < 6: # Vertical separators (except after the last column)
var v_separator = VSeparator.new()
v_separator.custom_minimum_size.x = 5
board_grid.add_child(v_separator)
func create_small_board(board_index: int) -> Control:
var board_container = PanelContainer.new()
board_container.name = "Board" + str(board_index)
var grid = GridContainer.new()
grid.columns = 3
grid.add_theme_constant_override("h_separation", 5)
grid.add_theme_constant_override("v_separation", 5)
board_container.add_child(grid)
for i in range(BOARD_SIZE * BOARD_SIZE):
var cell_index = board_index * BOARD_SIZE * BOARD_SIZE + i
var cell: Button
if cell_index < cells.size():
cell = cells[cell_index]
else:
cell = Cell.instantiate()
cell.name = "Cell" + str(i)
cell.board_index = board_index
cell.cell_index = i
cell.main = self
cells.append(cell)
cell.connect("cell_updated", Callable(self, "_on_cell_updated"))
grid.add_child(cell)
print("Added/Reused cell. Total cells: ", cells.size())
return board_container
func setup_buttons():
# Clear and reinitialize focusable buttons
focusable_buttons.clear()
# Add all cells to focusable buttons
for cell in cells:
focusable_buttons.append(cell)
# Add UI buttons
if has_node("RematchYourselfButton"):
focusable_buttons.append($CanvasLayer/Control/RematchYourselfButton)
if has_node("HomeTownButton"):
focusable_buttons.append($CanvasLayer/Control/HomeTownButton)
if has_node("MiniHomePage"):
focusable_buttons.append($MiniHomePage)
# Set up button properties
for button in focusable_buttons:
button.focus_mode = Control.FOCUS_ALL
func set_initial_focus():
if not focusable_buttons.is_empty():
focusable_buttons[0].grab_focus()
current_focus_index = 0
func _input(_event):
if Input.is_action_just_pressed("ui_right"):
change_focus(1, 0)
get_viewport().set_input_as_handled()
elif Input.is_action_just_pressed("ui_left"):
change_focus(-1, 0)
get_viewport().set_input_as_handled()
elif Input.is_action_just_pressed("ui_down"):
change_focus(0, 1)
get_viewport().set_input_as_handled()
elif Input.is_action_just_pressed("ui_up"):
change_focus(0, -1)
get_viewport().set_input_as_handled()
elif Input.is_action_just_pressed("ui_accept"):
if focusable_buttons[current_focus_index].has_focus():
focusable_buttons[current_focus_index].emit_signal("pressed")
get_viewport().set_input_as_handled() # Prevent double input
func change_focus(dx: int, dy: int):
var grid_size = 3 # 3x3 grid for each small board
@warning_ignore("integer_division")
var current_grid = int(current_focus_index / (grid_size * grid_size))
var position_in_grid = current_focus_index % (grid_size * grid_size)
@warning_ignore("integer_division")
var row = int(position_in_grid / grid_size)
var col = position_in_grid % grid_size
row += dy
col += dx
if row < 0:
if current_grid >= 3:
current_grid -= 3
row = 2
else:
row = 0
elif row > 2:
if current_grid < 6:
current_grid += 3
row = 0
else:
row = 2
if col < 0:
if current_grid % 3 > 0:
current_grid -= 1
col = 2
else:
col = 0
elif col > 2:
if current_grid % 3 < 2:
current_grid += 1
col = 0
else:
col = 2
var new_index = (current_grid * grid_size * grid_size) + (row * grid_size) + col
new_index = clamp(new_index, 0, focusable_buttons.size() - 1)
if new_index != current_focus_index:
current_focus_index = new_index
focusable_buttons[current_focus_index].grab_focus()
func update_state_labels() -> void:
for i in range(state_labels.size()):
state_labels[i].visible = (i == active_board and small_board_wins[i] == null)
for i in range(NUM_BOARDS):
var board_node = get_node("Board" + str(i + 1))
for cell in board_node.get_children():
if cell is Button:
cell.disabled = not is_valid_move(i) or small_board_wins[i] != null
if active_board != -1 and not is_board_full(active_board):
var board_node = get_node("Board" + str(active_board + 1))
for j in range(9):
var cell: Button = board_node.get_child(j)
if cell.text == "":
cell.grab_focus()
current_focus_index = focusable_buttons.find(cell)
break
else:
active_board = find_next_unwon_board()
if active_board != -1:
update_state_labels()
func is_column_locked(board_index: int) -> bool:
var column = board_index % 3
for i in range(3):
var column_board_index = column + (i * 3)
if small_board_wins[column_board_index] == null:
return false
return true
func _process(_delta: float) -> void:
for button in focusable_buttons:
if is_instance_valid(button):
button_hovered(button)
func start_tween(object: Object, property: String, final_val: Variant, duration: float):
var tween = create_tween()
tween.tween_property(object, property, final_val, duration)
func button_hovered(button: Control) -> void:
if not is_instance_valid(button):
return
if not button is Button:
return
button.pivot_offset = button.size / 2
if button.is_hovered() or button.has_focus():
start_tween(button, "scale", Vector2.ONE * tween_intensity, tween_duration)
else:
start_tween(button, "scale", Vector2.ONE, tween_duration)
func _connect_button(button: Button, handler: String):
if button and !button.is_connected("pressed", Callable(self, handler)):
button.connect("pressed", Callable(self, handler))
else:
print(button.name + " not found or already connected.")
# Function to play button click sound
func _play_button_click_sound():
print("Playing button click sound") # Debugging statement
button5_click_player.play() # Play the button click sound
func update_player_labels():
x_playing_label.visible = (current_player == "X")
o_playing_label.visible = (current_player == "O")
func update_cell_color(cell: Button) -> void:
if cell.text != "":
var color = ColorManager.get_player_color(cell.text)
cell.add_theme_color_override("font_color", color)
func _on_cell_updated(cell: Button) -> void:
var board_index = cell.board_index
var cell_index = cell.cell_index
if overall_winner != "" or not is_valid_move(board_index) or small_board_wins[board_index] != null:
return
cell.text = current_player
cell.cell_value = current_player
boards[board_index][cell_index] = current_player
update_cell_color(cell)
cell.disabled = true # Disable the cell after it's been played
if check_winner(board_index):
small_board_wins[board_index] = current_player
update_board_win_label(board_index)
lock_column(board_index)
if check_overall_winner():
display_winner(current_player)
lock_game()
return
active_board = cell_index if small_board_wins[cell_index] == null else find_next_unwon_board()
update_state_labels()
current_player = "O" if current_player == "X" else "X"
update_player_labels()
func is_valid_move(board_index: int) -> bool:
return active_board == -1 or active_board == board_index
func find_next_unwon_board() -> int:
var available_boards = []
for i in range(9):
if small_board_wins[i] == null and not is_board_full(i) and not is_column_locked(i):
available_boards.append(i)
if available_boards.size() > 0:
return available_boards[randi() % available_boards.size()]
return -1 # No unwon boards available
func update_stats(is_win: bool, player: String):
print("Updating stats - is_win:", is_win, "player:", player) # Debugging output
# Ensure the necessary keys are present in the stats dictionary
if not stats.has("Ultimate_Tic_Tac_Toe_Yourself_Won"):
stats["Ultimate_Tic_Tac_Toe_Yourself_Won"] = 0
if not stats.has("Ultimate_Tic_Tac_Toe_Yourself_Lost"):
stats["Ultimate_Tic_Tac_Toe_Yourself_Lost"] = 0
# Update stats based on win/loss and player
if player == "X":
if is_win:
stats["Ultimate_Tic_Tac_Toe_Yourself_Won"] += 1
elif player == "O":
if is_win:
stats["Ultimate_Tic_Tac_Toe_Yourself_Lost"] += 1
save_stats(stats)
func display_winner(player: String) -> void:
if player == "X":
update_stats(true, "X") # Player wins
update_stats(false, "O") # AI loses
winner_label.text = "X wins!"
elif player == "O":
update_stats(false, "X") # Player loses
update_stats(true, "O") # AI wins
winner_label.text = "O wins!"
else:
# It's a tie
update_stats(false, "X")
update_stats(false, "O")
winner_label.text = "It's a Tie!"
# Hide all win labels
for label in x_win_labels:
label.visible = false
for label in o_win_labels:
label.visible = false
for label in tie_labels:
label.visible = false
winner_label.visible = true
home_button.visible = true
rematch_button.visible = true
lock_game()
overall_winner = player
# Update cell colors if needed
for cell in cells:
update_cell_color(cell)
cell.queue_redraw() # Force redraw of the cell
# Set focus to the appropriate button based on the winner
if overall_winner == "X":
rematch_button.grab_focus() # Focus on rematch button
else:
home_button.grab_focus() # Focus on home button
func end_game(is_player_win: bool):
if is_player_win: # If the player won
update_stats(true, "X") # Call with is_win true
else: # Player lost
update_stats(false, "X") # Call with is_win false
func reset_game_state() -> void:
current_player = "X"
small_board_wins = [null, null, null, null, null, null, null, null, null]
overall_winner = ""
active_board = -1
for cell in cells:
cell.disabled = false
cell.text = ""
cell.cell_value = ""
update_state_labels()
func is_board_full(board_index: int) -> bool:
var board_node = get_node("Board" + str(board_index + 1))
for cell in board_node.get_children():
if cell is Button and cell.text == "":
return false # Return false if any cell is empty
return true # Return true if all cells are filled
func lock_game() -> void:
for board_index in range(9):
lock_column(board_index)
active_board = -1
func check_winner(board_index: int) -> bool:
var current_board = boards[board_index]
# Check rows
for i in range(3):
if current_board[i*3] != "" and current_board[i*3] == current_board[i*3+1] and current_board[i*3] == current_board[i*3+2]:
return true
# Check columns
for i in range(3):
if current_board[i] != "" and current_board[i] == current_board[i+3] and current_board[i] == current_board[i+6]:
return true
# Check diagonals
if current_board[0] != "" and current_board[0] == current_board[4] and current_board[0] == current_board[8]:
return true
if current_board[2] != "" and current_board[2] == current_board[4] and current_board[2] == current_board[6]:
return true
return false
func check_overall_winner() -> bool:
for i in range(3):
if small_board_wins[i*3] != null and small_board_wins[i*3] == small_board_wins[i*3+1] and small_board_wins[i*3] == small_board_wins[i*3+2]:
return true
if small_board_wins[i] != null and small_board_wins[i] == small_board_wins[i+3] and small_board_wins[i] == small_board_wins[i+6]:
return true
if small_board_wins[0] != null and small_board_wins[0] == small_board_wins[4] and small_board_wins[0] == small_board_wins[8]:
return true
if small_board_wins[2] != null and small_board_wins[2] == small_board_wins[4] and small_board_wins[2] == small_board_wins[6]:
return true
return false
func update_board_win_label(board_index: int) -> void:
# Update labels based on column index
if small_board_wins[board_index] == "X":
if has_node("XWinLabelColumn" + str(board_index + 1)):
get_node("XWinLabelColumn" + str(board_index + 1)).visible = true
elif small_board_wins[board_index] == "O":
if has_node("OWinLabelColumn" + str(board_index + 1)):
get_node("OWinLabelColumn" + str(board_index + 1)).visible = true
else: # It's a tie
if has_node("ItsATieLabelColumn" + str(board_index + 1)):
get_node("ItsATieLabelColumn" + str(board_index + 1)).visible = true
func lock_column(board_index: int) -> void:
var column = board_index % 3
for i in range(3):
var column_board_index = column + (i * 3)
var board_node = get_node("Board" + str(column_board_index + 1))
for cell in board_node.get_children():
if cell is Button:
cell.disabled = true
update_state_labels()
func _on_hometown_button_pressed() -> void:
button5_click_player.play() # Play the button click sound
print("HomeButton pressed")
await get_tree().create_timer(0.1).timeout # Add a delay
Transition.load_scene("res://Scenes/UI.tscn")
# get_tree().change_scene_to_file("res://UI.tscn") # Update with your actual main menu scene path
func _on_minihomepage_pressed() -> void:
button5_click_player.play() # Play the button click sound
print("MiniHomepage pressed")
await get_tree().create_timer(0.1).timeout # Add a delay
Transition.load_scene("res://Scenes/UI.tscn")
# get_tree().change_scene_to_file("res://UI.tscn") # Update with your actual main menu scene path
func _on_rematchyourselfbutton_pressed() -> void:
button5_click_player.play() # Play the button click sound
print("Rematch button pressed")
await get_tree().create_timer(0.1).timeout # Add a delay
# Call functions to reset the game
clear_board()
reset_labels()
reset_game_state()
rematch_button.visible = false # Hide the rematch button after pressing it
home_button.visible = false # hide after pressed
func clear_board() -> void:
for i in range(boards.size()):
for j in range(boards[i].size()):
boards[i][j] = ""
for cell in cells:
cell.cell_value = ""
cell.text = ""
cell.self_modulate = Color.WHITE
cell.disabled = false
small_board_wins = [null, null, null, null, null, null, null, null, null]
func reset_labels() -> void:
for label in x_win_labels:
label.visible = false
for label in o_win_labels:
label.visible = false
for label in tie_labels:
label.visible = false
winner_label.visible = false # Hide the winner label
func _on_ResetGame_pressed() -> void:
button5_click_player.play() # Play the button click sound
print("Reset Game button pressed")
await get_tree().create_timer(0.1).timeout # Add a delay
reset_game()
func reset_game():
# Clear win labels
for i in range(1, 10):
if has_node("XWinLabelColumn" + str(i)):
get_node("XWinLabelColumn" + str(i)).visible = false
if has_node("OWinLabelColumn" + str(i)):
get_node("OWinLabelColumn" + str(i)).visible = false
if has_node("ItsATieLabelColumn" + str(i)):
get_node("ItsATieLabelColumn" + str(i)).visible = false
is_game_end = false
board = ["", "", "", "", "", "", "", "", ""]
randomize_starting_player()
for cell in cells:
cell.cell_value = ""
cell.text = ""
cell.self_modulate = Color.WHITE
cell.disabled = false
$WinnerLabel.hide()
$CanvasLayer/Control/HomeTownButton.hide()
$CanvasLayer/Control/RematchYourselfButton.hide()
update_player_labels()
func randomize_starting_player():
current_player = "X" if randf() < 0.5 else "O"
update_playing_labels()
func update_playing_labels():
x_playing_label.visible = (current_player == "X")
o_playing_label.visible = (current_player == "O")
And here is my Cell.gd (the script that references my cells to use in miniboard.gd and my other scripts
:
extends Button
signal cell_updated(cell: Button) # Updated signal definition
var main: Control
var cell_value: String = ""
var board_index: int
var cell_index: int
@onready var background = $Background
@onready var border = $Border
func _ready():
custom_minimum_size = Vector2(50, 50)
size_flags_horizontal = SIZE_EXPAND_FILL
size_flags_vertical = SIZE_EXPAND_FILL
var stylebox = StyleBoxFlat.new()
stylebox.set_border_width_all(1)
stylebox.border_color = Color.WHITE
add_theme_stylebox_override("normal", stylebox)
self_modulate.a = 0
pressed.connect(_on_pressed)
func _on_pressed():
draw_cell()
func draw_x():
var tween = create_tween()
self_modulate = Color("#00ffff")
self_modulate.a = 0
text = "X"
cell_value = "X"
tween.tween_property(self, "self_modulate:a", 1, 0.5)
func draw_o():
var tween = create_tween()
self_modulate = Color("#ff4200")
self_modulate.a = 0
text = "O"
cell_value = "O"
tween.tween_property(self, "self_modulate:a", 1, 0.5)
func draw_cell():
if main == null or main.is_game_end or cell_value != "":
return
if main.current_player == "X":
draw_x()
else:
draw_o()
cell_updated.emit(self) # Updated signal emit
func glow(color: Color):
var tween = create_tween()
background.modulate = color
background.modulate.a = 0
tween.tween_property(background, "modulate:a", 1, 0.5)
Here is the SceneTree’s if needed:
Cell.gd:
miniboard.gd:
Any help would be very much appreciated, and let me know if I should remove or add anything, or if you need anything, Thank you so much!!