
Godot Theme Easter
- 121 installs
- 454 repo stars
- Updated July 28, 2026
- thedivergentai/gd-agentic-skills
Helps with ai & agent building tasks during AI-assisted development.
About
godot-theme-easter is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- godot-theme-easter
- AI & Agent Building
- AI-coding skill
Godot Theme Easter by the numbers
- 121 all-time installs (skills.sh)
- +8 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #3,797 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/thedivergentai/gd-agentic-skills --skill godot-theme-easterAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 121 |
|---|---|
| repo stars | ★ 454 |
| Last updated | July 28, 2026 |
| Repository | thedivergentai/gd-agentic-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Easter Theme (Aesthetics & Juice)
Overview
This skill provides the assets and logic to "Easter-fy" a game. It focuses on the Classic Easter aesthetic: bright pastels, bouncy animations, and egg/bunny iconography.
Core Components (Expert Easter Tools)
easter_squash_stretch_juice.gd
Expert 'Squash and Stretch' logic for organic egg-like interactions using Tweens.
easter_runtime_ui_themer.gd
Runtime theme injector for applying mass pastel styles across the UI tree.
easter_shimmer_vfx_emitter.gd
Professional 'Hidden Item' shimmer effect with additive blending and scale curves.
easter_seasonal_activation_gate.gd
Date-aware manager for automatic activation of seasonal event content.
easter_egg_collection_tracker.gd
Expert registry for tracking hidden items with signal-based progression signals.
easter_mesh_painter_override.gd
Seasonal 3D material swapper using surface overrides to preserve base assets.
easter_wobble_physics_body.gd
Instability-driven physics body for 'Egg-like' wobbly movement.
easter_camera_pop_juice.gd
Immersive FOV 'kick' logic to emphasize collection or pop events.
easter_confetti_canon_vfx.gd
Celebratory confetti explosion with multi-colored pastel flakes.
easter_pastel_color_palette.gd
Static utility containing curated, harmonious Easter color tokens.
easter_custom_cursor_manager.gd
Expert logic for swapping system mouse cursors with themed Easter icons.
easter_seasonal_audio_swapper.gd
Dynamic audio resource loader that replaces standard UI sounds with seasonal variants.
Visual Guidelines
- Colors:
- Pink:
#FFC1CC - Cyan:
#E0FFFF - Yellow:
#FFFFE0 - Mint:
#98FF98 - Shapes: Rounded corners (
corner_radius> 8px). Avoid sharp edges. - VFX: Confetti, sparkles, and ribbons.
NEVER Do (Expert Easter Rules)
Aesthetics & Juice
- NEVER use sharp edges or high-contrast blacks — Easter aesthetics favor rounded corners (
corner_radius > 12) and soft pastel tones. - NEVER use standard linear scaling for pops — Linear scaling feels 'robotic.' Always use
TRANS_ELASTICorTRANS_QUARTfor organic eggs. - NEVER use billboarding for Easter particles — In close-up UI or VR, billboard sparkles look flat. Use mesh-based particles or axial rotation.
Logic & Performance
- NEVER modify the original .mesh or .tres resource — Swapping materials on a shared Resource changes it for EVERY instance in the game. Always use
surface_overrideorduplicate(). - NEVER run date-checks in _process — Checking the system calendar every frame is wasteful. Run
Time.get_date_dict_from_system()once on_readyor event trigger. - NEVER ignore the 'No-Seasonal' toggle — Some players hate seasonal overrides. Always provide a 'Disable Seasonal Themes' option in settings.
Elite Theming Hooks
- Dynamic Z-Ordering: Use
RenderingServer.canvas_item_set_draw_index()to dynamically move collected egg particles to the front of the UI stack without reparenting nodes. - Physics Interpolation: When using
TRANS_ELASTICtweens on physics-driven eggs, invokeRenderingServer.canvas_item_reset_physics_interpolation()to prevent visual "jitter" on the first frame of the pop animation. - StyleBox Overrides: Use
Control.add_theme_stylebox_override("panel", my_stylebox)instead of modifying the global Theme to isolate seasonal changes to specific UI modules.
Expert Easter Implementation
1. Custom-Mouse-Cursor (Juice)
Replacing the standard arrow with a themed Easter icon (e.g., a bunny ear).
- Implementation:
func _apply_easter_cursor():
var cursor_img = preload("res://ui/easter/cursor_bunny.png")
Input.set_custom_mouse_cursor(cursor_img, Input.CURSOR_ARROW, Vector2(16, 16))- Expert Note: Always define a
hotspot(the pixel that actually clicks). For a bunny ear, this is usually the center or base of the ear.
2. Themed-Sound-Loaders
Dynamically swapping UI sounds (e.g., button clicks) for "bouncy" or "egg-pop" variants.
- Pattern: Use a
Resourcemap to store original vs. seasonal sound pairs.
@export var sound_overrides: Dictionary # String -> AudioStream
func play_seasonal_sfx(original_name: String):
var stream = sound_overrides.get(original_name, default_sounds[original_name])
sfx_player.stream = stream
sfx_player.play()3. World-Environment-Override (Spring Glow)
Using code to transition the game's atmosphere without creating a new scene.
- Implementation:
func _apply_spring_env(env: Environment):
var tween = create_tween()
tween.tween_property(env, "ambient_light_color", Color("#FFF4E0"), 2.0)
tween.tween_property(env, "tonemap_exposure", 1.2, 2.0)
tween.tween_property(env, "fog_light_color", Color("#E0FFFF"), 2.0)- Expert Note: Smoothly tweening these properties during a loading screen or transition prevents the "Sudden Change" glitch.
class_name BouncyEggComponent
extends RigidBody3D
## A RigidBody that wobbles like an egg.
## Requires a collision shape.
@export var wobble_strength: float = 0.5
@export var squash_factor: float = 0.2
var _original_scale: Vector3
func _ready() -> void:
_original_scale = scale
# Offset center of mass to make it bottom-heavy (classic wobble)
center_of_mass = Vector3(0, -0.3, 0)
body_entered.connect(_on_impact)
contact_monitor = true
max_contacts_reported = 1
func _on_impact(body: Node) -> void:
# Squash and stretch on impact
var tween = create_tween()
tween.set_trans(Tween.TRANS_ELASTIC)
tween.set_ease(Tween.EASE_OUT)
# Scale down Y (squash), Scale up X/Z (stretch)
var squash_scale = _original_scale * Vector3(1.0 + squash_factor, 1.0 - squash_factor, 1.0 + squash_factor)
tween.tween_property(self, "scale", squash_scale, 0.1)
tween.tween_property(self, "scale", _original_scale, 0.4)
class_name EasterCameraPopJuice
extends Camera3D
## Expert camera juice for 'Egg Pops' or collection events.
## Pulses the FOV temporarily to emphasize the impact.
func trigger_pop_kick(strength: float = 5.0) -> void:
var base_fov := fov
var tween := create_tween().set_trans(Tween.TRANS_QUART).set_ease(Tween.EASE_OUT)
tween.tween_property(self, "fov", base_fov + strength, 0.05)
tween.tween_property(self, "fov", base_fov, 0.2)
## Rule: FOV kicks should be subtle (< 10 degrees) to avoid motion sickness.
class_name EasterConfettiCanonVFX
extends GPUParticles3D
## Expert confetti canon for celebratory Easter events.
## Emits multi-colored pastel flakes with gravity and rotation.
func burst() -> void:
amount = 100
one_shot = true
emitting = true
## Tip: Use 'collision_mode' on particles to have confetti land on the ground.
extends Node
## Expert logic for swapping system mouse cursors with themed Easter icons.
func _ready() -> void:
_apply_easter_cursor()
func _apply_easter_cursor() -> void:
# Example implementation from reference
var cursor_img = preload("res://ui/easter/cursor_bunny.png")
if cursor_img:
Input.set_custom_mouse_cursor(cursor_img, Input.CURSOR_ARROW, Vector2(16, 16))
else:
push_warning("Easter cursor image not found.")
class_name EasterEggCollectionTracker
extends Node
## Expert collection registry for hidden event items.
## Tracks total eggs found and emits signals for HUD updates.
signal egg_count_changed(found: int, total: int)
signal all_eggs_found
var total_eggs := 0
var found_eggs := 0
func register_egg() -> void:
total_eggs += 1
egg_count_changed.emit(found_eggs, total_eggs)
func collect_egg() -> void:
found_eggs += 1
egg_count_changed.emit(found_eggs, total_eggs)
if found_eggs >= total_eggs:
all_eggs_found.emit()
## Tip: Use a Global Autoload for this tracker to persist counts across scene changes.
class_name EasterMeshPainterOverride
extends Node
## Expert seasonal material swapper for 3D meshes.
## Replaces standard surface materials with Easter-themed versions.
@export var mesh_instance: MeshInstance3D
@export var easter_material: Material
func apply_easter_material() -> void:
if not mesh_instance or not easter_material: return
# Expert: Use surface override to avoid modifying the Mesh resource itself.
mesh_instance.set_surface_override_material(0, easter_material)
func remove_easter_material() -> void:
if mesh_instance:
mesh_instance.set_surface_override_material(0, null)
## Rule: Always use 'surface_override' for seasonal changes to preserve original assets.
class_name EasterPaletteOverride
extends Node
## Applies an Easter Pastel palette to all child Control nodes.
## Useful for instantly "Spring-ifying" a UI menu.
# The Palette
const COLOR_PINK = Color("FFC1CC")
const COLOR_CYAN = Color("E0FFFF")
const COLOR_YELLOW = Color("FFFFE0")
const COLOR_MINT = Color("98FF98")
@export var target_root: Control
@export var apply_on_ready: bool = true
func _ready() -> void:
if apply_on_ready:
apply_theme()
func apply_theme() -> void:
var root = target_root if target_root else get_parent()
if not root is Control:
return
_apply_to_node_recursive(root)
func _apply_to_node_recursive(node: Node) -> void:
if node is Panel:
_override_stylebox(node, "panel", COLOR_PINK)
elif node is Button:
_override_stylebox(node, "normal", COLOR_CYAN)
_override_stylebox(node, "hover", COLOR_YELLOW)
_override_stylebox(node, "pressed", COLOR_MINT)
elif node is Label:
node.add_theme_color_override("font_color", Color.WHITE)
node.add_theme_color_override("font_outline_color", COLOR_PINK)
node.add_theme_constant_override("outline_size", 4)
for child in node.get_children():
_apply_to_node_recursive(child)
func _override_stylebox(control: Control, theme_item: String, color: Color) -> void:
# We try to get the existing stylebox to preserve borders/radius
# If it's a StyleBoxFlat, we copy it. If not, we make a new one.
var existing = control.get_theme_stylebox(theme_item)
var new_style: StyleBoxFlat
# Crucial: We must duplicate the stylebox to avoid modifying the global theme
if existing is StyleBoxFlat:
new_style = existing.duplicate()
else:
new_style = StyleBoxFlat.new()
# Set some sensible defaults if we're creating from scratch
new_style.set_corner_radius_all(8)
new_style.bg_color = color
control.add_override(theme_item, new_style)
class_name EasterPastelColorPalette
extends Node
## Expert utility for curated Easter aesthetics.
## Provides static Color constants for consistent theming.
static var BLUE := Color("#E0FFFF")
static var PINK := Color("#FFC1CC")
static var YELLOW := Color("#FFFFE0")
static var MINT := Color("#98FF98")
static var PURPLE := Color("#E6E6FA")
## Rule: Stick to these 5 colors for all Easter UI for a cohesive look.
class_name EasterRuntimeUIThemer
extends Node
## Expert runtime theme injector for mass UI customization.
## Iterates through the scene tree and applies pastel aesthetics.
const PASTEL_PINK = Color("#FFC1CC")
const PASTEL_MINT = Color("#98FF98")
func apply_easter_theme(root_node: Node) -> void:
for child in root_node.get_children():
if child is Button:
_theme_button(child)
elif child is Panel:
_theme_panel(child)
# Recursive injection
apply_easter_theme(child)
func _theme_button(btn: Button) -> void:
var style := StyleBoxFlat.new()
style.bg_color = PASTEL_PINK
style.set_corner_radius_all(12)
style.border_width_bottom = 4
style.border_color = Color.WHITE
btn.add_theme_stylebox_override("normal", style)
## Rule: Always 'duplicate()' or create 'new()' StyleBoxes to avoid global leakage.
class_name EasterSeasonalActivationGate
extends Node
## Expert date-aware activation manager.
## Automatically toggles seasonal content based on the system calendar.
@export var easter_content_root: Node
func _ready() -> void:
var date := Time.get_date_dict_from_system()
# Check if month is April (Month 4)
var is_easter_season := (date.month == 4)
if easter_content_root:
easter_content_root.visible = is_easter_season
print("Seasonal: Easter Content ", "ENABLED" if is_easter_season else "DISABLED")
## Rule: Always provide a 'Dev Override' flag to test seasonal content off-season.
extends Node
## Dynamic audio resource loader that replaces standard UI sounds with seasonal variants.
@export var sound_overrides: Dictionary # String -> AudioStream
@onready var sfx_player: AudioStreamPlayer = AudioStreamPlayer.new()
var default_sounds: Dictionary = {}
func _ready() -> void:
add_child(sfx_player)
func play_seasonal_sfx(original_name: String) -> void:
var stream = sound_overrides.get(original_name, default_sounds.get(original_name))
if stream:
sfx_player.stream = stream
sfx_player.play()
else:
push_warning("Sound not found for: " + original_name)
class_name EasterShimmerVFXEmitter
extends CPUParticles2D
## Expert 'Hidden Item' shimmer effect for Easter Eggs.
## Uses additive blending and scale curves for professional sparkles.
func _ready() -> void:
amount = 8
lifetime = 1.5
explosiveness = 0.1
texture = preload("res://addons/godot-master/assets/sparkle.png") # Placeholder
emission_shape = EMISSION_SHAPE_SPHERE
emission_sphere_radius = 20.0
gravity = Vector2(0, -10) # Slow rise
scale_amount_min = 0.1
scale_amount_max = 0.3
# Shimmer pulse
color = Color(1, 1, 0.8, 1) # Warm white
## Tip: Use 'emitted' signals to trigger collection SFX when the player gets close.
class_name EasterSquashStretchJuice
extends Node
## Expert squash and stretch 'juice' for interactive objects (Eggs).
## Uses a single Tween to generate organic physical responses.
@export var target_spatial: Node3D
func apply_impact_juice(intensity: float = 0.2) -> void:
if not target_spatial: return
var tween := create_tween().set_trans(Tween.TRANS_ELASTIC).set_ease(Tween.EASE_OUT)
# Squash: Flatten Y, Widen X/Z
tween.tween_property(target_spatial, "scale", Vector3(1.0 + intensity, 1.0 - intensity, 1.0 + intensity), 0.1)
# Snap back to normal
tween.tween_property(target_spatial, "scale", Vector3.ONE, 0.4)
## Tip: Trigger this on '_on_body_entered' or mouse click for maximum feedback.
class_name EasterWobblePhysicsBody
extends RigidBody3D
## Expert wobbly physics for 'Egg-like' interaction.
## Applies a random offset to the center of mass to create organic instability.
func _ready() -> void:
# Shift center of mass slightly to cause a wobble when it rolls
center_of_mass_mode = RigidBody3D.CENTER_OF_MASS_MODE_CUSTOM
center_of_mass = Vector3(randf_range(-0.1, 0.1), -0.2, randf_range(-0.1, 0.1))
## Tip: Low friction + Custom Center of Mass = High quality organic egg motion.
class_name SeasonalMaterialSwapper
extends Node
## A utility to swap materials based on the "Season".
## Needs to be attached to a MeshInstance3D or have one assigned.
enum Season { DEFAULT, EASTER }
@export var target_mesh: MeshInstance3D
@export var default_material: Material
@export var easter_material: Material
# Could be a global singleton or local export
@export var current_season: Season = Season.DEFAULT
func _ready() -> void:
if not target_mesh:
target_mesh = get_parent() as MeshInstance3D
apply_season()
func apply_season() -> void:
if not target_mesh:
return
var mat_to_use = default_material
match current_season:
Season.EASTER:
if easter_material:
mat_to_use = easter_material
# Override surface 0 (usually the main material)
target_mesh.set_surface_override_material(0, mat_to_use)
func set_season(new_season: Season) -> void:
current_season = new_season
apply_season()