### 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, "hello

This #{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, "hello

This #{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, "hello

This #{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, "hello

This #{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 ```