code

Building Browsergames: Integrating weapons into our combat system (Perl)

Even though we’ve built a combat system and a weapons system, we haven’t done anything yet to make them work together. Today, we’re going to be modifying our combat system so that it takes into account the ‘attack’ attribute of the user’s current primary weapon.

This is a quick, easy change - all we have to do is retrieve the ‘attack’ stat for the user’s primary weapon, and then add it onto their attack stat for our combat calculations. Here’s the code that retrieves a players stats, from forest.cgi:

28
29
30
31
32
33
my %player = (
	name		=>	$username,
	attack		=>	stats::getStat('atk',$userID),
	defence		=>	stats::getStat('def',$userID),
	curhp		=>	stats::getStat('curhp',$userID)
);

If you’ve been following along with all of the tutorials so far, you might have noticed a slight problem: we can’t retrieve weapon stats yet. Thanks to our DRY changes from earlier, it’s easy to write that code:

1
2
3
4
5
6
7
8
9
10
11
package weaponstats;
use DBI;
 
use statsDRY;
 
sub getWeaponStat {
	my ($statName,$userID) = @_;
	return statsDRY::getStatDRY('Weapon',$statName,$userID);
}
 
1;

It’s even easier because we aren’t going to be allowing users to change the stats - which means we only need to write the code to retrieve them(and not update them).

With that finished, we’re going to make sure that forest.cgi includes the new code:

8
use weaponstats;

Because our combat formula is as simple as it is(attack - defence), all we need to do is modify the ‘attack’ value that we stored in the %player hash with the attack for their primary weapon:

my $phand = stats::getStat('phand',$userID);
$player{attack} += weaponstats::getWeaponStat('atk',$phand);

And with that small piece of code added, we’re done! If the weapon has an attack value, it will be added to the player’s attack when they fight the monster - even if it’s negative.

Extra Credit

  • Make it so that only positive attack values are added to the player’s attack.

There was a small bug with the stats retrieval code found in this version of the tutorial - it has been fixed in the latest revision of the Google Code Repository. Make sure to update if you’ve been using it!

Monday, September 15th, 2008 buildingbrowsergames, code, perl No Comments

Building Browsergames: Integrating weapons into our combat system (PHP)

For all that we’ve built both a combat system and a weapons system, we haven’t yet done anything that allows the weapon a user has selected as their primary weapon to affect the combat system. Today, we will be integrating weapons into our combat system, so that the stats of the weapon actually affect the combat results.

This is actually a lot easier than it sounds - all we have to do is retrieve the weapon’s ‘attack’ stat, use it to modify the damage that the player does, and we’re finished! We’ll open up forest.php, to the piece of code that retrieves our player’s attack:

21
22
23
24
25
26
$player = array (
	name		=>	$_SESSION['username'],
	attack 		=>	getStat('atk',$userID),
	defence		=>	getStat('def',$userID),
	curhp		=>	getStat('curhp',$userID)
);

Unfortunately, we don’t yet have a weapon stats retrieval system - but thanks to our DRY changes from earlier, that’s an easy piece of code to add:

1
2
3
4
5
6
7
8
9
<?php
 
require_once 'stats-dry.php';
 
function getWeaponStat($statName,$weaponID) {
	return getStatDRY('Weapon',$statName,$weaponID);
}
 
?>

Because we won’t be allowing users to modify the stats of weapons in the game, we only need to add the getWeaponStat function. Save that file as weapon-stats.php, and go back to forest.php. First off, we’ll require our weapon stats code:

4
require_once 'weapon-stats.php';

Because we’re using a simple combat formula, we can directly modify the player’s attack attribute in the associative array that we are using to store their stats. Here’s how we would retrieve their primary weapon, and then add it’s attack to the player’s:

28
29
30
$phand = getStat('phand',$userID);
$atk = getWeaponStat('atk',$phand);
$player['attack'] += $atk;

And with that small piece of code added, we’re finished! If the weapon has an attack value(even if it’s negative), it will be added to the player’s when they attack the monster.

