This skill should be used when the user asks to "create a game", "make a game", "game development", "dragonruby", "drgtk", "game loop", "tick method", "sprite rendering", "game state", or mentions args.outputs, args.state, args.inputs, coordinate system, collision detection, animation frames, or scene management. Should also be used when editing DragonRuby game files, working on 2D game logic, or discussing game performance optimization.
Creates 2D games using DragonRuby Game Toolkit with game loop, sprite rendering, and collision detection.
/plugin marketplace add hoblin/claude-ruby-marketplace/plugin install dragonruby@claude-ruby-marketplaceThis skill inherits all available tools. When active, it can use any tool Claude has access to.
examples/audio/audio_events.rbexamples/audio/background_music.rbexamples/audio/crossfade.rbexamples/audio/music_controls.rbexamples/audio/sound_effects.rbexamples/core/coordinate_system.rbexamples/core/hello_world.rbexamples/core/labels.rbexamples/core/sprites.rbexamples/core/state_management.rbexamples/distribution/background_pause.rbexamples/distribution/build_workflow.shexamples/distribution/cvars_production.txtexamples/distribution/game_metadata_hd.txtexamples/distribution/game_metadata_minimal.txtexamples/distribution/game_metadata_mobile.txtexamples/distribution/platform_detection.rbexamples/distribution/steam_metadata.txtexamples/entities/collision_detection.rbexamples/entities/entity_lifecycle.rbThis skill provides comprehensive guidance for building 2D games with DragonRuby Game Toolkit (DRGTK). Use for game loop implementation, sprite rendering, input handling, collision detection, animation, and scene management.
def boot args
args.state = {}
end
def tick args
# Called 60 times per second
args.state.player ||= { x: 640, y: 360, w: 50, h: 50, path: 'player.png' }
# Handle input
args.state.player.x += 5 if args.inputs.right
args.state.player.x -= 5 if args.inputs.left
# Render
args.outputs.sprites << args.state.player
end
| Concept | Purpose |
|---|---|
def tick(args) | Main game loop (60 FPS) |
args.outputs | Render sprites, labels, primitives |
args.state | Persistent game data storage |
args.inputs | Keyboard, mouse, controller input |
args.grid | Screen dimensions (1280x720) |
Geometry | Collision detection helpers |
(0, 720) ─────────────── (1280, 720)
│ │
│ 1280 × 720 │
│ │
(0, 0) ─────────────── (1280, 0)
Use args.outputs.primitives for FIFO (first-in, first-out) render order control.
args.outputs.primitives << {
x: 100, y: 100, w: 64, h: 64,
path: 'sprites/player.png',
angle: 45,
anchor_x: 0.5, anchor_y: 0.5,
r: 255, g: 255, b: 255, a: 255,
flip_horizontally: false
}
args.outputs.primitives << {
x: 640, y: 360,
text: "Score: #{args.state.score}",
size_px: 22,
anchor_x: 0.5, anchor_y: 0.5,
r: 255, g: 255, b: 255
}
# Filled rectangle (use primitive_marker: :solid)
args.outputs.primitives << {
x: 0, y: 0, w: 100, h: 100,
r: 255, g: 0, b: 0,
primitive_marker: :solid
}
# For many rectangles, use path: :solid for better performance
args.outputs.primitives << { x: 0, y: 0, w: 100, h: 100, path: :solid, r: 255, g: 0, b: 0 }
# Outline rectangle
args.outputs.primitives << { x: 0, y: 0, w: 100, h: 100, r: 0, g: 0, b: 0, primitive_marker: :border }
Use args.state with ||= for lazy initialization:
def tick args
args.state.player ||= { x: 640, y: 360 }
args.state.enemies ||= []
args.state.score ||= 0
args.state.scene ||= :title
end
# Directional (arrows, WASD, gamepad)
args.inputs.up / down / left / right
# Magnitude values
args.inputs.left_right # -1, 0, or 1
args.inputs.up_down # -1, 0, or 1
args.inputs.keyboard.key_down.space # Pressed this frame
args.inputs.keyboard.key_held.space # Held down
args.inputs.keyboard.key_up.space # Released this frame
args.inputs.mouse.click # Any button clicked
args.inputs.mouse.x / .y # Position
args.inputs.mouse.inside_rect?(rect) # Collision check
if Geometry.intersect_rect?(player, enemy)
enemy.dead = true
args.state.score += 1
end
# Clean up dead entities
args.state.enemies.reject! { |e| e.dead }
# Frame-based animation
sprite_index = 0.frame_index(count: 6, hold_for: 8, repeat: true)
args.state.player.path = "sprites/player-#{sprite_index}.png"
def tick args
args.state.scene ||= :title
send("#{args.state.scene}_tick", args)
end
def title_tick args
args.outputs.labels << { x: 640, y: 400, text: "Press SPACE", anchor_x: 0.5 }
args.state.scene = :gameplay if args.inputs.keyboard.key_down.space
end
def gameplay_tick args
# Game logic here
end
||= for state initialization$gtk.reset during development to reset stateargs.outputs.primitives for FIFO render order controlprimitive_marker: :solid or :border for rectangle typesFPS = 60)For detailed API documentation and patterns:
references/core.md - Game loop, args object, rendering, coordinatesreferences/input.md - Keyboard, mouse, controller input patternsreferences/entities.md - Entity spawning, collision, lifecyclereferences/game-logic/state.md - Timers, scoring, scene transitionsreferences/game-logic/persistence.md - Save/load, file I/O patternsreferences/audio.md - Sound effects, music playback, audio controlsreferences/rendering/primitives.md - Sprites, labels, solids, borders, layeringreferences/rendering/animation.md - frame_index, spritesheets, easing functionsWorking code in examples/:
examples/core/ - Hello world, sprites, labels, state, coordinatesexamples/input/ - Directional, keyboard, mouse, movementexamples/entities/ - Storage, factories, collision, lifecycleexamples/game-logic/ - Timers, scoring, save/load, state transitionsexamples/audio/ - Sound effects, background music, pause/resumeexamples/rendering/ - Sprites, labels, animation, layeringdef tick args
# Game logic
end
$gtk.reset # Add at end during development
$gtk.reset # Immediate reset
$gtk.reset_next_tick # Reset before next tick (safer)
args.outputs.debug << "Frame: #{Kernel.tick_count}"
args.outputs.debug.watch args.state.player
Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.