Category Archives: Ruby

Don’t Leave a Festering Pile

One of the most memorable statements from Clean Code was the author describing some of his own example code as a “festering pile.” And he doesn’t just use the term once, he uses it multiple times.

The most important statement however comes after he goes through how he cleans up his code and he is going over key points at the end of the chapter.

It is not enough for code to work. Code that works is often badly broken. Programmers who satisfy themselves with merely working code are behaving unprofessionally.
– Uncle Bob in Clean Code

Get It Working, Then Clean It Up

Don’t get me wrong, you should get your code working. If it does not work, it is completely useless.

But that is not where you stop.

When you stop here, it becomes difficult to add features to your program and makes it more likely that you will introduce errors later.

As a professional programmer and creator, cleaning up your code after you get it working is a must.

What’s That Smell?

As I am working on my current game, I started noticing that some of my own code was becoming a bit of its own smelly, festering pile.

Classes were getting a little clunky, functions where getting a little too long, and it was taking longer to make small changes.

Since I am trying to write the same logic in 2 different languages (Monkey-X for the client and Ruby for the server), having clean code was even more important to be able to replicate the logic in a second language.

And with the code getting a little cluttered, there started being some hard to figure out bugs where the client would show one thing, but the server would do another.

I finally got the code behaving the same and it took longer than it should have.

Programming Febreeze

Now it is time to get rid of some of these smells. The way to do that in programming is refactoring.

This is basically what Clean Code was all about. Changing your code to be more clear and designing the classes and methods to be easier to change (think DRY and SRP) have your code smelling like fresh linen.

That is what I am working on now with Drone Tournament. My original goal this year was to finish a game every 3 months, but I don’t want a half baked game. So I am taking the time to refactor the code and clean it up because I am a professional.

Be a Pro, Clean Your Code

Ruby Mod Operator Does Not Behave As Expected

I am writing the multiplayer server for my current game in Ruby using Sinatra. Since it is turn based and not particularly performance heavy, this is not a problem. One of the cardinal rules of making a multiplayer game is don’t trust the client.

This means I needed to write the game logic for the game on the server.

Modulo

Part of the game logic involves taking an angle and a position and calculating a new position and angle based of a units performance stats. In order to simplify the math, I wanted to keep all the angles positive.

So if the angle is negative, I Mod it by 360 and then add 360.

If the angle is positive, I just Mod it by 360.

But then I change it either adding a units turn rate to it or subtracting the turn rate from it.

The client (written in Monkey-X) was working 100% as expected. But the server was giving me some weird results.

Negative Numbers Behave Differently

I have always understood Mod, often the % operator in language, to return the remainder from a division operation. And that is what it is supposed to do. In Monkey-X that is exactly what it does (incidentally it is the word ‘Mod’ in Monkey-X). And in Ruby, all of my positive angles where behaving as expected.

But for negative numbers in Ruby, something like:

-21 % 5

is not going to return -1, it returns 4 (go ahead and try it in irb).

How Do You Get The Remainder?

Funny enough, in Ruby you need to use the .remainder function on a numeric type to get a consistent result. So:


num = -21
result = num.remainder(5)

and result will equal -1 as expected.

TL:DR

In Ruby if you want the remainder of a number, use the .remainder method instead of the % operator, especially if you are going to hit negative numbers.

Monkey-X and Connecting to Your Server

While traveling to visit family this past weekend I was attempting to set up a simple high score server for Prism Ship. I decided to use Sinatra for the backend because it would allow me to make a very simple and quick server using only a couple of lines since I don’t need an interface of any kind. Little did I know this simple task would turn out to take several hours.

This was partly caused by my lack of familiarity with Monkey-X and partly allergies.

Backstory

I was staying with some relatives and the females all went shopping and what not. My brother-in-law had made plans to spend the afternoon gaming at a friends house (Dark Souls II anyone?) so I tagged along figuring I would just program while they played. Better than sitting in an empty apartment for 5 hours right?

I had been to this friends house before but forgot about the pets. Normally I don’t have any problems with dogs or cats and didn’t the last time I was there (which was probably because we spent a majority of the time outside on that visit). However, this visit caused very annoying allergy type symptoms to be present for 4.5/5 hours.

Now, the server was simple enough to set up. Just a few lines of Ruby using Sinatra to test.

require 'sinatra'

get '/' do
body "High Score List"
end

It’s really that simple.

First Problem – Different Domains

I noticed that despite following the instructions in the documentation for the brl.httprequest module in Monkey-X, I was not getting expected output. So I opened the dev tools in the browser and saw this:
Access-Control-Allow-Origin: access denied
After a brief investigation, it seemed to be related to CORS (Cross Origin Resource Sharing). It was caused by trying to run the game on the localhost and accessing the Sinatra server running on Heroku. This is fixed with a little addition to the Ruby code:
require 'sinatra'

get '/' do
response.headers['Access-Control-Allow-Origin'] = "*"
body "High Score List"
end

This is not very secure, but it fits our purposes for the time being.

Second Problem – Not Carefully Reading Documentation

A nose that is running because of excessive cat and dog dander will keep you from thinking straight and reading carefully. I missed an important line in the HttpRequest documentation that says – “Your application must continously call UpdateAsyncEvents at regular intervals (for example, once per OnUpdate) while an http request operation is in progress for it to complete.”

My little program was sending just fine, I could see the server send back a nice HTTP:200 code, but the game would not fire the OnHttpComplete method.

The very next time I sat down to work on this problem, it took less than 5 minutes of googling and reading to find the cause. I put the UpdateAsyncEvents line in and everything just started working.

Moral of the story

Read documentation carefully and try not to program somewhere that will cause you to have a runny nose (or other types of distractions).

Shallow Copy Got Me

How to properly initialize a 2D array in Ruby

I am working on a small game and that game happens to have a two dimensional map. In trying to be minimalistic, the implementation of the map is just a 2d array. For some reason, I decided it was a good idea to learn a new programming language and 2 new frameworks to make this game.
When creating an array in Ruby, one can prefill it easily like so

myarray = Array(10, 0)

So without reading any documentation I thought “well I think I know what I’m doing” and proceeded to write

myarray = Array.new(10, Array.new(10, 0))

The problem here is that it makes an array of 10 references to the same array. The right way to do it is to use a block following a call to Array with only 1 argument. This is conveniently listed fairly early on in the Ruby Array documentation.

myarray = Array.new(10) { Array.new(10, 0) }

Its just one of those things that happens when you are learning a new language.