Skip to main content

Overview

The Nyuron Color minigame is a Simon-style sequence memory game where players must replicate increasingly longer color sequences. This script manages the Simon game logic, sequence generation, and player input validation. Script Path: minigames/nyuron_color/scripts/main.gd Extends: Node2D

Exported Variables

None - all configuration is handled through scene setup and constants.

@onready Node References

Crabs (Interactive Elements)

crabs
Dictionary
Dictionary mapping color names to crab node references:
  • "red": $Crabs/CrabRed
  • "blue": $Crabs/CrabBlue
  • "green": $Crabs/CrabGreen
  • "yellow": $Crabs/CrabYellow

UI Elements

score_label
Label
Displays current score (sequence length achieved)
info_label
Label
Shows game state messages: “Observa…”, “Tu turno”, “Bien hecho!”
intro_panel
Control
Initial instruction panel shown before game starts
intro_button
Button
Button to start the game from intro panel
backButton
Button
Pause button visible during gameplay

Game Over Panel

panel
Panel
Game over/pause overlay panel
title
Label
Panel title (“Fallaste” or “Pausa”)
score_lbl
Label
Final score display in game over panel
back_btn
TextureButton
Return to main menu button
retry_btn
TextureButton
Restart game button

State Variables

sequence
Array[String]
The current color sequence the player must replicate. Grows by one color each successful round.Example: ["red", "blue", "red", "yellow"]
player_input
Array[String]
Player’s current input sequence. Cleared at the start of each round.
colors
Array[String]
Available colors for sequence generation: ["red", "blue", "green", "yellow"]
showing_sequence
bool
Whether the game is currently showing the sequence to the player (blocks input)
game_started
bool
Whether the player’s turn has begun (enables crab input)
is_processing_input
bool
Debounce flag to prevent rapid double-taps on crabs
is_paused
bool
Whether the game is paused
last_coins_gained
int
Coins earned in the current session (for display in game over)

Signals

back_to_menu
signal
Emitted when player navigates back to main menu from pause

Core Functions

Game Initialization

_ready
void
Initializes the game:
  • Sets screen to portrait 270x480
  • Hides game UI elements
  • Connects crab press signals
  • Shows intro panel
func _ready() -> void:
    DisplayServer.window_set_size(Vector2i(270, 480))
    DisplayServer.screen_set_orientation(DisplayServer.SCREEN_PORTRAIT)
    randomize()
    
    game_started = false
    showing_sequence = true
    panel.visible = false
    
    intro_panel.visible = true
    info_label.visible = false
    score_label.visible = false
    backButton.visible = false
    
    intro_button.connect("pressed", Callable(self, "_on_intro_pressed"))
    back_btn.connect("pressed", Callable(self, "_on_back_pressed"))
    backButton.pressed.connect(_on_backButton_pressed)
    retry_btn.pressed.connect(_on_retry_pressed)
    
    for c in colors:
        crabs[c].connect("crab_pressed", Callable(self, "_on_crab_pressed"))
_on_intro_pressed
void
Starts the game when intro button is pressed. Hides intro panel and begins first round.

Game Flow

_start_game
void
Resets game state and starts a new game:
  • Clears sequence and player input
  • Resets score to 0
  • Adds first color to sequence
  • Plays the sequence
func _start_game() -> void:
    game_started = false
    showing_sequence = true
    panel.visible = false
    score_label.text = "Puntaje: 0"
    info_label.text = "Observa..."
    sequence.clear()
    player_input.clear()
    _add_color_to_sequence()
    await _play_sequence()
_add_color_to_sequence
void
Adds a random color to the sequence.
func _add_color_to_sequence() -> void:
    var new_color: String = colors[randi() % colors.size()]
    sequence.append(new_color)
    print("Secuencia actual:", sequence)
_play_sequence
void
Shows the current sequence to the player by flashing each crab in order.Behavior:
  • Blocks player input during sequence display
  • Flashes each crab with 0.6s delay between colors
  • Sets game_started = true when finished
  • Updates info label to “Tu turno”
func _play_sequence() -> void:
    showing_sequence = true
    game_started = false
    player_input.clear()
    info_label.text = "Observa..."
    
    for color in sequence:
        if crabs.has(color):
            crabs[color]._flash()
            await get_tree().create_timer(0.6).timeout
    
    showing_sequence = false
    game_started = true
    info_label.text = "Tu turno"

Player Input

_on_crab_pressed
void
Called when player taps a crab. Validates input against expected sequence.Parameters:
  • color (String): Color of the tapped crab
