The ScoreManager is an autoload singleton that handles all persistent game data including high scores, coins, inventory, and equipped items. It uses Godot’s ConfigFile system to save and load player progress.
File Location
nyuron/scripts/ScoreManager.gd.gd
Save Path
All data is stored in:
const SAVE_PATH = "user://high_scores.cfg"
The user:// protocol points to:
- Windows:
%APPDATA%/Godot/app_userdata/[project_name]/
- Linux:
~/.local/share/godot/app_userdata/[project_name]/
- macOS:
~/Library/Application Support/Godot/app_userdata/[project_name]/
- Android/iOS: App-specific sandboxed storage
High Score Management
save_high_score()
Saves a new high score if it exceeds the current record.
The minigame identifier. Valid values:
"memorice"
"turtle_runner"
"worm_catch"
"food_catch"
"counting_animals"
"nyuron_color"
Returns true if a new record was set, false otherwise
Example from worm_catch minigame:
worm_bucket/scripts/main.gd
func _on_game_over() -> void:
var score_manager = get_node("/root/ScoreManager")
if score_manager:
score_manager.save_high_score("worm_catch", score)
var coins_earned = int(score * 2.5)
if coins_earned > 0:
score_manager.add_coins(coins_earned)
get_high_score()
Retrieves the high score for a specific game.
The high score, or 0 if the game is not registered
var best_score = ScoreManager.get_high_score("turtle_runner")
print("Your best: ", best_score)
get_all_scores()
Returns a dictionary containing all high scores.
var all_scores = ScoreManager.get_all_scores()
print(all_scores)
# Output: {"memorice": 450, "turtle_runner": 2100, ...}
Coin Management
add_coins()
Adds or removes coins from the player’s balance.
Amount to add (positive) or subtract (negative)
Usage in minigames:
# Award coins based on score
var coins_earned = int(score * 0.1)
if coins_earned > 0:
score_manager.add_coins(coins_earned)
print("Ganaste:", coins_earned, "monedas")
tienda/Script/store_menu.gd
# Deduct coins when purchasing
if ScoreManager.get_coins() >= item.price:
ScoreManager.add_to_inventory(item.name)
ScoreManager.add_coins(-item.price) # Negative to subtract
get_coins()
Returns the current coin balance.
var coins = ScoreManager.get_coins()
coins_label.text = "Monedas: %s" % coins
Inventory System
add_to_inventory()
Adds an item to the player’s inventory (if not already owned).
The unique name of the item (e.g., "Corona", "Caparazón Azul")
ScoreManager.add_to_inventory("Gafas")
get_inventory()
Returns an array of owned item names.
var owned_items = ScoreManager.get_inventory()
if owned_items.has("Corona"):
print("Player owns the crown!")
Equipped Items
equip_item()
Equips an item from the inventory.
Item category: "caparazon" or "accesorio"
Name of the item to equip. Special values:
"default" - Default shell
"none" - No accessory
Example from shop:
tienda/Script/store_menu.gd
func _on_equip_item(item: Dictionary):
ScoreManager.equip_item(item.category, item.name)
print("Equipado:", item.name)
This emits the skin_updated signal to notify listeners.
get_equipped_item()
Returns the name of the currently equipped item in a category.
"caparazon" or "accesorio"
Usage in main menu:
func update_menu_skin():
var id_cuerpo = ScoreManager.get_equipped_item("caparazon")
var id_accesorio = ScoreManager.get_equipped_item("accesorio")
# ... load corresponding texture
is_equipped()
Checks if a specific item is currently equipped.
if ScoreManager.is_equipped("Caparazón Azul"):
print("Blue shell is active")
Signals
skin_updated
Emitted when an item is equipped. Used to refresh character visuals.
ScoreManager.skin_updated.connect(_on_skin_changed)
func _on_skin_changed():
update_character_appearance()
Data Persistence
File Structure
The save file uses INI-like sections:
[high_scores]
memorize=450
turtle_runner=2100
worm_catch=85
food_catch=1800
counting_animals=320
nyuron_color=14
[player_data]
coins=1250
equipped_items={"caparazon":"Caparazón Azul","accesorio":"Corona"}
[inventory]
items=["Caparazón Azul","Caparazón Verde","Corona","Gafas"]
save_to_file()
Automatically called by other methods to persist changes. Uses ConfigFile to write all data:
func save_to_file():
var config = ConfigFile.new()
config.load(SAVE_PATH)
# Save high scores
for game in high_scores.keys():
config.set_value("high_scores", game, high_scores[game])
# Save coins and equipped items
config.set_value("player_data", "coins", coins)
config.set_value("player_data", "equipped_items", equipped_items)
# Save inventory
config.set_value("inventory", "items", inventory)
var error = config.save(SAVE_PATH)
load_high_scores()
Called automatically in _ready(). Loads all saved data or creates a new file if none exists.
func load_high_scores():
var config = ConfigFile.new()
var error = config.load(SAVE_PATH)
if error != OK:
print("Creando archivo de progreso...")
save_to_file()
return
# Load all sections
for game in high_scores.keys():
high_scores[game] = config.get_value("high_scores", game, 0)
coins = config.get_value("player_data", "coins", 0)
inventory = config.get_value("inventory", "items", [])
equipped_items = config.get_value("player_data", "equipped_items", equipped_items)
Default Values
var high_scores = {
"memorice": 0,
"turtle_runner": 0,
"worm_catch": 0,
"food_catch": 0,
"counting_animals": 0,
"nyuron_color": 0
}
var coins := 0
var inventory: Array = []
var equipped_items = {
"caparazon": "default",
"accesorio": "none"
}
Common Patterns
End-of-Game Reward Flow
func _on_game_over():
var final_score = int(score)
var score_manager = get_node("/root/ScoreManager")
if score_manager and final_score > 0:
# Save high score
score_manager.save_high_score("turtle_runner", final_score)
# Award coins
var coins_earned = int(final_score * 0.1)
if coins_earned > 0:
score_manager.add_coins(coins_earned)
print("Ganaste:", coins_earned, "monedas")
Shop Purchase Flow
func _on_buy_item(item: Dictionary):
if ScoreManager.get_coins() >= item.price:
ScoreManager.add_to_inventory(item.name)
ScoreManager.add_coins(-item.price)
update_coins()
print("Comprado:", item.name)
else:
print("No tienes monedas suficientes")