Architecture Overview
Nyuron is built as a modular ecosystem of minigames in Godot 4, with shared systems for progression, transitions, and state management. This architecture allows each minigame to be developed, tested, and maintained independently while contributing to a unified player experience.
Core Architecture Principles
Modularity Each minigame is a self-contained scene with its own logic, UI, and assets
Shared Systems Autoloaded singletons handle scoring, transitions, and save data
Mobile-First Dynamic resolution scaling and orientation switching per minigame
Scene Independence Minigames can be tested in isolation without loading the full menu
Project Configuration
From project.godot:11-22, Nyuron is configured as a mobile game:
[application]
config/ name = "nyuron"
run/ main_scene = "uid://7q1r7r4yp7fa"
config/ features =PackedStringArray( "4.5" , "Mobile" )
[autoload]
TransitionBlocks = "*res://TransitionBlocks.gd"
ScoreManager = "*res://scripts/ScoreManager.gd.gd"
[display]
window/size/ viewport_width =270
window/size/ viewport_height =480
window/stretch/ mode = "canvas_items"
window/stretch/ scale_mode = "integer"
window/handheld/ orientation =6
The base viewport is 270x480 (portrait), but minigames dynamically switch to 480x270 (landscape) when needed.
Core Systems
Nyuron relies on two critical autoloaded singletons that are accessible from any scene:
ScoreManager (Global State)
The ScoreManager autoload (scripts/ScoreManager.gd.gd:1-125) handles all persistent game data:
# High scores for all 6 minigames (ScoreManager.gd.gd:9-16)
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"
}
Key Methods:
save_high_score(game_name: String, new_score: int) - Updates high score if beaten
get_high_score(game_name: String) - Retrieves current high score
add_coins(amount: int) - Awards coins for gameplay
get_coins() - Returns current coin balance
equip_item(category: String, item_name: String) - Equips cosmetic items
save_to_file() / load_high_scores() - Persistence to user://high_scores.cfg
All minigames should call ScoreManager.save_high_score() when the game ends to track player progress.
TransitionBlocks (Scene Transitions)
The TransitionBlocks autoload (TransitionBlocks.gd:1-97) provides animated scene transitions:
# Creates a spiral wipe effect with colored blocks (TransitionBlocks.gd:54-70)
func wipe_to ( scene_path : String , duration : = 0.1 ):
visible = true
var delay_per_block := 0.004
for i in range ( blocks . size ()):
var idx = block_order [ i ]
var block = blocks [ idx ]
block . visible = true
block . modulate . a = 0.0
var tween := create_tween ()
tween . tween_property ( block , "modulate:a" , 1.0 , duration )\
. set_delay ( i * delay_per_block )
var total_time := duration + blocks . size () * delay_per_block
get_tree (). create_timer ( total_time ). timeout . connect ( func ():
get_tree (). change_scene_to_file ( scene_path )
wipe_out_fade ()
)
Key Features:
Spiral block-based wipe transition
transition_finished signal for UI timing
Smooth fade-in/fade-out on scene load
Used for visual polish between menu and minigames
Main Menu System
The main menu (scripts/main_menu.gd:1-294) serves as the game’s hub:
# UI references from main_menu.gd:4-12
@onready var menu_panel := $ CanvasLayer/MenuSlidePanel
@onready var turtle_button := $ CanvasLayer/MenuSlidePanel / ... / TurtleButton
@onready var worm_button := $ CanvasLayer/MenuSlidePanel / ... / WormButton
@onready var food_button := $ CanvasLayer/MenuSlidePanel / ... / FoodButton
@onready var memorice_button := $ CanvasLayer/MenuSlidePanel / ... / MemoriceButton
@onready var counting_button := $ CanvasLayer/MenuSlidePanel / ... / CountingButton
@onready var color_button := $ CanvasLayer/MenuSlidePanel / ... / ColorButton
@onready var coin_label : Label = $ CanvasLayer/CoinDisplay / ... / CoinLabel
Minigame Launcher Pattern
Each minigame button follows this pattern (main_menu.gd:204-233):
func _on_turtle_pressed ():
DisplayServer . screen_set_orientation ( DisplayServer . SCREEN_LANDSCAPE )
get_tree (). root . set_content_scale_size ( Vector2i ( 480 , 270 ))
get_tree (). change_scene_to_file ( "res://minigames/turtle_run/scenes/main.tscn" )
func _on_worm_pressed ():
DisplayServer . screen_set_orientation ( DisplayServer . SCREEN_PORTRAIT )
get_tree (). root . set_content_scale_size ( Vector2i ( 270 , 480 ))
get_tree (). change_scene_to_file ( "res://minigames/worm_bucket/Scenes/main.tscn" )
Important: Each minigame must set the correct orientation and viewport size before transitioning to ensure proper rendering.
Character Customization
The menu dynamically updates the player character’s appearance (main_menu.gd:98-137):
func update_menu_skin ():
var id_cuerpo = ScoreManager . get_equipped_item ( "caparazon" )
var id_accesorio = ScoreManager . get_equipped_item ( "accesorio" )
var color_suffix = menu_color_codes . get ( id_cuerpo , "" )
var acc_suffix = menu_accessory_codes . get ( id_accesorio , "" )
var folder_path = "res://Accesorios/global/"
var base_filename = "spr_rest"
var final_path = folder_path + base_filename + color_suffix + acc_suffix + ".png"
if ResourceLoader . exists ( final_path ):
var new_texture = load ( final_path )
_apply_texture_to_menu_anim ( new_texture )
Minigame Architecture
Each minigame follows a consistent structure:
Main Scene
Root node (usually Control or Node2D) with a main controller script (main.gd)
UI Layer
CanvasLayer containing:
HUD (score, lives, timer)
Start panel
Game over panel
Pause menu (optional)
Game Logic
Spawners with Timer nodes
Player/character nodes
Collectibles/obstacles
Physics/collision handling
Audio
Background music (AudioStreamPlayer)
Sound effects for actions
Feedback sounds (success/failure)
Directory Structure
nyuron/
├── minigames/
│ ├── turtle_run/ # Landscape runner game
│ ├── worm_bucket/ # Portrait catching game
│ ├── food_catch/ # Portrait food collection
│ ├── memorice/ # Portrait memory card game
│ ├── counting_animals/ # Landscape counting game
│ └── nyuron_color/ # Portrait color matching
├── scripts/
│ ├── main_menu.gd # Main menu controller
│ └── ScoreManager.gd.gd # Global state management
├── scenes/
│ ├── main_menu.tscn # Hub scene
│ └── intro.tscn # First-time intro sequence
├── tienda/ # Shop system for cosmetics
├── Accesorios/ # Character customization assets
├── TransitionBlocks.gd # Scene transition system
└── project.godot # Project configuration
Mobile Optimization
Nyuron is optimized for mobile devices:
Rendering Settings
From project.godot:40-46:
[rendering]
textures/canvas_textures/ default_texture_filter =0
renderer/ rendering_method = "mobile"
textures/vram_compression/ import_etc2_astc =true
2d/snap/ snap_2d_transforms_to_pixel =true
Pixel-perfect filtering for crisp pixel-art
Mobile renderer for performance
Integer scaling to prevent blur
ETC2/ASTC compression for reduced memory usage
Simple touch controls mapped to mouse input (project.godot:33-38):
[input]
click ={
"events" : [InputEventMouseButton, button_index =1]
}
Touch events are automatically translated to mouse button events by Godot, making testing on desktop straightforward.
Aesthetic & Theme
Nyuron features a cohesive underwater/beach pixel-art aesthetic:
Vibrant, child-friendly color palette
Low-resolution sprites for nostalgic pixel-art feel
Animated sprites for characters and UI elements
Consistent visual language across all minigames
The pixel-art style keeps file sizes small (important for mobile) while maintaining visual appeal for young players.
Next Steps
Installation Clone the repository and set up Godot 4
Minigames Deep dive into each minigame’s mechanics