Extra Credit

  • Make the combat system display the name of the weapon when the player attacks - e.g. “You attack <monster> with your <weapon> for 10 damage!”.

There was a small bug with the stats retrieval code found in this version of the tutorial - it has been fixed in the latest revision of the Google Code Repository. Make sure to update if you’ve been using it!

Friday, September 12th, 2008 buildingbrowsergames, code, php No Comments

Displaying A User’s Stats (Ruby on Rails)

Introduction

This entry is based on the Building Browsergames blog entry: Displaying A User’s Stats (PHP)

It’s a pretty good idea to at least skim quickly through the original article before you go through this one, just to familiarize yourself with what we’re going to do.

Second Verse Same As The First

> ruby script/generate migration AddGoldToUser gold:integer

To add a new stat in the database for the amount of gold held we’ll create and edit a new migration. You saw something just like this a few entries back in this series:

class AddGoldToUser < ActiveRecord::Migration
  def self.up
    add_column :users, :gold, :integer, :default => 0
 
    # Any existing users will get the new stat just like new users. If we had 
    # to do any special setup for the value though, we could do it here.
  end
 
  def self.down
    remove_column :users, :gold
  end
end

Note that a default value for the gold stat has been added above. The code as generated won’t have that. Be sure to run the new migration so we get our database schema updated:

> rake db:migrate

Now we’ll change the index page to display the various stats that we’ve assigned to our user whenever he/she logs in.

<h1>Welcome To The Game</h1>
 
<% if logged_in? %>
<h2><%= @current_user.login %></h2>
 
<ul>
  <li>Attack: <strong><%= @current_user.attack %></strong></li>
  <li>Defense: <strong><%= @current_user.defense %></strong></li>
  <li>Magic: <strong><%= @current_user.magic %></strong></li>
  <li>Gold in hand: <strong><%= @current_user.gold %></strong></li>
</ul>
<% end %>
The welcome page now displays both the user\'s login name and his/her stats.

The welcome page now displays both the user's login name and his/her stats.

Note that neither the controller nor the view have ever accessed the database or set any values. Instead they get the user model which represents a particular user and call functions on it to get its values. This is exactly the kind of thing we want to see, controllers and views which are ignorant on details (like SQL) and depend upon a well written model to handle them. This will give us compartmentalized code that is easier to understand, to test, and to modify.

By this point, you should be starting to get a little more comfortable with how Rails lays out things. You’ll see HTML in the views with the occasional reference to variables we need to display (e.g. @current_user). Those variables are setup in a controller method which is called before we get the view to render (e.g. index). The controller will rely upon the model (e.g. User) to handle all the nitty gritty details of loading and storing data and also rules for that data (e.g. no more than two weapons per user). You’ll see this again in the next installment as we turn to adding combat to our game.

Extra Credit

  1. I’m told that I’m a pretty good teacher, in person, but this is not in person and there are probably a lot of times I pick the wrong things to touch lightly on and to belabor. So, a few good books, a very few, is a good idea both for their reference value and because they tend to cover material I don’t cover or give you another chance to see the same things in a different way. Here are two I recommend: The Rails Way (Addison-Wesley Professional Ruby Series) (the best reference text by far) and RailsSpace: Building a Social Networking Website with Ruby on Rails (Addison-Wesley Professional Ruby Series) (a complete social network site built in Rails 1.2, a little bit of the code is older but still one of the best all around books out there).


Thursday, September 11th, 2008 buildingbrowsergames, code, rubyonrails No Comments

Adding Stats (Ruby on Rails)

Introduction

This entry is based on the Building Browsergames blog entry: Adding Stats (PHP)

It doesn’t hurt to have at least skimmed through the original blog entry about the PHP version before proceeding to the the Ruby on Rails version below.

Setting The User’s Defaults

