Getting to Know the DragonRuby Game Engine
Tags: dragonruby, ruby, gamedev
Published: 2020-11-08 23:00:38

---
title: Getting to Know the DragonRuby Game Engine
published: true
description: learning the DragonRuby game engine
tags: dragonruby, ruby, gamedev
//cover_image: https://direct_url_to_image.jpg
---

DragonRuby Game Toolkit is a 2D game engine for making games using the Ruby programming language. I happened to get a license for it as part of the [Bundle for Racial Justice and Equality](https://itch.io/b/520/bundle-for-racial-justice-and-equality) on itch.io back in June but never got around to trying it out. Last week I received an email from one of the creators and it mentioned that there is a beginner friendly Game Jam so I figured now would be a good time to dive in! 

The [docs](http://docs.dragonruby.org/) are pretty extensive but here I'll attempt to sum up some of the very basics.


## Game Loop
The main function in DragonRuby is called `tick` and it runs 60 times per second (about every 16ms). There is no `delta time` to worry about; the loop just works at 60fps.

The code below will create a new instance of `Dog` every 16ms and store it in `args.state` (I'll come back to this in a bit).

```
def tick args
  args.state.dog = Dog.new
end

class Dog
  def initialize
    puts "I am a new dog"
  end
end
```

<center>
	<img src="https://github.com/robotspacefish/blog-photos/blob/master/dragonruby/new_dog_repeat.png?raw=true" alt='"I am a new dog!" written repeatedly in the console"'>
</center>

Being that you only want to create a new `Dog` instance once and set it to `args.state.dog`, this isn't ideal. Luckily, there is an easy way to fix this.

```
def tick args
  args.state.dog = Dog.new if !args.state.dog
end
```

Here I am using a conditional to set `args.state.dog` if it does not already exist. By doing this, it will only set `args.state.dog` the first time and will only create the `Dog` instance once. 

This is repetitive and long-winded, however. Below, you see an example that accomplishes the same thing by using `||=` (or equals), which means to only set the value if its value is `false` or `nil`.

```
def tick args
  args.state.dog ||= Dog.new
end
```

## args 
`args` contains all the functionality for making your game, such as a way handle input and output, and store your variables. 

### args.state

`args.state` is a data structure where you can store your game data, such as an instance of `Dog`, or your player's position. What's stored in state is carried over from tick to tick.

```
def tick args 
	args.state.player.x ||= 120
	args.state.player.y ||= 200
end

``` 

### args.outputs

`args.outputs` is used for rendering to the screen.

This creates a red 100x100 square at (100, 250). You can change the color by adjusting the RGB values.

```
# 								[x, y, width, height, red, green, blue]
args.outputs.solids << [100, 250, 100, 100, 255, 0, 0]
```

**Quick Note on the coordinate sytem:** `(0, 0)` is at the bottom left corner. Positive numbers go up and to the right and negative numbers go down and to the left.

`args.labels` is used to write text to the screen.

This adds the black text 'This is a red square' slightly below the red square.

```
#								[x, y, text, red, green, blue]
args.outputs.labels << [100, 240, "This is a red square", 0, 0, 0]
```

<center>
	<img src="https://github.com/robotspacefish/blog-photos/blob/master/dragonruby/red_square_with_text.png?raw=true" alt='red square'>
</center>

### args.inputs 
`args.inputs` is used for keyboard, mouse, and gamepad input.

**Mouse Input**

This code initializes a `click_count` to 0 and displays the total clicks to the 
screen. Every time the user clicks and releases their mouse button, the `click_count` is increased by 1.

```
 args.state.click_count ||= 0
  
 args.outputs.labels << [100, 240, "Click count: #{args.state.click_count}", 0, 0, 0]

 args.state.click_count += 1 if args.inputs.mouse.up
```

**Keyboard Input**

This code initializes a player's (x,y) position to (100, 100) and creates a red square (just like above) at those coordinates. Then, it increases or decreases the (x,y) values by 1, depending on which directional key was pressed.

```
def tick args
  args.state.player.x ||= 100
  args.state.player.y ||= 100
  args.outputs.solids << [args.state.player.x, args.state.player.y, 100, 100, 255, 0, 0]

  args.state.player.x += 1 if args.inputs.keyboard.d
  args.state.player.x -= 1 if args.inputs.keyboard.a
  args.state.player.y += 1 if args.inputs.keyboard.w
  args.state.player.y -= 1 if args.inputs.keyboard.s
end
```


---

There is a lot more to DragonRuby that I haven't even touched on. If you're interested in trying it out I highly recommend you check out the docs [here](http://docs.dragonruby.org/), and [here](https://dragonruby-docs.readthedocs.io/), which also link to some tutorial videos. There is also a free [course](https://wndx.school/p/dragon-ruby-game-toolkit-tutorial) you can check out to get started.

Here is a [link](https://itch.io/jam/teenytiny-dragonruby-minigamejam-2020) to the Game Jam if you'd like to join. You can also claim a [free Game Jam license](http://teenytiny.dragonruby.org/).