Coding
PromptBeginner5 minmarkdown
Markdown Converter
Agent skill for markdown-converter
21
- Scope: this repo is the DragonRuby Game Toolkit drop (engine + docs + samples). The only game code you own lives under `mygame/`; everything else is reference material.
Sign in to like and favorite skills
mygame/; everything else is reference material.mygame/app/main.rb defines a single tick args function that the engine calls 60 fps. Keep all frame work inside tick; avoid extra threads or timers.args.state for per-frame or persistent game data (Ruby object with lazy init via ||=). Do not create globals.args.outputs each frame; common lists are labels, sprites, and shapes. Either hash keys ({ x:, y:, w:, h:, path:, angle: }) or ordered arrays ([x, y, w, h, path, angle]) are accepted; see mygame/app/main.rb for the hash style.args.inputs.keyboard, args.inputs.mouse, and controller helpers; patterns are in mygame/app/main.rb and docs/guides/getting-started.md.dragonruby.exe is running to see live reloads. No explicit build step../dragonruby.exe (or double-click). To explore samples, pass the sample folder: ./dragonruby.exe samples/01_rendering_basics.mygame/sprites, mygame/sounds, mygame/fonts, mygame/data; reference by filename in outputs (lazy-loaded on first use).docs/api/*.md; tutorials in docs/guides/; sample patterns in samples/ (ordered by difficulty). Mirror is at docs.dragonruby.org.||=), use args.state.tick_count/Kernel.tick_count for time, and favor simple data structs over classes.docs/guides/getting-started.md and samples for pacing).samples/12_c_extensions/* for the expected directory layout and build scripts if adding native code.dragonruby-publish.exe handles packaging; if you touch build/publish flows, prefer reusing that tool instead of custom scripts.dragonruby*.exe) or docs unless intentionally updating upstream content.mygame/ or new sample-style content; keep sample code minimal and readable for teaching purposes../dragonruby mygame --test app/tests.rb --no-tick runs tests headlessly.mygame/app/tests.rb or any .rb file passed to --test.test_ that accept args and assert parameters:
def test_example args, assert # setup game = MyGame.new game.args = args game.tick # assertions assert.true! condition, "failure message" assert.false! condition, "failure message" assert.equal! expected, actual, "optional message" assert.not_equal! expected, actual assert.ok! # mark test passed without specific assertion end
assert.true!, assert.false!, assert.equal!, assert.not_equal!, assert.ok!.$gtk.reset 100 then $gtk.tests.start at end of test file.GTK.benchmark to compare code performance:
GTK.benchmark iterations: 1000, label_one: -> { code_block_1 }, label_two: -> { code_block_2 } # OR by time GTK.benchmark seconds: 5, label_one: -> { code_block_1 }, label_two: -> { code_block_2 }
$game = nil) at start of each test to avoid cross-test contamination.This project uses the State pattern from https://gameprogrammingpatterns.com/state.html for player behavior. Key concepts:
PlayerState in mygame/app/lib/player_state.rb defines the interface with enter, exit, handle_input(mouse), and update methods.IdlePlayerState, ChargingPlayerState, BurstingPlayerState each encapsulate their own behavior and data.nil to stay). The owner calls change_state(new_state) which invokes exit on old state and enter on new state.charge_timer in ChargingPlayerState, burst_cooldown in BurstingPlayerState).Player entity delegates handle_input and update_state to its current state, keeping the entity class simple.Example state transition flow:
# In state class - return new state or nil def handle_input(mouse) return nil if mouse.key_held.left # stay in this state IdlePlayerState.new(player) # transition to idle end # In entity class - handle the transition def change_state(new_state) @state.exit @state = new_state @state.enter end
Benefits:
is_charging && !is_bursting && ...)