Now, having skimmed through the PHP version of this, you can ignore most of what happened there. We don’t have to do anything special to use our templating system, it just works. We don’t need to go get the ID of the user after creating a new one, ActiveRecord handles that for us. As soon as we’ve done a User.create or User.new plus a save of the record, the ID will already be filled in for you to use. So where does that leave us?

Rails subscribes to a pattern for developing applications known as Model-View-Controller, I’ll link it to the Wikipedia entry for the topic because frankly I couldn’t find any short simple explanation of it. So hopefully as you see me use it through this series of tutorials you’ll pick up the basics by osmosis. The way MVC is relevant to this is that there is no way we are going to add new stats to a user or assign default values within the registration page or any other page. In Rails, those are views and they exist not to contain game logic but rather to simply display information and take input from the user. That’s it. Code to change the user belongs in the User model, so that’s where we’ll put it.

In this case what we want to do is assign a new set of default values (since the defaults we set in the migration that added the stats isn’t what we wanted). We could add another migration to alter the default values but that’s only necessary if we’ve got existing users we need to fix in the database and the only user’s we’ve got are test ones. If you only need to fix new users, we can just add a before_create function to the User model (app/models/user.rb):

def before_create
  self.attack = 5
  self.defense = 5
  self.magic = 5
end

Here’s the User model with our new code in place. Note that virtually all the code here came from restful_authentication when it created the User model in the first place. We just added the code above to it:

require 'digest/sha1'
 
class User < ActiveRecord::Base
  include Authentication
  include Authentication::ByPassword
  include Authentication::ByCookieToken
 
  validates_presence_of     :login
  validates_length_of       :login,    :within => 3..40
  validates_uniqueness_of   :login,    :case_sensitive => false
  validates_format_of       :login,    :with => RE_LOGIN_OK, :message => MSG_LOGIN_BAD
 
  validates_format_of       :name,     :with => RE_NAME_OK,  :message => MSG_NAME_BAD, :allow_nil => true
  validates_length_of       :name,     :maximum => 100
 
  validates_presence_of     :email
  validates_length_of       :email,    :within => 6..100 #r@a.wk
  validates_uniqueness_of   :email,    :case_sensitive => false
  validates_format_of       :email,    :with => RE_EMAIL_OK, :message => MSG_EMAIL_BAD
 
  # HACK HACK HACK -- how to do attr_accessible from here?
  # prevents a user from submitting a crafted form that bypasses activation
  # anything else you want your user to change should be added here.
  attr_accessible :login, :email, :name, :password, :password_confirmation
 
  # Authenticates a user by their login name and unencrypted password.  Returns the user or nil.
  #
  # uff.  this is really an authorization, not authentication routine.  
  # We really need a Dispatch Chain here or something.
  # This will also let us return a human error message.
  #
  def self.authenticate(login, password)
    u = find_by_login(login) # need to get the salt
    u && u.authenticated?(password) ? u : nil
  end
 
  protected
 
  def before_create
    self.attack = 5
    self.defense = 5
    self.magic = 5
  end
end