Behavior:
  • Ignores input if game is paused, showing sequence, or processing previous input
  • Uses is_processing_input flag to prevent double-taps (0.1s debounce)
  • Checks if color matches expected position in sequence
  • Calls _game_over() if wrong color
  • Calls _next_round() if sequence completed correctly
func _on_crab_pressed(color: String) -> void:
    if panel.visible or is_paused:
        return
    
    if showing_sequence or not game_started or is_processing_input:
        return
    
    is_processing_input = true
    player_input.append(color)
    crabs[color]._flash()
    
    var index := player_input.size() - 1
    
    if index >= sequence.size():
        is_processing_input = false
        return
    
    if player_input[index] != sequence[index]:
        _game_over()
        is_processing_input = false
        return
    
    if player_input.size() == sequence.size():
        await get_tree().create_timer(0.5).timeout 
        _next_round()
    
    await get_tree().create_timer(0.1).timeout
    is_processing_input = false
_next_round
void
Advances to next round after successful sequence completion.Behavior:
  • Updates score display to current sequence length
  • Shows “Bien hecho!” message
  • Waits 1 second
  • Adds new color to sequence
  • Plays updated sequence
func _next_round() -> void:
    game_started = false
    showing_sequence = true
    score_label.text = "Puntaje: %d" % sequence.size()
    info_label.text = "Bien hecho!"
    await get_tree().create_timer(1.0).timeout
    _add_color_to_sequence()
    await _play_sequence()

Game Over

_game_over
void
Called when player makes a mistake. Saves score and shows game over panel.Scoring:
  • Final score = sequence length achieved
  • Coins earned = sequence length × 20
Integration:
func _game_over() -> void:
    if sequence.size() > 0:
        var score_manager = get_node("/root/ScoreManager")
        if score_manager:
            score_manager.save_high_score("nyuron_color", sequence.size())
            var coins_earned = int(sequence.size() * 20.0)
            if coins_earned > 0 and score_manager:
                score_manager.add_coins(coins_earned)
                print("Ganaste:", coins_earned, "monedas")
                last_coins_gained = coins_earned
    
    game_started = false
    showing_sequence = true
    info_label.text = ""
    score_lbl.text = "Puntaje: %d" % sequence.size()
    $CanvasLayer/GameOverPanel/CoinsEarned.text = "Monedas obtenidas: +%d" % last_coins_gained
    title.text = "Fallaste"
    panel.visible = true
_on_back_pressed
void
Returns to main menu. Resets screen orientation to portrait.
_on_retry_pressed
void
Reloads the current scene to restart the game.
_on_backButton_pressed
void
Toggles pause state when back button pressed during gameplay.

Pause System

pause_game
void
Pauses the game:
  • Sets is_paused = true
  • Blocks sequence display and player input
  • Disables crab input
  • Pauses crab animations
  • Shows pause panel
func pause_game():
    is_paused = true
    showing_sequence = true
    game_started = false
    
    for color in colors:
        if crabs.has(color):
            crabs[color].input_pickable = false
            crabs[color].set_process(false)
            var sprite = crabs[color].get_node("AnimatedSprite2D")
            if sprite and sprite.is_playing():
                sprite.pause()
    
    panel.visible = true
    title.text = "Pausa"
    score_lbl.text = "Puntaje: %d" % sequence.size()
    back_btn.visible = true
    retry_btn.visible = true
resume_game
void
Resumes from pause:
  • Sets is_paused = false
  • Re-enables crab input if not showing sequence
  • Resumes crab animations
  • Hides pause panel
func resume_game():
    is_paused = false
    
    if not showing_sequence:
        game_started = true
    
    for color in colors:
        if crabs.has(color):
            crabs[color].input_pickable = true
            crabs[color].set_process(true)
            var sprite = crabs[color].get_node("AnimatedSprite2D")
            if sprite and not sprite.is_playing():
                sprite.play()
    
    if title.text == "Pausa":
        panel.visible = false

Scene Structure Requirements

The scene must include:
  • Four crab nodes under $Crabs/ (CrabRed, CrabBlue, CrabGreen, CrabYellow)
  • Each crab must emit crab_pressed(color: String) signal and have _flash() method
  • UI labels for score and info
  • Intro panel with start button
  • Game over panel with title, score, back, and retry buttons
  • Back button for pause during gameplay

Nyuron Color Guide

User guide for the Nyuron Color minigame

ScoreManager API

High score and coin management system

Build docs developers (and LLMs) love