### Boot Function Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/api/runtime.md
This function is called once when the game boots. It's useful for initial setup and logging startup information.
```ruby
def boot args
puts "The current tick count is: #{Kernel.tick_count}"
puts "The global tick count is: #{Kernel.global_tick_count}"
end
```
--------------------------------
### In-Game Web Server HTTP GET Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.html
This snippet demonstrates how to set up and handle HTTP GET requests within an in-game web server. It shows how to start the server, define routes, and respond to requests. The web server is disabled by default in production builds and requires specific configuration to enable.
```ruby
def tick args
args.state.reqnum ||= 0
# by default the embedded webserver is disabled in a production build
# to enable the http server in a production build you need to:
# - update metadata/cvars.txt
# - manually start the server up with enable_in_prod set to true:
GTK.start_server! port: 3000, enable_in_prod: true
args.outputs.background_color = [0, 0, 0]
args.outputs.labels << { x: 640,
y: 360,
text: "Point your web browser at http://localhost:#{args.state.port}/",
size_px: 30,
anchor_x: 0.5,
anchor_y: 0.5 }
args.outputs.labels << { x: 640,
y: 360,
text: "See metadata/cvars.txt for webserer configuration requirements.",
size_px: 30,
anchor_x: 0.5,
anchor_y: 1.5 }
if Kernel.tick_count == 1
GTK.openurl "http://localhost:3000"
end
args.inputs.http_requests.each { |req|
puts("METHOD: #{req.method}");
puts("URI: #{req.uri}");
puts("HEADERS:");
req.headers.each { |k,v| puts(" #{k}: #{v}") }
if (req.uri == '/')
# headers and body can be nil if you don't care about them.
# If you don't set the Content-Type, it will default to
# "text/html; charset=utf-8".
# Don't set Content-Length; we'll ignore it and calculate it for you
args.state.reqnum += 1
req.respond 200, "
helloThis #{req.method} was request number #{args.state.reqnum}!
\n", { 'X-DRGTK-header' => 'Powered by DragonRuby!' }
else
req.reject
end
}
end
```
--------------------------------
### HTTP GET Request Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.html
Demonstrates how to perform an HTTP GET request.
```Ruby
require 'net/http'
require 'uri'
uri = URI.parse("http://example.com")
response = Net::HTTP.get_response(uri)
puts response.body
```
--------------------------------
### In-Game Web Server HTTP GET Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.txt
This snippet demonstrates how to set up an in-game web server that handles HTTP GET requests. It shows how to enable the server, respond to requests with custom HTML content, and set headers. Ensure the server is enabled in production builds by updating metadata/cvars.txt and setting enable_in_prod to true.
```ruby
def tick args
args.state.reqnum ||= 0
# by default the embedded webserver is disabled in a production build
# to enable the http server in a production build you need to:
# - update metadata/cvars.txt
# - manually start the server up with enable_in_prod set to true:
GTK.start_server! port: 3000, enable_in_prod: true
args.outputs.background_color = [0, 0, 0]
args.outputs.labels << { x: 640,
y: 360,
text: "Point your web browser at http://localhost:#{args.state.port}/",
size_px: 30,
anchor_x: 0.5,
anchor_y: 0.5 }
args.outputs.labels << { x: 640,
y: 360,
text: "See metadata/cvars.txt for webserer configuration requirements.",
size_px: 30,
anchor_x: 0.5,
anchor_y: 1.5 }
if Kernel.tick_count == 1
GTK.openurl "http://localhost:3000"
end
args.inputs.http_requests.each { |req|
puts("METHOD: #{req.method}");
puts("URI: #{req.uri}");
puts("HEADERS:");
req.headers.each { |k,v| puts(" #{k}: #{v}") }
if (req.uri == '/')
# headers and body can be nil if you don't care about them.
# If you don't set the Content-Type, it will default to
# "text/html; charset=utf-8".
# Don't set Content-Length; we'll ignore it and calculate it for you
args.state.reqnum += 1
req.respond 200, "helloThis #{req.method} was request number #{args.state.reqnum}!
\n", { 'X-DRGTK-header' => 'Powered by DragonRuby!' }
else
req.reject
end
}
end
```
--------------------------------
### Starting iOS Environment
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/samples/01_rendering_basics/01_labels/logs/console_history.txt
Starts the iOS environment with specified settings.
```ruby
$wizards.ios.start env: :dev
```
```ruby
$wizards.ios.start env: :hotload
```
--------------------------------
### Start VR Server for Cube Drawing
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.html
Initializes the game loop and starts a server for VR applications. This is the entry point for the VR cube drawing example.
```ruby
# ./samples/14_vr/05_draw_a_cube_with_triangles/app/main.rb
require 'app/tick.rb'
def tick args
args.gtk.start_server! port: 9001, enable_in_prod: true
tick_game args
end
```
--------------------------------
### Ruby Looping Introduction
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/index.txt
A basic example showing the start of a Ruby primer on looping constructs.
```ruby
# ./samples/00_learn_ruby_optional/00_intermediate_ruby_primer/app/06_looping.txt
# ====================================================================================
# Looping
# ====================================================================================
#
# Looping looks a whole lot different than other languages.
# But it's pretty awesome when you get used to it.
repl do
puts "* RUBY PRIMER: Loops"
end
```
--------------------------------
### Topdown Starting Point - main.rb
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.html
Example main file for a topdown RPG genre sample. It includes comments on API usage like 'reverse' and 'intersect_rect?', and details for 'args.outputs.labels'.
```ruby
# ./samples/99_genre_rpg_topdown/topdown_starting_point/app/main.rb
=begin
APIs listing that haven't been encountered in previous sample apps:
- reverse: Returns a new string with the characters from original string in reverse order.
For example, the command "dragonruby".reverse would return the string "yburnogard".
Reverse is not only limited to strings, but can be applied to arrays and other collections.
Reminders:
- HASH#intersect_rect?: Returns true or false depending on if two rectangles intersect.
- args.outputs.labels: Added a hash to this collection will generate a label.
The parameters are:
{
x: X,
y: y,
text: TEXT,
size_px: 22 (optional),
anchor_x: 0 (optional),
anchor_y: 0 (optional),
r: RED (optional),
g: GREEN (optional),
```
--------------------------------
### Starting Gameplay Replay from Command Line
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/index.txt
Demonstrates how to initiate a gameplay replay directly from the command line.
```bash
dragonruby replay path/to/replay/recording. பதிவு
```
--------------------------------
### Initialize Game and Start Server (Let There Be Light)
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.html
Initializes the game and starts a server for the Let There Be Light sample. This is the entry point for the application.
```ruby
# ./samples/14_vr/04_let_there_be_light/app/main.rb
require 'app/tick.rb'
def tick args
GTK.start_server! port: 9001, enable_in_prod: true
tick_game args
end
```
--------------------------------
### Get Game Start Timestamp in DragonRuby
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.txt
Returns the timestamp when the player started or retried the game. It prioritizes the retry timestamp over the initial start timestamp.
```ruby
def started_at
state.events.game_retried_at || state.events.game_started_at
end
```
--------------------------------
### New Main Module Capabilities Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/changelog.txt
Demonstrates the new capabilities of the Main module, allowing direct access to arguments, inputs, outputs, state, events, and audio without passing them explicitly. Includes the 'boot' function which runs once at game startup.
```ruby
module Main
def boot
# invoked once when the game boots
puts "boot: #{Kernel.tick_count}"
end
```
--------------------------------
### Start SSH Service on Steam Deck
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/guides/deploying-to-steam.md
This command starts the SSH service immediately. This is a one-time setup step.
```bash
sudo systemctl start sshd
```
--------------------------------
### Start Server for VR Cube Sample
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.html
Initializes the game loop and starts a server for the VR cube sample. This is the main entry point for the application.
```ruby
# ./samples/14_vr/05_draw_a_cube/app/main.rb
require 'app/tick.rb'
def tick args
args.gtk.start_server! port: 9001, enable_in_prod: true
tick_game args
end
```
--------------------------------
### Get Game Start Time
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.txt
Returns the timestamp when the game was started or retried. Used for timing animations and game state.
```ruby
def started_at
state.events.game_retried_at || state.events.game_started_at
end
```
--------------------------------
### Start In-Game Web Server and Handle HTTP GET Requests
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.txt
This snippet demonstrates how to start an embedded web server in DragonRuby and handle incoming HTTP GET requests. It configures the server to run on a specified port and respond to requests for the root path ('/').
```ruby
def tick args
args.state.port ||= 3000
args.state.reqnum ||= 0
# by default the embedded webserver runs on port 9001 (the port number is over 9000) and is disabled in a production build
# to enable the http server in a production build, you need to manually start
# the server up:
args.gtk.start_server! port: args.state.port, enable_in_prod: true
args.outputs.background_color = [0, 0, 0]
args.outputs.labels << [640, 600, "Point your web browser at http://localhost:#{args.state.port}/", 10, 1, 255, 255, 255]
if args.state.tick_count == 1
$gtk.openurl "http://localhost:3000"
end
args.inputs.http_requests.each { |req|
puts("METHOD: #{req.method}");
puts("URI: #{req.uri}");
puts("HEADERS:");
req.headers.each { |k,v| puts(" #{k}: #{v}") }
if (req.uri == '/')
# headers and body can be nil if you don't care about them.
# If you don't set the Content-Type, it will default to
# "text/html; charset=utf-8".
# Don't set Content-Length; we'll ignore it and calculate it for you
args.state.reqnum += 1
req.respond 200, "helloThis #{req.method} was request number #{args.state.reqnum}!
\n", { 'X-DRGTK-header' => 'Powered by DragonRuby!' }
else
req.reject
end
}
end
```
--------------------------------
### Play Sound Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.html
Demonstrates how to play a sound file using `args.outputs.sounds`. Ensure the sound file path is correct.
```ruby
args.outputs.sounds << "path_to_wav.wav"
```
--------------------------------
### Game Initialization and Rendering Setup
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.html
Sets up the game's default state and initializes the rendering pipeline, including scene dimensions and background color.
```ruby
class Game
attr_gtk
def request_action name, at: nil
at ||= state.tick_count
state.player.requested_action = name
state.player.requested_action_at = at
end
def defaults
state.player.x ||= 64
state.player.y ||= 0
state.player.dx ||= 0
state.player.dy ||= 0
state.player.action ||= :standing
state.player.action_at ||= 0
state.player.next_action_queue ||= {}
state.player.facing ||= 1
state.player.jump_at ||= 0
state.player.jump_count ||= 0
state.player.max_speed ||= 1.0
state.sabre.x ||= state.player.x
state.sabre.y ||= state.player.y
state.actions_lookup ||= new_actions_lookup
end
def render
outputs.background_color = [32, 32, 32]
outputs[:scene].transient!
outputs[:scene].w = 128
outputs[:scene].h = 128
outputs[:scene].borders << { x: 0, y: 0, w: 128, h: 128, r: 255, g: 255, b: 255 }
render_player
render_sabre
args.outputs.sprites << { x: 320, y: 0, w: 640, h: 640, path: :scene }
args.outputs.labels << { x: 10, y: 100, text: "Controls:", r: 255, g: 255, b: 255, size_enum: -1 }
args.outputs.labels << { x: 10, y: 80, text: "Move: left/right", r: 255, g: 255, b: 255, size_enum: -1 }
args.outputs.labels << { x: 10, y: 60, text: "Jump: space | up | right click", r: 255, g: 255, b: 255, size_enum: -1 }
args.outputs.labels << { x: 10, y: 40, text: "Attack: f | j | left click", r: 255, g: 255, b: 255, size_enum: -1 }
end
def render_sabre
return if !state.sabre.is_active
sabre_index = 0.frame_index count: 4,
hold_for: 2,
repeat: true
offset = 0
offset = -8 if state.player.facing == -1
outputs[:scene].sprites << { x: state.sabre.x + offset,
y: state.sabre.y, w: 16, h: 16, path: "sprites/sabre-throw/#{sabre_index}.png" }
end
def new_actions_lookup
r = {
slash_0: {
frame_count: 6,
interrupt_count: 4,
path: "sprites/kenobi/slash-0/:index.png"
},
slash_1: {
frame_count: 6,
interrupt_count: 4,
path: "sprites/kenobi/slash-1/:index.png"
},
throw_0: {
frame_count: 8,
throw_frame: 2,
catch_frame: 6,
path: "sprites/kenobi/slash-2/:index.png"
},
throw_1: {
frame_count: 9,
throw_frame: 2,
catch_frame: 7,
path: "sprites/kenobi/slash-3/:index.png"
},
throw_2: {
frame_count: 9,
throw_frame: 2,
catch_frame: 7,
path: "sprites/kenobi/slash-4/:index.png"
},
slash_5: {
frame_count: 11,
path: "sprites/kenobi/slash-5/:index.png"
},
slash_6: {
frame_count: 8,
interrupt_count: 6,
path: "sprites/kenobi/slash-6/:index.png"
}
}
r.each.with_index do |(k, v), i|
v.name ||= k
v.index ||= i
v.hold_for ||= 5
v.duration ||= v.frame_count * v.hold_for
v.last_index ||= v.frame_count - 1
v.interrupt_count ||= v.frame_count
v.interrupt_duration ||= v.interrupt_count * v.hold_for
v.repeat ||= false
v.next_action ||= r[r.keys[i + 1]]
end
r
end
def render_player
```
--------------------------------
### Get Start of Tongue Position
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.txt
Calculates and returns the starting position of the player's tongue, which is at the center of the player character. This is a utility function for tongue-related mechanics.
```Ruby
def start_of_tongue
{
x: player.x + player.w / 2,
y: player.y + player.h / 2
}
end
```
--------------------------------
### Start Game Server
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.html
This snippet shows how to start a game server using `args.gtk.start_server!`. It's typically used in the main game loop to enable network features.
```ruby
def tick args
args.gtk.start_server! port: 9001, enable_in_prod: true
tick_game args
end
```
--------------------------------
### 3D Rendering Setup and Input Handling
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.txt
Initializes the game state, sets up camera controls using keyboard input (W, A, S, D for movement, Q, E, U, O for rotation, I, K for elevation), and defines initial camera parameters.
```ruby
include MatrixFunctions
def tick args
args.outputs.labels << { x: 0,
y: 30.from_top,
text: "W,A,S,D to move. Q,E,U,O to turn, I,K for elevation.",
alignment_enum: 1 }
args.grid.origin_center!
args.state.cam_x ||= 0.00
if args.inputs.keyboard.left
args.state.cam_x += 0.01
elsif args.inputs.keyboard.right
args.state.cam_x -= 0.01
end
args.state.cam_y ||= 0.00
if args.inputs.keyboard.i
args.state.cam_y += 0.01
elsif args.inputs.keyboard.k
args.state.cam_y -= 0.01
end
args.state.cam_z ||= 6.5
if args.inputs.keyboard.s
args.state.cam_z += 0.1
elsif args.inputs.keyboard.w
args.state.cam_z -= 0.1
end
args.state.cam_angle_y ||= 0
if args.inputs.keyboard.q
args.state.cam_angle_y += 0.25
elsif args.inputs.keyboard.e
args.state.cam_angle_y -= 0.25
end
args.state.cam_angle_x ||= 0
if args.inputs.keyboard.u
args.state.cam_angle_x += 0.1
elsif args.inputs.keyboard.o
args.state.cam_angle_x -= 0.1
end
```
--------------------------------
### Package and Deploy Android Application
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/samples/12_c_extensions/08_handcrafted_android_extension/readme.txt
Automates the creation of a Google Play package (`.aab`), converts it to an APK, and installs it on a connected Android device. Includes steps for cleaning previous installations and starting the application.
```bash
# assuming the following contents of game_metadata.txt
# devid=developer
# devtitle=Developer Name
# gameid=mygame
# gametitle=My Game
# version=1.0
# icon=metadata/icon.png
# packageid=com.developer.mygame
./dragonruby-publish --package --platforms=googleplay
java -jar ./.android/bundletool.jar build-apks --bundle=./builds/mygame-googleplay.aab --output=./builds/app.apks --mode=universal
mv ./builds/app.apks ./builds/app.zip
rm -rf ./builds/tmp
mkdir ./builds/tmp
unzip ./builds/app.zip -d ./builds/tmp
cp ./builds/tmp/universal.apk ./builds/tmp/universal.zip
./.android/platform-tools/adb shell am force-stop com.dev.mygame
./.android/platform-tools/adb uninstall com.dev.mygame
./.android/platform-tools/adb install ./builds/tmp/universal.apk
./.android/platform-tools/adb shell am start -n com.dev.mygame/com.dev.mygame.DragonRubyActivity
```
--------------------------------
### In-Game Web Server HTTP GET Request Handling
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.html
This snippet sets up an in-game web server to handle HTTP GET requests. It demonstrates how to start the server, respond to requests with custom HTML, and log request details.
```Ruby
# ./samples/11_http/02_in_game_web_server_http_get/app/main.rb
def tick args
args.state.port ||= 3000
args.state.reqnum ||= 0
# by default the embedded webserver runs on port 9001 (the port number is over 9000) and is disabled in a production build
# to enable the http server in a production build, you need to manually start
# the server up:
args.gtk.start_server! port: args.state.port, enable_in_prod: true
args.outputs.background_color = [0, 0, 0]
args.outputs.labels << [640, 600, "Point your web browser at http://localhost:#{args.state.port}/", 10, 1, 255, 255, 255]
if args.state.tick_count == 1
$gtk.openurl "http://localhost:3000"
end
args.inputs.http_requests.each { |req|
puts("METHOD: #{req.method}");
puts("URI: #{req.uri}");
puts("HEADERS:");
req.headers.each { |k,v| puts(" #{k}: #{v}") }
if (req.uri == '/')
# headers and body can be nil if you don't care about them.
# If you don't set the Content-Type, it will default to
# "text/html; charset=utf-8".
# Don't set Content-Length; we'll ignore it and calculate it for you
args.state.reqnum += 1
req.respond 200, "helloThis #{req.method} was request number #{args.state.reqnum}!
\n", { 'X-DRGTK-header' => 'Powered by DragonRuby!' }
else
req.reject
end
}
end
```
--------------------------------
### List Files Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.txt
Provides examples for listing files in the root directory and within the 'app' subdirectory. The output includes the number of ticks.
```ruby
root_files = args.gtk.list_files("")
app_files = args.gtk.list_files("app")
```
--------------------------------
### Display Tutorial Introduction
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/index.txt
Queues a welcome message for the DragonRuby GTK primer, instructing the user to type and execute a 'puts' command.
```ruby
def tick_intro
queue_message "Welcome to the DragonRuby GTK primer! Try typing the
code below and press ENTER:
puts \"Hello DragonRuby!\"
"
end
```
--------------------------------
### Start Server and Game Loop
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/index.txt
Initializes the game server and the main game loop. This is a common setup for DragonRuby applications.
```ruby
require 'app/tick.rb'
def tick args
args.gtk.start_server! port: 9001, enable_in_prod: true
$game ||= Game.new
$game.args = args
$game.tick
end
```
--------------------------------
### Start iOS Deployment Wizard
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/guides/deploying-to-mobile.md
Initiates the iOS deployment process. Use different environments for development, hotloading, simulator, or production builds.
```bash
$wizards.ios.start env: :dev
```
```bash
$wizards.ios.start env: :hotload
```
```bash
$wizards.ios.start env: :sim
```
```bash
$wizards.ios.start env: :prod
```
--------------------------------
### Get Death Timestamp in DragonRuby
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.txt
Returns the timestamp when the player died, or nil if the player has not died or the death event is before the game started.
```ruby
def death_at
return nil if !@game.death_at
return nil if @game.death_at < started_at
@game.death_at
end
```
--------------------------------
### Introductory Message for Tutorial
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/index.txt
Displays a welcome message to the user and prompts them to enter their first command. This is part of the initial tutorial sequence.
```ruby
def tick_intro
queue_message "Welcome to the DragonRuby GTK primer! Try typing the
code below and press ENTER:
puts \"Hello DragonRuby!\"
"
end
```
--------------------------------
### Enable SSH Service on Steam Deck
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/guides/deploying-to-steam.md
This command enables the SSH service to start automatically on boot. This is a one-time setup step.
```bash
sudo systemctl enable sshd
```
--------------------------------
### Play Background Music (.ogg)
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/docs.txt
Plays background music that ends with '.ogg'. This sound will loop. The example starts the music loop at the beginning of the game.
```ruby
def tick args
# Start a sound loop at the beginning of the game
if Kernel.tick_count == 0
args.outputs.sounds << 'background_music.ogg'
end
end
```
--------------------------------
### Initialize Tutorial Outputs
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.txt
Initializes the tutorial outputs object and sets up initial drawing elements like solids and borders.
```ruby
$tutorial_outputs ||= TutorialOutputs.new
$gtk.log_level = :off
defaults
console.show
$tutorial_outputs.clear
$tutorial_outputs.solids << [900, 37, 480, 700, 0, 0, 0, 255]
$tutorial_outputs.borders << [900, 37, 380, 683, 255, 255, 255]
tick_evals
$tutorial_outputs.tick
tick_intro
tick_hello_dragonruby
tick_reset_button
tick_explain_solid
tick_explain_solid_blue
tick_reprint_on_error
tick_explain_tick_count
tick_explain_mod
tick_explain_string_interpolation
end
```
--------------------------------
### Get Player Death Time
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.txt
Returns the time the player died, used for animation calculations. Returns nil if the death event has not occurred or is before the game started.
```ruby
def death_at
return nil if !@game.death_at
return nil if @game.death_at < started_at
@game.death_at
end
```
--------------------------------
### Initialize Game on Boot
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.txt
Sets up the global game instance when the game boots. This is the entry point for initializing the game's main object.
```ruby
def boot args
# initialize the game on boot
$game = Game.new
end
```
--------------------------------
### Starting Gameplay Replay with start_replay
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/index.txt
Initiates a replay of a previously recorded gameplay session using the provided file path.
```ruby
args.gtk.start_replay "path/to/replay/recording. பதிவு"
```
--------------------------------
### Get Valid Neighbors for Pathfinding
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.html
Retrieves all valid neighboring cells for a given cell, ordered clockwise starting from the southern neighbor. This method is used in pathfinding algorithms.
```ruby
# Gets all the valid neighbors into the array
# From southern neighbor, clockwise
neighbors << [cell.x, cell.y - 1] unless cell.y == 0
neighbors << [cell.x - 1, cell.y] unless cell.x == 0
neighbors << [cell.x, cell.y + 1] unless cell.y == grid.height - 1
neighbors << [cell.x + 1, cell.y] unless cell.x == grid.width - 1
# Sorts the neighbors so the rendered path is a zigzag path
# Cells in a diagonal direction are given priority
# Comment this line to see the difference
neighbors = neighbors.sort_by { |neighbor_x, neighbor_y| proximity_to_star(neighbor_x, neighbor_y) }
neighbors
```
--------------------------------
### Start iOS Development Environment
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/changelog.txt
Starts the iOS development environment for the simulator. Requires provisioning profiles for device deployment.
```ruby
$wizards.ios.start env: :dev
```
```ruby
$wizards.ios.start env: :sim
```
```ruby
$wizards.ios.help
```
--------------------------------
### Initialize Tutorial Outputs and Game State
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/index.txt
This code initializes the tutorial outputs and sets default game state. It's part of the main game loop setup.
```ruby
$tutorial_outputs ||= TutorialOutputs.new
def tick args
$gtk.log_level = :off
defaults
console.show
$tutorial_outputs.clear
$tutorial_outputs.solids << [900, 37, 480, 700, 0, 0, 0, 255]
$tutorial_outputs.borders << [900, 37, 380, 683, 255, 255, 255]
tick_evals
$tutorial_outputs.tick
tick_intro
tick_hello_dragonruby
tick_reset_button
tick_explain_solid
tick_explain_solid_blue
tick_reprint_on_error
tick_explain_tick_count
tick_explain_mod
tick_explain_string_interpolation
end
```
--------------------------------
### Main Module Entry Point Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/changelog.txt
An example of using the `Main` module for the `tick` entry point, as recommended for better control and scoping.
```ruby
module Main
def tick args
end
end
```
--------------------------------
### Box Collision Example Setup
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/index.txt
This snippet is from the box collision sample and lists several DragonRuby APIs that might be encountered. It includes explanations for 'first', 'idiv', and reminders about 'find_all', 'intersect_rect?', and 'reject'.
```ruby
=begin
APIs listing that haven't been encountered in previous sample apps:
- first: Returns the first element of the array.
For example, if we have an array
numbers = [1, 2, 3, 4, 5]
and we call first by saying
numbers.first
the number 1 will be returned because it is the first element of the numbers array.
- num1.idiv(num2): Divides two numbers and returns an integer.
For example,
16.idiv(3) = 5, because 16 / 3 is 5.33333 returned as an integer.
16.idiv(4) = 4, because 16 / 4 is 4 and already has no decimal.
Reminders:
- find_all: Finds all values that satisfy specific requirements.
- ARRAY#intersect_rect?: An array with at least four values is
considered a rect. The intersect_rect? function returns true
or false depending on if the two rectangles intersect.
- reject: Removes elements from a collection if they meet certain requirements.
=end
```
--------------------------------
### Recording Game on Startup
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/deploy_template/CHANGELOG.txt
This command-line argument initiates game recording automatically when the game starts and saves it upon closing.
```sh
./dragonruby(.exe) --record
```
--------------------------------
### Game Loop Hooks in Ruby
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/changelog.txt
Defines the core game loop functions: start, tick, reset, did_reset, and shutdown. The 'tick' function is invoked at 60Hz and includes examples for checking input, updating state, and setting the background color.
```ruby
def start
# invoked on Kernel.tick_count == 0 before tick is invoked
puts "start: #{Kernel.tick_count}"
state.some_variable = 0
end
def tick
# invoked at 60hz
if Kernel.tick_count.zmod?(30)
# state top level function
state.some_variable += 1
puts "state.some_variable: #{state.some_variable}"
end
if Kernel.tick_count.zmod?(60)
puts "tick: #{Kernel.tick_count}"
end
# inputs top level function
if inputs.keyboard.key_down.enter
puts "inputs.keyboard.key_down.enter #{Kernel.tick_count}"
end
# outputs top level function
outputs.background_color = [30, 30, 30]
end
def reset
# invoked before reset occurs
puts "reset #{Kernel.tick_count}"
end
def did_reset
# invoked after reset occurs
puts "did_reset #{Kernel.tick_count}"
end
def shutdown
# invoked once before game exits
puts "shutdown #{Kernel.tick_count}"
end
end
DR.reset
```
--------------------------------
### start_replay
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/docs.html
Runs a recorded gameplay session against the current codebase.
```APIDOC
## `start_replay`
### Description
Given a file that represents a recording, this method will run the recording against the current codebase.
### Method Signature
`GTK.start_replay(recording_file)`
### Parameters
* `recording_file` (string) - The path to the recording file to replay.
### Example (CLI)
```bash
# first argument: the game directory
# --replay switch is the file path relative to the game directory
# --speed switch is optional. a value of 4 will run the replay and game at 4x speed
# cli command example is in the context of Linux and Mac, for Windows the binary would be ./dragonruby.exe
./dragonruby ./mygame --replay replay.txt --speed 4
```
```
--------------------------------
### Bind Render Target to Shader Texture
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/api/outputs.md
Use `shader_tex1` through `shader_tex15` to bind additional render targets to shader textures, starting from `tex1`. `tex0` is reserved for the screen output. This example binds a custom render target named `:single_blue_square` to `tex1`.
```ruby
def tick args
args.outputs.shader_path = "shaders/example.glsl"
args.outputs.shader_tex1 = :single_blue_square
args.outputs[:single_blue_square].background_color = { r: 255, g: 255, b: 255, a: 255 }
args.outputs[:single_blue_square].w = 1280;
args.outputs[:single_blue_square].h = 720;
args.outputs[:single_blue_square].sprites << {
x: 0,
y: 0,
w: 100,
h: 100,
path:
"sprites/square/blue.png"
}
args.outputs.background_color = { r: 0, g: 0, b: 0 }
args.outputs.sprites << {
x: 0,
y: 0,
w: 200,
h: 200,
path:
"sprites/square/red.png"
}
end
```
```glsl
uniform sampler2D tex0;
uniform sampler2D tex1; // :single_blue_square render target
varying vec2 v_texCoord;
void noop() {
vec4 pixel_from_rt = texture2D(tex1, v_texCoord);
// if the pixel from the render target isn't white
// then render the pixel from the RT
// otherwise render the pixel from the screen
if (pixel_from_rt.r < 1.0 ||
pixel_from_rt.g < 1.0 ||
pixel_from_rt.b < 1.0) {
gl_FragColor.r = pixel_from_rt.r;
gl_FragColor.g = pixel_from_rt.g;
gl_FragColor.b = pixel_from_rt.b;
} else {
gl_FragColor = texture2D(tex0, v_texCoord);
}
}
```
--------------------------------
### Column Examples with Layout
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.txt
Demonstrates column rendering using the Layout module. Various column widths and heights are illustrated.
```ruby
def render_column_examples args
# columns (yellow)
yellow = { r: 255, g: 255, b: 128 }
args.outputs.labels << Layout.rect(row: 1, col: 12 + 3).merge(text: "column examples", anchor_x: 0.5, anchor_y: 0.5)
6.times do |col|
args.outputs.solids << Layout.rect(row: 0, col: 12 + col, w: 1, h: 1).merge(**yellow)
end
3.times do |col|
args.outputs.solids << Layout.rect(row: 1, col: 12 + col * 2, w: 2, h: 1).merge(**yellow)
end
6.times do |col|
args.outputs.solids << Layout.rect(row: 2, col: 12 + col, w: 1, h: 2).merge(**yellow)
end
end
```
--------------------------------
### Easing Functions Animation Example
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/samples.txt
This snippet demonstrates how to use the Numeric#ease method to apply different easing functions to animate properties like position and size. It requires setting up starting and target values, animation duration, and the desired animation type.
```ruby
def tick args
# STOP! Watch the following presentation first!!!!
# Math for Game Programmers: Fast and Funky 1D Nonlinear Transformations
# https://www.youtube.com/watch?v=mr5xkf6zSzk
# You've watched the talk, yes? YES???
# define starting and ending points of properties to animate
args.state.target_x = 1180
args.state.target_y = 620
args.state.target_w = 100
args.state.target_h = 100
args.state.starting_x = 0
args.state.starting_y = 0
args.state.starting_w = 300
args.state.starting_h = 300
# define start time and duration of animation
args.state.start_animate_at = 3.seconds # this is the same as writing 60 * 5 (or 300)
args.state.duration = 2.seconds # this is the same as writing 60 * 2 (or 120)
# define type of animations
# Here are all the options you have for values you can put in the array:
# :identity, :quad, :cube, :quart, :quint, :flip
# Linear is defined as:
# [:identity]
#
# Smooth start variations are:
# [:quad]
# [:cube]
# [:quart]
# [:quint]
# Linear reversed, and smooth stop are the same as the animations defined above, but reversed:
# [:flip, :identity]
# [:flip, :quad, :flip]
# [:flip, :cube, :flip]
# [:flip, :quart, :flip]
# [:flip, :quint, :flip]
# You can also do custom definitions. See the bottom of the file details
# on how to do that. I've defined a couple for you:
# [:smoothest_start]
# [:smoothest_stop]
# CHANGE THIS LINE TO ONE OF THE LINES ABOVE TO SEE VARIATIONS
args.state.animation_type = [:identity]
# args.state.animation_type = [:quad]
# args.state.animation_type = [:cube]
# args.state.animation_type = [:quart]
# args.state.animation_type = [:quint]
# args.state.animation_type = [:flip, :identity]
# args.state.animation_type = [:flip, :quad, :flip]
# args.state.animation_type = [:flip, :cube, :flip]
# args.state.animation_type = [:flip, :quart, :flip]
# args.state.animation_type = [:flip, :quint, :flip]
# args.state.animation_type = [:smoothest_start]
# args.state.animation_type = [:smoothest_stop]
# THIS IS WHERE THE MAGIC HAPPENS!
# Numeric#ease
progress = args.state.start_animate_at.ease(args.state.duration, args.state.animation_type)
# Numeric#ease needs to called:
# 1. On the number that represents the point in time you want to start, and takes two parameters:
# a. The first parameter is how long the animation should take.
# b. The second parameter represents the functions that need to be called.
#
# For example, if I wanted an animate to start 3 seconds in, and last for 10 seconds,
# and I want to animation to start fast and end slow, I would do:
# (60 * 3).ease(60 * 10, :flip, :quint, :flip)
# initial value delta to the final value
calc_x = args.state.starting_x + (args.state.target_x - args.state.starting_x) * progress
calc_y = args.state.starting_y + (args.state.target_y - args.state.starting_y) * progress
calc_w = args.state.starting_w + (args.state.target_w - args.state.starting_w) * progress
calc_h = args.state.starting_h + (args.state.target_h - args.state.starting_h) * progress
args.outputs.solids << [calc_x, calc_y, calc_w, calc_h, 0, 0, 0]
# count down
count_down = args.state.start_animate_at - args.state.tick_count
if count_down > 0
args.outputs.labels << [640, 375, "Running: #{args.state.animation_type} in...", 3, 1]
args.outputs.labels << [640, 345, "%.2f" % count_down.fdiv(60), 3, 1]
elsif progress >= 1
args.outputs.labels << [640, 360, "Click screen to reset.", 3, 1]
if args.inputs.click
$gtk.reset
end
end
end
```
--------------------------------
### Install Clang on Debian-based Linux
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/samples/12_c_extensions/01_basics/README.md
Installs Clang version 10 on Debian-based systems and displays the installed version.
```bash
> apt-get install clang-10
> clang-10 --version
```
--------------------------------
### Initialize Game and Start Server (Space Invaders)
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.html
Initializes the game and starts a server for the Space Invaders sample. This is typically the entry point for the application.
```ruby
# ./samples/14_vr/03_space_invaders/app/main.rb
require 'app/tick.rb'
def tick args
GTK.start_server! port: 9001, enable_in_prod: true
tick_game args
end
```
--------------------------------
### Start Scene Implementation
Source: https://github.com/dragonruby/dragonruby-game-toolkit-contrib/blob/main/docs/static/samples.html
Defines the start scene for the game, including a 'play' button that initiates the game. This scene is displayed on game start.
```Ruby
# the start scene is loaded when the game is started
# it contains a PulseButton that starts the game by setting the next_scene to :game and
# setting the started_at time
class StartScene
attr_gtk
def initialize
@play_button = PulseButton.new pulse_button_location, "play" do
state.next_scene = :game
state.events.game_started_at = Kernel.tick_count
state.events.game_over_at = nil
end
end
def title_prefab
label = { text: "Squares", anchor_x: 0.5, anchor_y: 0.5, size_px: 64, **BLACK }
if Grid.landscape?
Layout.rect(row: 1, col: 11, w: 2, h: 2, allscreen: true)
.center
.merge(label)
else
Layout.rect(row: 1, col: 5, w: 2, h: 2, allscreen: true)
.center
.merge(label)
end
end
def pulse_button_location
if Grid.landscape?
Layout.rect(row: 9, col: 11, w: 2, h: 2, allscreen: true)
else
Layout.rect(row: 17, col: 5, w: 2, h: 2, allscreen: true)
end
end
def tick
return if state.current_scene != :start
@play_button.rect = pulse_button_location
@play_button.tick inputs.mouse
outputs[:start_scene].w = Grid.allscreen_w
outputs[:start_scene].h = Grid.allscreen_h
outputs[:start_scene].primitives << title_prefab
outputs[:start_scene].primitives << @play_button.prefab
end
end
```