Extra Credit

  1. In this entry you saw one of the hooks ActiveRecord provides for us to perform actions at certain points within the lifecycle of an object (i.e. before_create). There are actually eight hooks in total for you to use. Visit one of several public repositories of Rails documentation (e.g. http://api.rubyonrails.org/) and read the documentation for ActiveRecord::Callbacks to see them all.
  2. As was mentioned in the previous extra credit item, http://api.rubyonrails.org/ is only one of several repositories of Rails and/or Ruby documentation. Here are a few others: RailsBrain.com, GotApi.com (this site offers documentation for many other APIs as well), and Noobkit Docs.

Wednesday, September 10th, 2008 buildingbrowsergames, code, rubyonrails No Comments

Post Mortem: TerraTanks: Dominion (Part 2) Need to improve

Really this section could go on forever. I fell into a despair about the game 2 months ago where every week I would make a large update to fix what I thought was the game not being fun and by the end of the week the game was not fun again. This has since dissipated and I have been having a blast with the game.

I want to focus on 2 things that I think need talking about (and one of them is not web page layout). One is something games in general suffer from. The other is something my game uniquely suffers from.

Thing 1: Scope, scope, scope, scope, scope.
Something I have difficulty with is wrapping my brain around just how big something is going to be. While being big is not necessarily a bad thing, being big and empty is a horrible thing. When you create a space, that space needs to be filled out completely. The first game I made (Atlas: The Gift of Aramai) suffered from this. The driving principal of the game was “we want to make it big”. The fallout of this was 5 years creating content to still have the game seem desolate and empty as you character walked for 7 minuets to the next town.

It is amazing how the power of squares can effect the amount of content you have to generate. Filling area is literally X times more time consuming than filling a linear map where X is the length of that map.

When starting a game, think small. When you think of most browser games they occur on one screen. Depth is so much more valuable than breadth. Depth displays the designer’s creativity. Depth in a small game means that you can actually release your game in a time span that doesn’t drive you crazy.

Far be it from me to follow my own advice. TerraTanks is a very large game. I believe it is also a very deep game. It certainly is a complicated game that evaluates actions in a sophisticated way. It took me 2 months to finish the breadth of the game and an additional 8 months to add depth to a state where I am satisfied with my work. (2 months of that was under the public beta). I have a very long list of things to do to add more depth to the game. It is playable and fun as it is, but the oportunity to add depth seems to be expanding and not getting smaller as I create features.

Thing 2: I created an odd way of displaying the map.
This can be prefaced by saying that compared to many of my peers, I think sideways. It is fun to be unique in my problem solving but it is sometimes difficult for me to relate my ideas to the general audience.

This is what I mean. Most people when they want to create a map they will go about creating a cartesian coordinate system grid. People understand the incrementing value and it is easy to calculate distance using the pythagorian theorem. When I went about creating the map I originally thought of how space looked in my head. You have a universe with nested galaxies. Each galaxy had nested stars. Most stars are solar systems with nested planets. The idea of nesting is what stuck with me. What I did from that was to create a system of nested areas which defined my space. My galaxy was a square divided into 4 square quadrants like this:

0 | 1
----
2 | 3

Please note how like any good programmer I start with 0. Each square quadrant was divided into 16 square sectors so in quadrant 0 it would look like:

00 | 01 | 02 | 03
-------------
04 | 05 | 06 | 07
-------------
08 | 09 | 0a | 0b
-------------
0c | 0d | 0e | 0f

Now note that since I have 16 squares I am using hexidecimal notation.

What I end up with is planets that have identifiers that look like 0b23c5 which accurately descirbes the location of the planet in a nested notation. While it makes complete sense, this is really difficult to explain. Most people don’t have a computer science background and even if you do, people don’t view maps as a series of nested grids. While this way of making maps simplified programming in many respects, but it is not good to make your end users learn something like that to understand your game. The other problem is the effort to convert the game to a cartesian map is difficult and pretty much impossible now that people are already playing the game.

Game makers often fall for the old trap of either trying to show how smart they are or treating their audience with contempt for not knowing the minutea of their own passion. Really smart game makers can present difficult concepts in a way that everyone can pick up and understand. You don’t need to spell things out for your audience at every moment, but don’t make them figure you out either.

Most of the remaining issues with my game involve how to efficiently display large amounts of information. This is something I work on every day so I don’t think of it as something that I did wrong in hindsight, but something that is still in progress.

Putting It All Together (Ruby on Rails)

Introduction

This entry is based upon this entry from the Building Browsergames blog: Putting It All Together (PHP)

A Quick Recap

In past installments we provided a way for users to authenticate who they were (login, logout, signup) and have users with stats. The original article shows the SQL that was used to create the tables but we used migrations from our Rails code to do the same thing.

The example code we’ve already built is basically equivalent to what is built in the PHP entry so all we’re going to do is a few minor tweaks to match the version outlined in the article about the PHP version:

  • Our pages don’t have titles - We’ll use the layout feature of Rails to fix that.
  • Our pages don’t have any style - The PHP examples don’t have much style either, but at least they’ve got messages in green and red depending upon the type of message.

Note: One other difference is that restful_authentication logs you in immediately after registration. If the plan is not to require email confirmation, I prefer that we do it that way.

Let’s go through the changes required to make our code match the PHP version feature for feature so we’re up with the latest version.

Add Titles

We’re going to use another part of the templating engine in Rails to make it easy to have a title on every page. Rails has a concept called layouts. A layout takes the [something].html.erb files we’ve been creating and wraps them with another [something].html.erb file. It’s handy where you want a group of pages to all have the same headers, footers, navigation, etc. which, if you think about it, is most every website you go to. In order to wrap all the pages you create a layout called application.html.erb. A layout with that name in the layouts directory will be used as a default layout for the entire application. You can override the default easily if you need to though, one of the extra credit learning opportunities this week is about that. Here’s the app/views/layouts/application.html.erb I created:

<html>
  <head>
    <title><%= @title %></title>
  </head>
  <body>
    <%= yield  %>
  </body>
</html>

Now we can edit the various controllers (welcome_controller.rb, users_controller.rb, and sessions_controller.rb) adding assignments to @title in the methods that get called before we go to the view. For example:

class WelcomeController < ApplicationController
  def index
    # Call the function current_user to get the user assigned to the 
    # @current_user variable (if anyone is logged in). The
    # function comes with restful_authentication.
    current_user
 
    @title = "Welcome"
  end
end

Note that all we added here was an assignment to the @title variable in the controller action. Once the action is finished Rails will render the app/views/welcome/index.html.erb (with our new layout surrounding it) and the @title will go into the title of the page.

Add A Little Style

Styling message display is pretty easy, we just put a div tag with a class around the flash[:notice] output and we’re set. The class can then be styled any way we like:

<% if flash[:notice] %>
  <div class="flashNotice"><%= h flash[:notice] %></div>
<% end %>

To handle styling our entire game we’ll create a new file (public/stylesheets/pbbg.css). To get the stylesheet loaded we can add the following line within the head section of app/views/layouts/application.html.erb:

<%= stylesheet_link_tag "pbbg"  %>

Styling the errors that come out in the form whenever a user’s input fails validation isn’t much more complicated. If we take our registration form as an example, we can botch the password confirmation field and submit to see what we get:

<div class="errorExplanation" id="errorExplanation">
  <h2>3 errors prohibited this user from being saved</h2>
  <p>There were problems with the following fields:</p>
  <ul>
    <li>Password confirmation can't be blank</li>
    <li>Password can't be blank</li>
    <li>Password is too short (minimum is 6 characters)</li>
  </ul>
</div>
 
<form action="/users" method="post"> 
  <div style="margin:0;padding:0">
    <input name="authenticity_token" type="hidden" value="31249bde4aede2633a4391a44eafff49ec27ae17" />
  </div>
 
  <p><label for="login">Login</label><br/>
  <input id="user_login" name="user[login]" size="30" type="text" value="Testing" /></p>
 
  <p><label for="email">Email</label><br/>
  <input id="user_email" name="user[email]" size="30" type="text" value="sample@email.com" /></p>
 
  <p><label for="password">Password</label><br/>
  <div class="fieldWithErrors">
    <input id="user_password" name="user[password]" size="30" type="password" />
  </div></p>
 
  <p><label for="password_confirmation">Confirm Password</label><br/>
  <div class="fieldWithErrors">
    <input id="user_password_confirmation" name="user[password_confirmation]" size="30" type="password" />
  </div></p>
 
  <p><input name="commit" type="submit" value="Sign up" /></p>
</form>

That’s the error output and the form (with some of the error output wrapped through it) generated automatically by Rails. The thing to notice there is that Rails has inserted a couple of div tags automatically. One wraps the description of any and all errors (i.e. class=”errorExplanation”) and the other wraps individual fields which had errors (i.e. class=”fieldWithErrors”). By styling those two classes and even tags within each one (e.g. the h2 and ul tags in the explanation section) we can make the error output from Rails a little more appealing.

It probably wouldn’t take you a lot of effort to come up with better CSS to style the tags than what I present here, but at least it will give you a starting point (public/stylesheets/pbbg.css):

.errorExplanation {
  background-color:#ffcccc;
  border:1px solid red;
  vertical-align:top;
  padding: 10px;
}
 
.errorExplanation h2 {
  color: maroon;
}
 
.errorExplanation ul li {
  list-style: square;
}
 
.fieldWithErrors input[type="text"],
.fieldWithErrors input[type="password"] {
  border-color: red;
}
 
.flashNotice {
    border: 1px solid green;
    background-color: #ccffcc;
}

Here’s what the error page above looks like with that crude CSS applied to it. Note that not only is the error explanation styled, but that the fields that are in error are outlined in red:

The sign up form showing some simple CSS attributes applied to error messages and error fields.

The sign up form showing some simple CSS attributes applied to error messages and error fields.

Extra Credit

  1. You’ve already seen that you can easily have a default layout for the entire application. Watch Railscasts #7 - All About Layouts to learn about default layouts for any view in a particular controller and about how to override the default layout when you want something different for certain actions or even dynamically decide which layout to use.

Saving Database Space through Bit-masking

This is a trick you can use to increase the efficiency and readability of your project. It is an argument for good up front design as utilizing this is only plausible when you take the time and effort at the beginning. The following is a real world example from my game TerraTanks.

The problem is that you have an object with a ton of properties that are incredibly similar and they describe the object in a yes|no fashion. In my case, players can do 24 types of research and the state of the player is “yes, I have done that particular research” or “no, I have not done that research”.

One solution is to make a table with a column that associates with the player id and a boolean column for every type of research that you have. Now if you have 24 types of research your table is 25 columns big. This can get out of hand pretty quickly. The table becomes hard to read and you have to use different code (or procedurally dynamic code) to set individual columns.

Another solution is to add a column to your player definition table and make it type INT UNSIGNED. Then you let your code efficiently handle interpreting the integer as the player’s research definition through bit masking. Here’s how it works.

The maximum value of an unsigned INT in MySQL is 4294967295. In binary this number looks like 11111111111111111111111111111111. That is 32 1’s in a row. Each of those digits can describe a research type as ‘have’ (it is a 1) or ‘have not’ (it is a 0). Now in a global file for your code you need to define each research type as a number that is a power of 2. It would look something like this in PHP:

$g_shield_research = 1;              // in binary 001
$g_armor_piercing_research = 2;  // in binary 010
$g_mining_research = 4;             // in binary 100

Now if you want to know whether you have a particular research you would perform a bitmask operation on the integer you retrieve from your database using the & operator.

// will mask players research and return true if the mining bit is set to 1
if ($element->research & $g_mining_research)

The bit masking procedure is extremely efficient and fast and you can see how it compresses all the research information into the size of an integer. Also, if you want to know everything about a player’s research you only have to retrieve a single integer from the database.

Assigning research to a player is also very easy. Simply bitwise OR the current research integer with the set bitmask using the | operator:

$newPlayerResearch = $element->research | $g_shield_research;

You can technically add the two numbers to get the same result, but this is unsafe because if you add the research when it is already there it will throw everything off.

There are some pitfalls to using this trick. While it is easy to add another type of research just by assigning its mask to the next highest power of 2, you are limited to 32 total research types. One way to get around this is to make the column type BIGINT which would give you 64 bits to work with, but at the end of the day you are still limited. Also, once a game starts the research you choose for that bit position is pretty much stuck there unless you want to do some math maintenance.

While this trick will tend to make your code more readable because database statements won’t be as long, your database entry will not be human readable so it could slow down your debugging efforts.

So there you have it. A very powerful tool if used wisely. Please design well before you start writing code. It makes life easier.

Thursday, September 4th, 2008 SQL, database, optimization, php 4 Comments

Making Your Forms Auto-Focus (Ruby on Rails)

Introduction

This covers the same material as this entry from Building Browsergames: Making Your Forms Auto-Focus

Why Do We Have To Do Anything Different?

The advice is excellent and it works perfectly, but it has to be tweaked ever so slightly for Rails. Rails actually generates your form fields for you and names them itself in order to easily copy an object into the fields when populating a form and then make a new object out of the form inputs afterward. As a result, the form_for command you see in a page like app/views/users/new.html.erb:

<% form_for :user, :url => users_path do |f| -%>
  <p><%= label_tag 'login' %><br/>
  <%= f.text_field :login %></p>
 
  <p><%= label_tag 'email' %><br/>
  <%= f.text_field :email %></p>
 
  <p><%= label_tag 'password' %><br/>
  <%= f.password_field :password %></p>
 
  <p><%= label_tag 'password_confirmation', 'Confirm Password' %><br/>
  <%= f.password_field :password_confirmation %></p>
 
  <p><%= submit_tag 'Sign up' %></p>
<% end -%>

Generates HTML that looks like this:

<form action="/users" method="post">
  <div style="margin:0;padding:0"><input name="authenticity_token" 
type="hidden" value="41adf13eec9e99506a55c427ce59052a5543cf70" /></div>
  <p><label for="login">Login</label><br/>
  <input id="user_login" name="user[login]" size="30" type="text" /></p>
 
  <p><label for="email">Email</label><br/>
  <input id="user_email" name="user[email]" size="30" type="text" /></p>
 
  <p><label for="password">Password</label><br/>
  <input id="user_password" name="user[password]" size="30" type="password" /></p>
 
  <p><label for="password_confirmation">Confirm Password</label><br/>
  <input id="user_password_confirmation" name="user[password_confirmation]" size="30" type="password" /></p>
 
  <p><input name="commit" type="submit" value="Sign up" /></p>
</form>

So when we write our JavaScript, we need to make sure it specifies the correct element ID for the HTML that will actually be generated by Rails:

<script type="text/javascript">
window.onload = function() {
  document.getElementById('user_login').focus();
}
</script>

user_login is the name of the field that Rails will generate for login input in our case. If you aren’t sure of the name that will be used, just go to the page in your browser and view the page source. You can see the actual label used there.

Extra Credit

  1. Line #3 of the HTML code above features an “authenticity_token” that Rails inserted automatically for us. Find out what it does and why you want it.

Wednesday, September 3rd, 2008 buildingbrowsergames, code, rubyonrails, tutorial 2 Comments

Making Your Forms Remember Their Values (Ruby on Rails)

Introduction

This entry is based on an entry of the same name from Building Browsergames: Making Your Forms Remember Their Values

I Think We’re Already There

You may have noticed from our existing forms that it was remembering things like the login and feeding it back to the form automatically whenever there was an error. That’s because form_for in your view can take an object you created in the controller and use it to fill in the various fields as it builds them for the HTML. Likewise, when a form gets submitted, it automatically takes those fields and puts them into a Ruby hash which can be directly assigned to a new object to initialize it. That natural flow from controller to view and back to another controller when the user submits makes it easy to have forms “remember” their previous values whenever an error occurs or whenever they need to edit an existing record in the database.

<% form_for :user, :url => users_path do |f| -%>
  <p><%= label_tag 'login' %><br/>
  <%= f.text_field :login %></p>
 
  <p><%= label_tag 'email' %><br/>
  <%= f.text_field :email %></p>
 
  <p><%= label_tag 'password' %><br/>
  <%= f.password_field :password %></p>
 
  <p><%= label_tag 'password_confirmation', 'Confirm Password' %><br/>
  <%= f.password_field :password_confirmation %></p>
 
  <p><%= submit_tag 'Sign up' %></p>
<% end -%>

Simply by specifying the text field as “f.text_field :login” pulls the username from @user (which was supplied by the new function in app/controllers/users_controller.rb) and if there is any value on @user for that field then it is used to fill in the field as the page is built. You don’t have to do any of this yourself. Just learn and follow the standard Rails conventions for these things and it will handle the rest automatically.

If you’d like to see it in action, start entering in some intentionally wrong values into the sign up form and submit it. What you will see is how you get bounced in a loop between the new and create functions in the UsersController (app/controllers/users_controller.rb) and the app/views/users/new.html.erb. As you do so, even though it is may be erroneous, what you enter in for login and email will be preserved between one submission and the next and filled back into the form for you to correct and submit again (though Rails is noticing that the destination fields are password fields and it doesn’t fill those in for security reasons).

Extra Credit

  1. Dizzy offers several excellent one page cheatsheets you can print out for quick reference on the topics of forms, migrations, and ActionMailer. You might want to download the PDF for the FormHelper cheatsheet and print it out for quick reference.

Tuesday, September 2nd, 2008 buildingbrowsergames, code, rubyonrails, tutorial No Comments

Getting Started With A Templating System (Ruby on Rails)

Introduction

This entry is based on the Building Browsergames entry: Getting Started With A Templating System (PHP)

Since we’re using Ruby on Rails, we’re don’t have to select a templating system, there’s one already built into Rails itself. It offers many different features to make it easy to build web pages out of parts, cache parts of pages or whole pages, etc. As with most (probably all) parts of Rails, alternatives are available to what’s built in but you’ll be satisfied with what’s already there for quite a while.

I particularly want to amplify something Luke said in the original posting. He thought a lot of developers were fans of developing their own templating systems. Wow. If that is in fact true, then you are seriously misguided if you go down that path. What’s built into Rails and the Smarty templating system Luke used for his PHP work is more than enough to get your pages done. Do not waste your time on side projects like building a templating system, use the time to improve your overall programming skills or build your game. If you do, you might be one of the few percent who actually finishes a project and others get to play it.

Using Rails Views

The design of Rails is already about separating the view which builds our HTML from the controller which connects the model to the view. So displaying the user’s name in the view is as simple as adding some code like the following to the already existing app/views/welcome/index.html.erb:

<%= render :partial => 'users/user_bar' %>
 
<% if flash[:notice] %>
  <%= h flash[:notice] %>
<% end %>
 
<h1>Welcome To The Game</h1>
 
<% if logged_in? %>
  <p>Hello, <%= @current_user.login %>!</p>
<% end %>

It’s the same as it was before except that we’ve added the section at the end that checks to see if we’re logged in and greets us if we are. Now, as long as the controller method that is called for this page sets up a @current_user variable the view will pull the login out of it and display it within the page. The restful_authentication plugin provides us with an easy to use function to check if the user is logged in or not and put the user’s info into the @current_user variable if he/she is. We’ll call that from our controller (app/controllers/welcome_controller.rb) in the index function (remember, the flow of a user’s page request always goes to the controller first to set everything up and then to the view from there).

def index
  current_user
end

If you recall from before, the old index method didn’t do anything. Now it calls the function which will fill in the @current_user variable before the index.html.erb file gets used to generate the view. At this point if you login you should find that everything works nicely.

By this point we’ve seen that the templating code (in the .html.erb files) gives us the ability to include partials pages to reuse sections of HTML, pull data from variables, and even conditionally show or not show parts of the page.

Extra Credit

  1. To learn more about the functions that restful_authentication makes available to you, look in the file lib/authenticated_system.rb. There are several functions in there to help you determine whether or not the user is logged in, restrict pages from users who aren’t yet logged in, etc.

About

Building Browsergames is a blog about browsergames(also known as PBBG's). It's geared towards the beginner to intermediate developer who has an interest in building their own browsergame.

Write for us!

Have you built a browsergame before, or do you have an opinion to share on the subject? Send an e-mail to buildingbrowsergames@gmail.com!