The Game Plan: Getting Started

Leave a comment Standard

Your game design can run fairly smoothly or it can be a continuous cesspool of hardships and setbacks and pain points. In the next few series of posts I’m going to try and help walk you through the process of getting your game up and off the ground, from what you’re envisioning in your head to an actual working version. So, let’s get started.

1. Get It Out Of Your Head

It’s time you pull out a pencil, pen, or open your laptop to a writing program. First thing’s first, you have to get your game out of your head. Write it down and put it somewhere you can reference it later.

2. Writer’s Block

So if you’ve opened a text editor or you have a pen in your hand you’ve successfully completed step one. Now, what do you write? I like to start with the five W’s:

Whom?

  • Does your game appeal to a specific age range or interest group or gender or even ethnic background?
  • Will you have a large audience your game will appeal to or a small audience?
  • What are the benefits and downsides of the audience you’ve identified?

What?

  • What kind of game are you trying to make?
  • What programming language best suits this kind of game?
  • Does it fit into a specific genre of game or does it span multiple genres?
  • Does it embody a completely new genre?
  • Can you find other games that are similar to the game you are trying to make? If so, what do these games do well and where do fall short?
  • Are there lots of other games on the market similar to the type of game you’re trying to make?
  • What will your charge for your game?
  • What do other, similar games of this type charge?
  • What are the benefits and downsides of the type of game you’re trying to make?

Where?

  • Where does your game take place?
  • What kind of maps or features or environment are unique to your game?
  • What are the benefits and downsides of where your game takes place?

When?

  • When will you have time to work on this game?
  • When can you start this game?
  • When can you fund the development of this game?
  • What are the benefits and downsides of developing this game?

Why?

  • Why are you making this game?
  • Why is your game unique?
  • Why will your game stand out from the crowd?
  • Why will people choose to play your game over other similar games?
  • Why will people pay for your game?
  • What are the benefits and downsides of making this game?

3. Make A Design Document

Your design document is a refined version of everything you’ve written down in step 2. Go back and really analyze what your goals for the game are and if what you’ve written down makes sense in the larger picture. Sometimes a good idea you have for one area of the game will conflict or make another part of the game tedious, uninspired or downright frustrating. For a game design document I like to use the following format:

  1. Intro
    • What is the vision for your game and a short description of how the game is played
  2. Audience, Platform & Marketing Strategies
    • Who the game is for, what platforms you’re making it for and what sets your game apart that will make it marketable and different from others
  3. Core Gameplay & Mechanics
    • How the game is played including physics, rules and limitations
  4. Characters
    • What characters are in your game including what they look like, their names and backgrounds and personalities
  5. Story, Themes & Twists
    • If your game has an overarching story then you’ll outline your plot and how the game progresses with the story line
  6. World
    • Describe the world your game is set in, including maps and locations and their purpose or importance
  7. Assets
    • All the different images, music, animations, etc that you will need to have a fully functional game
  8. Technical Specs
    • What language you’re using, how games are loaded/saved, where games are stored, the number of servers you’ll need and anything else relating to the technical setup of your game
  9. Interface
    • What the game interface looks like and how the player will interact with it
  10. Outside References
    • Articles, links, design inspriations, or anything else that you’re using as a reference for the game you’re making
  11. Appendix
    • Code style guidelines, dictionary of terms, and anything else that is important for understanding your design document that may not necessarily relate to your game directly

Once you’ve fully fleshed out your game design by going into depth about the features, physics, economy, weapons, characters and how the game works it’s time to break it down. Start by creating lots of of small, easy tasks you can accomplish in order to see your core game mechanics to completion enough that you could play a simple version of your game without any extra bells and whistles. Set yourself up to do as little as you have to but as much as you need to in order to get a really simplified, yet completed, version of your game.

How To Get People To Play Your Game

Comments 2 Standard

I’ve learned a lot in the almost 15 years I’ve been running online games. Sure, I can tell you all the different marketing strategies you usually see articles for that show you how to spam your game in every social network and paid advertising service known to man, but that’s not what this post is all about. There’s a difference between getting people to KNOW about your game and getting people to PLAY your game.

Know Your Target Audience

First and foremost you need to know your audience. Who does your game appeal to? If you’re advertising your game for 30+ year old men but the only people who’ve played it so far are young  teenage girls then advertising it on a Cars Automotive Forum is just a waste of your time. If your game is brand new and you’re not sure of your target audience then you can do some playtesting to get feedback on who it appeals to the most. You can also try asking a variety of friend and family to play if playtesting isn’t an option for you — this will give you a varied pool of ages and computer skill levels to draw some basic conclusions from.

Advertise To Your Target Audience

If you’re looking for children to play your game and all of your advertisements/branding/banners/phrases use large vocabulary words and dense/visually busy/highly realistic/dark images then you’re already setting yourself up for increased headaches and hair pulling. If you don’t know much about your target audience then it’s time to stop and do some research. What appeals to children is completely different from what appeals to adults or teenages just like what appeals to women is different from what appeals to men.

Add Lots Of Variety

If you go the pay for advertising route, or even if you self-promote your game in forums/social networks you need to vary how you advertise. By this I mean use both different graphics and wording and in what you’re posting. You’ll quickly find out which advertisements and wording works better than others. If you always have one static saying and image that you’re spamming around the internet it will fade into the background noise. Try animated banners and static banners, bright colors and dull colors, varying text sizes and text amounts. If you post just one banner/phrase and it doesn’t attract people then don’t keep posting the same banner/phrase. One thing I like to tell people is the definition of stupidity — doing the same thing over and over again and expecting a different result. If you don’t mix things up you won’t get a different outcome.

Make It Easy

By this I mean you want your game to be easy to find, install, run and start playing. If someone clicks on your website and they now have to wade through 15 different links that are randomly dispersed through an already text-heavy blog post to find the link to get to your game download page then you’ve already lost customers before they’ve even started. Have your download or embedded game front and center. Make it easy to download or join — the fewer fields and steps they have to complete to start playing the faster they’ll become engaged and access to the experience they were looking for.

Teach Them How To Play

It’s hard to play if you can’t figure out how the game works or which buttons you need to press to get things started. Make access to instructions or a tutorial just as easy as it was to find and launch your game and keep your instructions appropriate for your target audience. Children need instructions with fewer, easier to follow with less text than adults do. Don’t shoot yourself in the foot by writing instructions or a tutorial that they can’t follow or don’t understand.

Start Playing As Soon As Possible

Instructions and a tutorial are great but they can also be tedious and time consuming. Keep them short and to the point, or intersperse brief tutorials/instructions that are introduced progressively throughout gameplay. The longer your target audience has to wade through learning how to play the less likely they are to start playing and stick with it.

Control, Control, Control

If your target audience has made it past your tutorial or instructions and they’re playing there’s one other thing that can really bring everything to an abrupt stop and that’s having difficulty interacting with the game. If your controls are too sensitive or your combinations are too tricky or are too fast for them to accomplish in the amount of time you’re giving them you’ll find that their interest drops off like an air-conditioner falling out of a window. I’m not saying your controls can’t have a learning curve, just that it should be a fairly short one or even a progressive one where you start off simple and add more and more complexity as you go.

Make It Fun

So you can do all of these things I’ve mentioned and people still don’t play your game because they don’t think it’s fun. I could go on and on about this topic and in fact I already have if you’re interested in reading about it so I won’t drag on about it here and now. If people don’t think your game is fun then it doesn’t matter if you’ve hit the mark on all the other points you’ll still find yourself back to the drawing board. So I hope this helps you in your endeavors to get people playing your game because in my experience if you can master these points here you’re well on your way down the path to success.

 

Why Making A Game Takes the Fun Out of It (and how to fix this)

Comments 4 Standard

I see it all the time, people coming into forums and online communities for games and game developers asking how to make a game or how to get their ultra cool idea that everyone will love and has never been done before off the ground and make it a tangible reality. Let’s get things straight, we love games because they’re fun and entertaining. It drives our creative vision and imagination and offers an escape from the mundane and the boring reality that is our lives. This passion, this drive to express ourselves and have fun is often what leads people to try their hand at making their own games. Many will start this journey but very few will finish it and even fewer will finish it with a successful and positive outcome (and let’s face it, money in your pockets). So why does this happen? Why do so many people start down this path of learning and creativity and adventure for fun that ends up leaving them broken, frustrated and depressed? The reality is that games are a lot of work and the very nature of making a game isn’t even a little bit fun. In many ways it’s the exact opposite of what we’re trying to achieve. So how does this happen and what can we do to fix it? Let’s break it down from the point of view of an Indie game developer whose a one man shop (or small shop) trying to make a game.

Lack of skills

You want to make a game but you’ve never programmed before, you don’t know anything about what’s required to make the type of game you want to create and even if you have those things covered you may not have all the skills you need to make it happen. Just because you can program doesn’t mean you can draw or compose artwork or market your finished product if you ever get that far. As an indie game developer you really have to be a jack of all trades. Think about trying to build a house if you’ve never built a house before. What happens if you only know how to frame the house but not how to do plumbing and electrical and tile work and all the other things that are required to finish the house? You end up with just the shell of a house that is lacking in so many ways you can hardly call it a house. This is one of the biggest problems I see with indie game devs — they lack the skills to accomplish what they’ve set out to do and they’re not prepared to outsource when they need to, which brings me to my next point.

Budget constraints

Making games is inherently expensive. Even if you create your own game framework and develop your own models/artwork, sounds and music you still have to — at a minimum — invest in a computer and dedicate hundreds of hours towards the development of your game. Those hours add up and while you’re developing your game you’re not earning a living that you need to support yourself and/or your family. Yes, that’s right, you still need to eat and buy necessities and support yourself and/or your family which is why even if you do have the funds outsource some of the work you lack the skills for you’re still fighting a losing battle towards my next point.

Time constraints and distractions

Supporting yourself and your family means that you’ll still need a full time job even as you chase the ethereal dream of creating your own game. Your time is precious and what little of it you have left after your regular day job has to be split between your other financial and personal commitments. Your kids need their parents and your house and car need to be maintained and you’ll struggle to find the proper work/life balance amidst all of the chaos that you juggle on a daily basis without adding the complexities of your game into the mix.

Technical problems, bugs, new frameworks and advances

So even if you can overcome all these odds so far you’ll still find yourself stuck hitting roadblocks as your game progresses. Technical problems you didn’t predict or forsee early on (and how could you, you’re still just learning yourself) end up being the bane of your game’s existence. Now you have to go back and re-write and re-factor and debug until you’re so frustrated you could pull all of your hair out and go bald. New frameworks and technological advances will make your second guess yourself or roll back to square one because you really do want to upgrade your SDK and add in the new dynamic system and better bump map texturing because who doesn’t want their game to be using the newest, latest and greatest technology available? No one wants to play a game that doesn’t have the same bells and whistles that their competition does because they took the the extra time/budget/testing cycle hits to go with the greater tech.

Slow progress and scope creep

Ultimately these things combined will drag your game down. What may have started off well and progressing quickly has suddenly slowed to a snail’s pace. Things suddenly feel like they’re never getting done or you have so many issues on your plate that it feels like there’s never an end in sight. Your game has hit a standstill and isn’t advancing like it was in the beginning and this is awfully discouraging and frustrating. The scope of your project has suddenly tripled and your todo list is a never-ending tally of bug fixes and re-factors and speed optimizations that need to be addressed for any chances of your game seeming like it’s something worth playing.

Early demo failures and monotonous repetition

If you’ve made it far enough to put together early demos and alpha access then pat yourself on the back — most people will never make it this far and you’ve just become a member of an elite club that deserves a badge of honor. The only problem is your demo gets horrible reviews, you realize your controls are too hard to use and this puts you into a crazy monotonous cycle of playing a particular part of your game over and over again as you attempt to fine tune it and make it more playable and more fun.

Never good enough

Unfortunately the truth is that your game will never be good enough. Someone will always find something to complain about even if you see some great feedback and helpful critiques that, if implemented, could really take your game to the next level and set you apart from your competition. Your controls will never be 100% perfect, your menu system may be too hard to read or too complex to navigate and you’ll never quash all the bugs that have been reported partly because you can’t re-create them all because your game is being run and tested under hundreds of different environments and hardware and operating systems that you didn’t have access to (and probably never will) as you were developing. If you’ve made it here this might just be the time for you to throw in the towel and say goodbye to all the blood, sweat and tears you succumbed to in order to make it this far.

Overcoming It All

If this has discouraged you against making your own game — good. Making a game isn’t easy and it’s not something for everyone so don’t waste your time early on if you’re not prepared to go through everything I’ve already mentioned and be able to walk away without anything to show for it. However that doesn’t mean you shouldn’t make a game or that it’s impossible to do it either. Where there is a will there’s a way and let me show you how.

  • Map out your game design, features, characters and how the game works. Now create lots of small, easy tasks you can accomplish in order to see your core game mechanics to completion enough that you could play a simple version of your game without any extra bells and whistles. Set yourself up to do as little as you have to but as much as you need to in order to get a completed version of your game.
  • If you lack the skill to do something you have two options. The first is that you resign yourself to taking the time to learn this new skill and the next is that you can outsource the skill to someone who’s already achieved it. You don’t have to be an expert programmer to make a game, just an adequate one. If you’re going to invest time into learning a new skill don’t dwell on it for too long, learn enough that you feel confident you can accomplish the task at hand and then move on. Investing too much time in learning a skill will start you down a path that walks further and further away from working on your game.
  • Sit down and map out all of the expenses you foresee as being necessary to complete your game. Now triple it. If you can’t afford to spend this amount of money into your game then you need to go back to your concept and re-work it until you get a budget that you can work with. If you’re really determined you can look for some outside investors but don’t count on this — ever. Most investors want to see a fully working demo before they’ll even consider opening their pocketbooks and investors will demand more than 50% of whatever profits you make from your game when it’s done.
  • Your time is precious when you have so little of it to devote to your game. Start by mapping out a timeline of your game features/assets and how long you think it will take you to accomplish them. Now double that. Now compare that to how much free time you really have to devote to your game. Will this game take you more than a year to complete? Do you have the dedication to spend more than a year working on a single project? If the answer is no then you need to go back to the drawing board until you’ve come up with a reasonable timeline that you can work with. Keep your game as small as you possibly can by focusing on the core mechanics and leaving out any fluff that you could add at a later date. Now stick to your timeline. If you budget 2 weeks to work on a character and by the end of the second week the character isn’t done don’t dwell on it — either move on to the next item in your list. Don’t adjust your timeline and don’t spend more time that you budgeted on this part of it. Sure, your ultimate goal is to have a working character with great animation but if you can’t ever get a game working with a broken character then who cares if your character’s animation is jerky or unrealistic? Think about the big picture because you can always circle back later.
  • Invest in a good debugger and testing tools. Do whatever you can to automate this process as much as possible because it will give you more time to work on trivial issues when you can quickly address and fix the larger ones. If you run into a bug that makes your game do something funky but it doesn’t prevent the gameplay from continuing table it and work on something else. Try not to get caught up in the more minute issues and focus more on the big picture. You can always circle back and fix bugs later but if you spend all your time bug quashing you’ll end up with a pretty interface or character or scene that doesn’t let interact and play with it. Pick a version of a framework and stick with it, don’t upgrade it unless you absolutely have to. The more you upgrade and update to the latest and greatest the more issues you’ll run into and the more refactoring and scope creep you’ll run into. It’s okay to build a game that isn’t using the latest and greatest version of your frameworks or 3rd party integrations. This will also give you a chance to work with and around the quirks in the version of the framework/software you chose to use instead of having to re-work around these every time you upgrade and re-factor.
  • Get the core mechanics working version of your game finished as early as possible no matter what it looks like or how bad it is. A crappy, ugly, glitching yet working version of your game is better than a pretty, perfectionist, bug free version of your game that isn’t at all playable. Don’t wait until the last minute or the week before it opens to get feedback on what you’re doing. Feedback is a great way to find issues you hadn’t considered and it will give you an idea of what other people think about your game. After all, no one wants to play a game they don’t think is fun. Don’t ignore constructive criticism even if it’s not what you want to hear. That doesn’t mean you have to change or add anything anyone has ever asked you for — it means that you need to take those things into consideration going forward. See past the reviews that focus on your aesthetics — at least initially — because you can always change and fix those later, core mechanics and gameplay are much harder to tackle once you’ve invested lots of time and energy into them.
  • Your game will NEVER be perfect. You will always be tweaking, adding, adjusting and fine tuning it. Instead of wasting your time doing this early on and ending up with something that isn’t a viable product devote that time to your game after you have something you can put out there. Don’t be a perfectionist, no matter how many bugs you quash and features you add or tweak there will always be another bug or problem coming down the pipeline. Try to prioritize the most important ones and tackle those first. Ultimately you want to get something up and working no matter how good or bad it is and then build upon it from there. Rome wasn’t built in a day so don’t expect your game to be. Get a working version up first and foremost and then add on to it and enhance it over time, your customer base won’t hate you for that, rather the opposite — they’ll appreciate your continued efforts to improve upon what you’ve done so far.

PHP Tutorial: Run Multiple Tic-Tac-Toe Game Instances (no database required)

Leave a comment Standard

Someone asked me about this in a comment recently so this post is specifically for you but I’m sure there are other people who will benefit from it as well. If you haven’t read the tic-tac-toe game tutorial yet then you’ll need to start there. This tutorial assumes you’ve already completed that and now you want to run two or more tic-tac-toe boards on the page simultaneously.

Or if you want to skip this tutorial you can
download the source code or try the working example

Concepts

The neat thing about classes is that you can use them to create multiple instances with varying states and data even though they all have the same methods and properties. Think about a monster RPG game. Each monster has a different name and breed and picture and strength — but they all have those things in common even though the values are different. Our tic tac toe class works the same way, we can create multiple instances of the game and they’ll each have different states — whose turn it is, which places on the board are filled — but they’ll all work the same way. In order to run multiple instances of our tic tac toe games we’re going to have to update our games so they can be uniquely identified by an instance number. The reason for this is so that when you play the game on instance 1 we know you want to update the state of instance 1 when you submit the form. If we didn’t give each game it’s own instance identifier then every time you made a move on one board it would reflect that move on all instances of the board at the same time.

Creating The Instance Form

Let’s change our index file so that we’re allowing the user to choose how many instances of the game they want to play. We start by removing where we created a new game from the top of the file. Since we want multiple instances we need to create the new game for every instance we have and since we don’t know how many instances we have at this point it needs to move down in our code base. Now once the user has selected how many instances of the game they want to play we need to dynamically generate that many. Using a for loop we loop through the number of instances they selected and create a game for each of those instances in our new $_SESSION[‘game’] array. Before this was only a single game, making it an array means we now have multiple games in our game session variable. Finally we create a new game instance and tell it to start playing. This is what our new index file looks like.

<?php
/***
* File: index.php
* Author: design1online.com, LLC
* Created: 4.6.2015
* License: Public GNU
* Description: PHP/MySQL Version of 2 Player Tic Tac Toe
* that allows playing multiple instances of the game at the same time
***/
require_once('oop/class.game.php');
require_once('oop/class.tictactoe.php');

//this will store their information as they refresh the page
session_start();

define('MAX_INSTANCES', 5); //the maximum number of games they can play at the same time

//trying to set number of instances to play
if (isset($_POST['instances'])) {
 if (is_numeric($_POST['instances']) && $_POST['instances'] > 0) {
 $_SESSION['instances'] = $_POST['instances'];
 }
}

?>
<html>
 <head>
 <title>Tic Tac Toe - Multiple Instances</title>
 <link rel="stylesheet" type="text/css" href="inc/style.css" />
 </head>
 <body>
 <div id="content">
 <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
 <h2>Let's Play Tic Tac Toe!</h2>
 <?php
 //we need to know how many instances to create
 if (!isset($_SESSION['instances'])) {
 ?>
 <p>How many games would you like to instantiate?</p>
 <select name="instances">
 <?php
 for ($i = 1; $i <= MAX_INSTANCES; $i++) {
 echo "<option value=\"$i\">$i</option>";
 }
 ?>
 </select>
 <input type="submit" name="submit" value="Let Me Play!" />
 <?php
 } else {
 echo "<table width=\"100%\">
 <tr>";
 
 for ($i = 1; $i <= $_SESSION['instances']; $i++) {
 
 //if they haven't started a game yet let's load one
 if (!isset($_SESSION['game'][$i]['tictactoe'])) {
 $_SESSION['game'][$i]['tictactoe'] = new tictactoe($i);
 }
 
 echo "<td>";
 
 //play the game passing it the game data for that instance
 $_SESSION['game'][$i]['tictactoe']->playGame($_POST);
 
 echo "</td>";
 }
 
 echo "</tr>
 </table>";
 }
 ?>
 </form>
 </div>
 </body>
</html>

Adding Instances To The Class

The first thing we need to do is add an instance identifier to our tictactoe class. Since we need to know which game the player is trying to play adding a $this->instance value to our class will let us keep track of which game is which. Once that’s done we update our checks for $_POST data to make sure we’re using the correct data for the correct instance. Voila! Our games now only update when they see $_POST data that pertains to them. Our new tictactoe class file looks like this:

<?php
/***
* File: oop/class.tictactoe.php
* Author: design1online.com, LLC
* Created: 1.31.2012
* License: Public GNU
* Description: tic tac toe game
***/

class tictactoe extends game
{
 var $instance = 0; //the instance of this game
 var $player = "X"; //whose turn is
 var $board = array(); //the tic tac toe board
 var $totalMoves = 0; //how many moves have been made so far 

 /**
 * Purpose: default constructor
 * Preconditions: none
 * Postconditions: parent object started
 **/
 function tictactoe($instance)
 {
 /**
 * instantiate the parent game class so this class
 * inherits all of the game class's attributes 
 * and methods
 **/
 $this->instance = $instance;
 game::start();
 
 $this->newBoard();
 }
 
 /**
 * Purpose: start a new tic tac toe game
 * Preconditions: none
 * Postconditions: game is ready to be displayed
 **/
 function newGame()
 {
 //setup the game
 $this->start();
 
 //reset the player
 $this->player = "X";
 $this->totalMoves = 0;
 
 //reset the board
 $this->newBoard();
 }
 
 function newBoard() {
 
 //clear out the board
 $this->board = array();
 
 //create the board
 for ($x = 0; $x <= 2; $x++)
 {
 for ($y = 0; $y <= 2; $y++)
 {
 $this->board[$x][$y] = null;
 }
 }
 }
 
 /**
 * Purpose: run the game until it's tied or someone has won
 * Preconditions: all $_POST content for this game
 * Postconditions: game is in play
 **/
 function playGame($gamedata)
 {
 if (!$this->isOver() && isset($gamedata[$this->instance . 'move'])) {
 $this->move($gamedata);
 }
 
 //player pressed the button to start a new game
 if (isset($gamedata[$this->instance . 'newgame'])) {
 $this->newGame();
 }
 
 //display the game
 $this->displayGame();
 }
 
 /**
 * Purpose: display the game interface
 * Preconditions: none
 * Postconditions: start a game or keep playing the current game
 **/
 function displayGame()
 {
 
 //while the game isn't over
 if (!$this->isOver())
 {
 echo "<div id=\"board\">";
 
 for ($x = 0; $x < 3; $x++)
 {
 for ($y = 0; $y < 3; $y++)
 {
 echo "<div class=\"board_cell\">";
 
 //check to see if that position is already filled
 if ($this->board[$x][$y])
 echo "<img src=\"images/{$this->board[$x][$y]}.jpg\" alt=\"{$this->board[$x][$y]}\" title=\"{$this->board[$x][$y]}\" />";
 else
 {
 //let them choose to put an x or o there
 echo "<select name=\"{$this->instance}_{$x}_{$y}\">
 <option value=\"\"></option>
 <option value=\"{$this->player}\">{$this->player}</option>
 </select>";
 }
 
 echo "</div>";
 }
 
 echo "<div class=\"break\"></div>";
 }
 
 echo "
 <p align=\"center\">
 <input type=\"submit\" name=\"{$this->instance}move\" value=\"Take Turn\" /><br/>
 <b>It's player {$this->player}'s turn.</b></p>
 </div>";
 }
 else
 {
 
 //someone won the game or there was a tie
 if ($this->isOver() != "Tie")
 echo successMsg("Congratulations player " . $this->isOver() . ", you've won the game!");
 else if ($this->isOver() == "Tie")
 echo errorMsg("Whoops! Looks like you've had a tie game. Want to try again?");
 
 echo "<p align=\"center\"><input type=\"submit\" name=\"{$this->instance}newgame\" value=\"New Game\" /></p>";
 }
 }
 
 /**
 * Purpose: trying to place an X or O on the board
 * Preconditions: the position they want to make their move
 * Postconditions: the game data is updated
 **/
 function move($gamedata)
 { 

 if ($this->isOver())
 return;

 //remove duplicate entries on the board 
 $gamedata = array_unique($gamedata);
 
 foreach ($gamedata as $key => $value)
 {
 if ($value == $this->player)
 { 
 //update the board in that position with the player's X or O 
 $coords = explode("_", $key);
 
 //make sure we use the data from the right instance
 if ($coords[0] == $this->instance) {
 $this->board[$coords[1]][$coords[2]] = $this->player;

 //change the turn to the next player
 if ($this->player == "X")
 $this->player = "O";
 else
 $this->player = "X";
 
 $this->totalMoves++;
 }
 }
 }
 
 if ($this->isOver())
 return;
 }
 
 /**
 * Purpose: check for a winner
 * Preconditions: none
 * Postconditions: return the winner if found
 **/
 function isOver()
 {
 //top row
 if ($this->board[0][0] && $this->board[0][0] == $this->board[0][1] && $this->board[0][1] == $this->board[0][2])
 return $this->board[0][0];
 
 //middle row
 if ($this->board[1][0] && $this->board[1][0] == $this->board[1][1] && $this->board[1][1] == $this->board[1][2])
 return $this->board[1][0];
 
 //bottom row
 if ($this->board[2][0] && $this->board[2][0] == $this->board[2][1] && $this->board[2][1] == $this->board[2][2])
 return $this->board[2][0];
 
 //first column
 if ($this->board[0][0] && $this->board[0][0] == $this->board[1][0] && $this->board[1][0] == $this->board[2][0])
 return $this->board[0][0];
 
 //second column
 if ($this->board[0][1] && $this->board[0][1] == $this->board[1][1] && $this->board[1][1] == $this->board[2][1])
 return $this->board[0][1];
 
 //third column
 if ($this->board[0][2] && $this->board[0][2] == $this->board[1][2] && $this->board[1][2] == $this->board[2][2])
 return $this->board[0][2];
 
 //diagonal 1
 if ($this->board[0][0] && $this->board[0][0] == $this->board[1][1] && $this->board[1][1] == $this->board[2][2])
 return $this->board[0][0];
 
 //diagonal 2
 if ($this->board[0][2] && $this->board[0][2] == $this->board[1][1] && $this->board[1][1] == $this->board[2][0])
 return $this->board[0][2];
 
 if ($this->totalMoves >= 9)
 return "Tie";
 }
}

Conclusion

Try the working example! In this tutorial we talked about instances and how you can use a class to dynamically create multiple instances each of which keep track of their own state and values. If you’ve been following my game tutorials then I hope you’re starting to see how powerful classes are and how iterative improvements can be used to enhance your gameplay, functionality and user experience.

How Do I Get Started Making An Online Game?

Leave a comment Standard

This is something I’ve been asked fairly often. If you’re interested in starting your own online game here’s a few things to get you moving in the right direction.

What game are you going to make?

Let’s not put the cart before the horse. Before you can even consider making an online game you need to decide what kind of game you’re going to make. I don’t care if it’s as simple as tic-tac-toe or hangman or as complex as world of warcraft, you’ll need to sit down and put some serious thought into what you want to accomplish before you set yourself to the task. Take some time to write out all of the things you want your game to do (or not do) and create a design document with an easy to follow checklist — this will allow you to check off all the things features and functionality in your game as you work on it.

What programming language are you going to use?

Take a day or two to look at several different programming languages. Which one will make it easiest for you to accomplish all of the goals and tasks you set down in your design document? Choosing the language you’re most familiar with won’t always be the best choice in the grand scheme of things. If you’re not sure which programming language your game is best suited for then try joining a programming forum and getting some honest feedback from senior programmers and developers who can help steer you in the right direction.

Can you afford an online game?

Now that you have a design document and you know what programming language you’re going to use it’s time to get down to facts and figures. How many servers will you need to get your game up and running and what will that cost you? How will you pay for your domain name or any specific software or artwork you’ll need to get your game where you want it to be? Pull up some kind of spreadsheet software and track down the prices for everything you need and add it all up. What will it cost you monthly and yearly? If you’re short on cash you can try to develop via a local machine however this won’t always give you the same experience, environment and the same range of problems as a live setup will. In addition, some programming languages/games require multiple servers in order to work properly so developing locally isn’t always an option.

How long will it take you to develop your online game?

Once you’ve figure out prices it’s time to consider how long it will take you to create your game. This will help you understand what your development costs are before your game is even up and running. There’s no easy way to figure out how long it will take you to make your game, however, you can break up your game design document with estimates (and DEADLINES!!!) on how much time you want to spend on each feature. Try to stick to those and you’ll be more successful in getting your game up and running on a timeline you can afford.

Do you have enough time and money available to dedicate to an online game?

Now you know what it will cost you and you have an idea of how long it will take you to complete your game. This is the make it or break it point. Can you afford the financial burden of getting your game developed and open to the public? What happens if it doesn’t bring in any money? Can you afford sustaining your game (or sadly closing it) if it doesn’t live up to it’s expectations? What happens if you go past your deadline and your game isn’t done yet? What will you do? Do you have enough time to set aside for the development of your game and stick to your deadlines? Will you have time to devote to your game after it’s done to answer emails, manage content, fix bugs and add new features? If the answer to any of these questions is no then you’re not ready to make this game. Shove it in a file — please don’t throw it away and waste your hard work or time — and come back to it again in the future. Go back to the first step and start over again. You can design a new game or the same game over and over again until you can answer every single one of these question with a yes. That means you’re ready to start.

Get setup and start, don’t procrastinate.

When I say you’re ready to start I mean it. Don’t put it aside another second, pull out your wallet to rent some server space or build your local development environment and get started. No excuses. The longer you wait and the more you put it off again and again the less of a chance there is of anything ever getting done. It might be hard and it may take a whole lot of blood, sweat and tears but your efforts will be rewarded with a finished product — whatever that may be.

Start small and simple.

There’s nothing wrong with starting small and keeping things simple. Most working, successful ideas and concepts start out that way. Over time you can refine and re-work the idea until it becomes larger and more complex. Let your game follow the same example. Start with anything on your list that’s simple and you can finish quickly. As you finish these small, simple tasks and features of the game you’ll get a greater feeling of accomplishment and it will encourage you continue to working towards the larger and more complex parts of your game. It will also help you stay focused and stick to your deadlines.

Push through the pain!

When all hope seems lost keep going, don’t stop. Even if your code is horrible or your have hundreds of bugs that you can’t fix don’t let it prevent you from completing your game. Nothing is or ever will be perfect. Instead strive to do a little bit better next time, and a little bit better the time after that. Rome wasn’t built in a day and neither will your game or your programming skills.

If at first you don’t succeed… don’t be afraid to close the game and try again.

So at this point your game should be finished and open to the public. Even if you advertise the heck out of it not every game will be a success or work out quite the way you wanted it to. Some people may laugh at it, criticize the graphics, or even tell you it’s repetitive, boring or it’s all been done before. Don’t let anything stop you from taking everything you’ve learned so far from going back to step one to try, try, try again. Whether you close your game or go through a few more iterations to add new features, fix problems and make it better, it will be GUARANTEED to fail in some way, shape or form. Nothing in life is set in stone — if something doesn’t work change it over and over again until it gets the job done and then exceeds your expectations. Every time you make a game or improve upon an existing one you’ll learn more, become a better programmer and game designer, and take another further step down the path of having the next big hit game on the Internet.

ML Text Based Game: Fantasy Quest

Comments 2 Standard

Haha I just found this old game I wrote in ML for a programming languages class in college. It takes about 20 minutes to play. Maybe it’ll be useful to someone out there?

Code

/*
  First, text descriptions of all the places in
  the game.
*/
description(valley,
  'You find yourself in a pleasant valley, with a trail ahead.').
description(path,
  'You are on a path, with ravines on both sides.').
description(cliff,
  'You are teetering on the edge of a cliff.').
description(fork,
  'There is a fork in the path.').
description(maze(_),
  'You are in a maze of twisty trails, all alike.').
description(gate,
  'You see a large locked gate before you.').
description(dungeon(0),
  'You wake up with an aching head. Finally you manage to look around. You are in a small dungeon 

room. The walls are slimy and damp.').
description(dungeon(1),
  'The wall appears slimy.').
description(dungeon(2),
  'You see a small window above you, but there is little light coming through.').
description(dungeon(3),
  'The sound of water can be heard.').
description(dungeon(4),
  'The wall is slimy to the touch.').
description(dungeondoor, 'A guard walks by and grins at you with broken teeth.').
description(alley1, 'You find yourself in a rotting, fetid alley.').
description(alley2, 'The smell grows fainter. You see shorter buildings and people ahead').
description(town(0), 'You find yourself in town outside of the alley.').
description(town(1), 'You find yourself on a fairly busy street.').
description(town(2), 'A colorful marketplace looms ahead.').
description(town(3), 'You wander past the marketplace and towards the service district').
description(town(4), 'A weaver tries to get you to buy and other hawkers preach about their wares').
description(town(5), 'The streets grow narrow.').
description(town(6), 'A blacksmith sits before his forge. He asks you if you\'ve seen his missing 

horseshoe and offers a reward if you find it.').
description(town(7), 'You can see the alley in the distance ahead of you.').
description(town(8), 'The marketplace is full of many exotic fruits and vegtables').
description(town(9), 'Past the market place houses line the streets.').
description(town(10), 'Houses grow sparce and delaphidated out here.').
description(town(11), 'Small boys play in sewage.').
description(town(12), 'A drunken man staggers towards you. You see the tavern ahead.').
description(town(13), 'You wander out of town and into the countryside.').
description(tavern, 'You enter the tavern you were in last night. The barkeep look as you oddly.').

/*
  report prints the description of your current
  location.
*/
report :-
  at(you,X),
  description(X,Y),
  write(Y), nl.

/*
  These connect predicates establish the map.
  The meaning of connect(X,Dir,Y) is that if you
  are at X and you move in direction Dir, you
  get to Y.  Recognized directions are
  forward, right, and left.
*/
connect(valley,forward,path). %outside of the town
connect(path,right,cliff).
connect(path,left,cliff).
connect(path,forward,fork).
connect(fork,left,maze(0)).
connect(fork,right,gate).
connect(gate,forward,mountaintop).
connect(gate,left,valley).
connect(gate,right,cliff).
connect(maze(0),left,maze(1)). %the maze
connect(maze(1),right,maze(2)).
connect(maze(2),left,fork).
connect(maze(0),right,maze(3)).
connect(maze(_),_,maze(0)).
connect(dungeon(0),forward,dungeon(1)). %the dungeon
connect(dungeon(0),left,dungeon(1)).
connect(dungeon(1),forward,dungeon(2)).
connect(dungeon(1),left,dungeon(2)).
connect(dungeon(2),left,dungeon(3)).
connect(dungeon(3),right,dungeon(2)).
connect(dungeon(3),forward,dungeon(4)).
connect(dungeon(4),forward,dungeondoor).
connect(dungeon(4),right,dungeon(1)).
connect(dungeon(4),left,dungeon(3)).
connect(dungeondoor,forward,alley(1)).
connect(dungeondoor,right,dungeon(4)).
connect(dungeondoor,left,dungeon(4)).
connect(alley(1),forward,alley(2)). %the alley outside the dungeon
connect(alley(2),forward,town(0)).
connect(town(0),right,town(1)). %the town
connect(town(0),forward,town(7)).
connect(town(1),right,town(2)).
connect(town(2),right,town(8)).
connect(town(2),right,town(3)).
connect(town(8),forward,town(9)).
connect(town(8),right,town(2)).
connect(town(8),left,town(2)).
connect(town(9),right,town(12)).
connect(town(10),left,town(10)).
connect(town(12),forward,tavern).
connect(town(12),right,town(9)).
connect(town(12),left,town(9)).
connect(town(10),forward,town(11)).
connect(town(10),right,town(9)).
connect(town(10),left,town(9)).
connect(town(11),right,town(13)).
connect(town(11),forward,town(13)).
connect(town(11),left,town(10)).
connect(town(13),forward,valley).
connect(town(13),right,town(11)).
connect(town(13),left,town(11)).
connect(town(3),forward,town(4)).
connect(town(4),left,town(5)).
connect(town(5),forward,town(6)).
connect(town(6),right,town(7)).
connect(town(7),forward,town(0)).
connect(tavern,forward,town(12)). %tavern always takes you back to
connect(tavern,right,town(12)).   %town no matter where you turn
connect(tavern,left,town(12)).

/*
  Don't move past the gate if its locked
*/
move(Dir) :-
  at(locked, Loc),
  at(you,Loc),
  at(locked, Loc),
  report.

/*
  move(Dir) moves you in direction Dir, then
  prints the description of your new location.
*/
move(Dir) :-
  at(you,Loc),
  connect(Loc,Dir,Next),
  retract(at(you,Loc)),
  assert(at(you,Next)),
  report.

/*
  But if the argument was not a legal direction,
  print an error message and don't move.
*/
move(_) :-
  write('You can\'t go that way.\n'),
  report.

/*
  Shorthand for moves.
*/
forward :- move(forward).
left :- move(left).
right :- move(right).

/*
  Displays a message if there is an item at this location
*/
item :-
  isat(Item, Loc),
  at(you, Loc),
  write('there is '),
  write(Item),
  write(' on the ground!\n'). 

/*
  But if there is no item in the same place,
  nothing happens.
*/
item.

/*
  Picks up the item at that location
*/
pickup :-
  at(you, Loc), /* you are at this location */
  isat(Item, Loc), /* the item is at this location */
  assert(has(you, Item)), /* you pick up the item */
  retractall(isat(Item, Loc)), /* remove this item from that location */
  write('You picked up the '),
  write(Item),
  write('! \n').

/*
  Or there is nothing there
*/
pickup :-
  write('There is nothing here!\n').

/*
  Drop the item you're carrying
*/
drop :-
  at(you, Loc),
  has(you, Item),
  assert(isat(Item, Loc)),
  retract(has(you, Item)),
  write('You dropped the '),
  write(Item),
  write('.\n').

/*
  Or they don't have an item to drop
*/
drop :-
  write('You are not carrying any items!\n').

/*
  You have a sword and the ogre attacks, you kill it!
*/
ogre :-
  at(ogre,Loc),
  at(you,Loc),
  has(you, sword),
  write('An ogre attacks you! You slice off his head just before he can suck your brains out!\n').

/*
  If you and the ogre are at the same place, and
  you don't have a sword then it
  kills you.
*/
ogre :-
  at(ogre,Loc),
  at(you,Loc),
  write('An ogre attacks you and sucks your brain out through '),
  write('your eye sockets. Your body lies broken on the ground.\n'),
  retract(at(you,Loc)),
  assert(at(you,done)).

/*
  But if you and the ogre are not in the same place,
  nothing happens.
*/
ogre.

/*
  They have a coin and are at the dungeon door
*/
guard :-
  at(you, dungeondoor),
  has(you, coin),
  write('"You there!" you yell at the guard.\n'),
  write('The guard\'s smile fades. "What do you want?" comes his grim reply. \n'),
  write('"I think I\'ve found something!" you say, flashing the coin. "Open the door."\n'),
  write('The guard\'s brows furrowed through the slats in the door window. Finally he grumbled '),
  write('and keys jingled as he toyed with his belt. The door opened with a creak and he pushed'),
  write('his bulk through.\n With one hand you '),
  write('punch the guard in the face, knocking him out and escaping the dungeon. \n'),
  move(forward).

/*
  You approach the guard and don't have a coin
*/
guard :-
  at(you, dungeondoor),
  write('"You\'re going to hang tomorrow pig." The guard says, his spitle hitting you in the eye. 

Slowly he moves off. You wonder if he\'s a bit daft and move off.\n\n'),
  move(left).

/*
  Not at the guard, nothing happens.
*/
guard.

/*
  If you have a horseshoe the blacksmith gives you a sword!
*/
blacksmith :-
  at(you, town(6)),
  has(you, horseshoe),
  write('"You found it!" The black smith exclaims when you show him his lost horseshoe. "Here is 

your reward." He hands you a fine crafted sword.\n'),
  retract(has(you, horseshoe)), % he takes the horseshoe back
  assert(has(you, sword)). %you take your reward
/*
  You don't have the horseshoe, the blacksmith says nothing.
*/
blacksmith.

/*
  You have the coin still, and you walk into the tavern and buy a drink
*/
tavern :-
  at(you, tavern),
  has(you, coin),
  write('"Give me a drink." You tell the bartender, ignoring his weary looks, and handing over the 

coin you found in the dungeon.\n'),
  retract(has(you, coin)). % you give him the coin

/*
  You don't have the coin so you leave without a drink.
*/
tavern.

/*
  They walk through the gate with the key
*/

treasure :-
  at(treasure,Loc),
  at(you,Loc),
  has(you, key),
  write('The key you carry is hit by lightening and you die.\n'),
  write('You were so close!\n'),
  retract(at(you,Loc)),
  assert(at(you,done)).
/*
  If you and the treasure are at the same place and they
  don't have a key then they win.
*/
treasure :-
  at(treasure,Loc),
  at(you,Loc),
  write('You find a beaten old chest. Curious you wander over to open it...'),
  write('Colin\'s decapitated head rolls out at you, his eyes empty and staring.\n'),
  retract(at(you,Loc)),
  assert(at(you,done)).
/*
  But if you and the treasure are not in the same
  place, nothing happens.
*/
treasure.

/*
  If you are at the cliff, you fall off and die.
*/
cliff :-
  at(you,cliff),
  write('You fall off and die.\n'),
  retract(at(you,cliff)),
  assert(at(you,done)).
/*
  But if you are not at the cliff nothing happens.
*/
cliff.

/*
  Have the key with you to open the gate
*/
locked :-
  at(locked,Loc),
  at(you,Loc),
  has(you, key),
  retract(at(locked, Loc)), /* unlock the gate */
  write('You unlocked the gate with your key.\n').
/*
 At the gate but don't have a key
*/
locked :-
  at(locked,Loc),
  at(you,Loc),
  write('The gate is locked!\n').
/*
  Not at the gate, nothing happens
*/
locked.

/*
  Main loop.  Stop if player won or lost.
*/
main :-
  at(you,done),
  write('You wake up screaming in bed! Good thing it was all just a dream!!\n').
/*
  Main loop.  Not done, so get a move from the user
  and make it.  Then run all our special behaviors.
  Then repeat.
*/
main :-
  write('\nNext move -- '),
  read(Move),
  call(Move),
  guard,
  blacksmith,
  tavern,
  item,
  ogre,
  treasure,
  cliff,
  locked,
  main.

/*
  This is the starting point for the game.  We
  assert the initial conditions, print an initial
  report, then start the main loop.
*/
go :-
  retractall(at(_,_)), % clean up from previous runs
  retractall(has(_,_)), % remove all items you had before
  retractall(isat(_,_)), % remove empty locations of old items
  assert(at(you,dungeon(0))),
  assert(at(ogre,maze(3))),
  assert(at(treasure,mountaintop)),
  assert(at(locked, gate)),
  assert(at(lockeddoor, dungeondoor)),
  assert(isat(key, path)),
  assert(isat(coin, dungeon(3))),
  assert(isat(horseshoe, town(1))),
  write('\n\n Your name is James Pattern. Last night your friend Colin asked you to the Inn for a 

drink. He talked excitedly of treasure on a mountain top and ogres out to get him. You laugh at him 

good naturedly and think he had a bit too much to drink.\n On your way home later that night you 

hear the scuffling of feet. You spin but see nothing in the dark alley behind you. You continue on 

until something sharp hits you over the head.... You wake up with an aching head and a groan. 

Finally you manage to look around.\n\n'),
  write('WELCOME TO FANTASY QUEST!!!'),
  write('\n\n'),
  write('Legal moves are left, right, forward, pickup, and drop.\n'),
  write('End each move with a period.\n\n'),
  report,
  main.

Explanation

The main loop of this program is located at the very bottom of the script. It starts out by removing all of the locations, item locations, and items the player had on their character before they started playing. Once that has been done it sets up the game by placing all the items and obstacles in the appropriate places. After the game is setup its ready for the user to begin playing. It introduces them to the game by writing text to the screen to detail where the player is.

Legal Moves

Movement: Forward, Left, Right – This moves the character on the game map. To do this, the program first calls the move(Dir) and then checks the game map to see if there are any connections between the player’s current position and a positing direction they are trying to move. If there is a position available it retracts the players old location and asserts their new location to the new position on the map. If a player has entered a movement that is not connected to another part of the map then the game notifies them that they cannot move that direction.

Pickup – This move allows players to pick up items they will encounter as they move through the game map. A player can pick up as many items as they like. Once a player has picked up an item it will remain with them as they navigate the map until they decide to drop it. The pickup code first checks to see if there is an item at the same location the character is located. If there is, the game retracts the item from its location and asserts that the player now has that item in their possession. If the player tries call pickup and there is no item at that location it gives them an error message.

Drop – This allows the players to drop items they have picked up in the game. A player can drop as many items as they have. Once they don’t have any more items it will notify them. However, a player cannot specify which item they mean to pickup or drop. In order to drop an item, the code first checks to see if they have any items. If they have an item it retracts the item as being in their possession and then asserts that the item is now available at the location where it has been dropped. This way if they character was to return to that location at a later time they could again pick up the item.

Item Notification

In order for a player to notice that there are items around the map an item call was put into the code. This checks to see if there are any items at that particular location and then lists any items that it finds. This way the player is notified of the item being available for them to pickup as they play.

Gameplay

You were at the tavern having drinks with a friend. He tells you that he was trying to find treasure but was chased away by an ogre. You have a few drinks with him and then laugh it off and leave. As you’re leaving someone hits you over the head.

Dungeon & Coin – You wake up in a dungeon that is patrolled by a guard. In order to escape from the dungeon you must first find a coin in your cell. Once you have the coin you can go up to the door of the cell. You tell the guard you found something great and flash the coin to catch his interest. He, being a dull witted fellow, falls for it and opens the door. You knock him out and are free.

Blacksmith & Horseshoe – Beyond the dungeon you find yourself in an alley. Outside of the alley you wander back into town. Along the way you stumble upon an expensive looking horseshoe and decide (or not) to pick it up. As you continue around town you’ll find a blacksmith whose looking for a horseshoe he lost and is offering a great reward for it. If you have the horseshoe the blacksmith gives you your reward: a sword. The horseshoe is retracted from your possession and a sword is added to them.

Tavern & Coin – As you continue through town you may eventually wander back into the tavern you met your friend at the night before. If you happen to still have a coin you will buy yourself a drink, otherwise you’ll leave dejectedly.

Gate & Key – As you continue out of town you’ll find yourself in a valley along a path. On the path you will find a key and decide (or not) to pick it up. You will need this key in order to unlock a gate that lies at the base of a mountaintop. Without this key you cannot pass through the gate. However, once the gate is unlocked all is not clear. You must first drop the key before passing through otherwise you’ll be struck by lightning.

Ogre & Sword – Outside of the town you may find yourself stuck in an endless maze. Somewhere hidden in that maze lies an evil ogre waiting to suck your brains out. If you happen to have a sword with you, all is fair and well as you cut off its head before it can touch you. If you weren’t so lucky as to help the blacksmith out you will find yourself dead and buried.

Cliffside – There are other treacherous obstacles outside of the town. If you don’t watch your step you can fall down the cliff and die!

Treasure – Beyond the gate, and the treacherous lightning attracting key you will find the treasure your friend only dreamed about.

Game Over – That’s it! I hope you’ll play!

Pits Of Doom Lesson 10: Member Interaction

Comments 5 Standard

In the last lesson we added the ability to fight monsters on our map and added a graphic library to display our maps and updated the map editor so we can easily customize our maps and how they look from here on out. In this lesson we’ll discuss member interaction, how to build a chat room, and how to display other member’s characters on the map when they’re logged into the game.

Lesson Concepts

No matter what you may think there is no such thing as “real time” as a result of how the Internet works. Let’s take visiting your favorite website for example.

On your computer you open a browser, type in the domain name and hit enter or press the go button. When this happens your computer sends a packet of information out to your Internet connection (or wireless router) and then waits for a response. Your request is passed from place to place until it finds a server that’s waiting and listening for your requests. When the server gets your request it processes it and  sends back a result to your computer. So when you see the google homepage you’ve actually sent a request, the google server has heard your request, generated a response, and then your computer hears the response and displays the information from the google server on your browser screen. This is also why people who have dial up experience slow Internet.

So the question becomes, how do you hide or overcome delays that result from Internet communications? Some features of our Pits of Doom game are inherently perfect for covering up this problem. Take a chat room for instance. When you use a chat room you expect there will be a delay before you get your response. In this case the delay is to some degree expected by the user.

Now take our map. If we see another member on the same map level we don’t expect it to jump from place to place as it moves around. Instead it should seamlessly navigate around the map even if we’re not moving ourselves.

Creating The Chat Room

The concept behind a chat room is simple. Every time someone posts a message we store it to the database. In the chat screen we always select the last few messages inserted into the database. Finally we update the chat display every couple of seconds so it appears as if people are talking simultaneously.

Let’s start by making a table for the chat messages. We’ll need a way to identify which message belongs to which member, a place to store their text, and then the date/time they posted the message to make searching and sorting easier if we ever want to reference a particular day/time in the chat log.

CREATE  TABLE  chatroom (
  id INT NOT  NULL  AUTO_INCREMENT,
  mid INT NOT  NULL,
  message MEDIUMTEXT NOT  NULL,
  date DATETIME NOT  NULL,
  PRIMARY  KEY (id),
  UNIQUE (id)

There are two fields in this table we haven’t talked about before. The first one is mediumtext. This is one of three text options available in MySQL. There’s tinytext, mediumtext, text, and longtext. These store varying amounts of data respectively. For everything we’re doing with this game we’ll only need a mediumtext or a text field type as those are the most common for the amount of data we’re going to store. So the question is, why not always use the text or longtext options? MySQL has to allocate space for the information that would fit in the different sized text fields. By using the smallest one we need we’ll increase our database speeds and cut down on any potentially wasted space.

Implementing The Chat Room

This is a fairly simple process. We have to tie the message box to the chat message submit button. When someone presses the submit button and they have a message we’re going to add that message to the chat table.

How we display the chat messages is a bit more complicated. We have two options:

  1. Use PHP to automatically refresh the screen periodically.
  2. Use Ajax to re-generate the screen without refreshing the whole page (best solution).

Since this is a PHP/MySQL game we’re going to go with the first PHP 0ption so  you don’t have to know any Ajax. If you want the Ajax version you can contact me and purchase it as an addon for $25. Our script to display the most recent chat room messages looks like this:

<?php
/****************
* File: chattext.php
* Date: 6.17.2011
* Author: design1online.com, LLC
* Purpose: display chat text messages
*****************/
require_once('../oop/mysqlobj.php');
require_once('functions.php');
require_once('dbconnect.php');

$MAX_MESSAGES = 25;
$REFRESH_SECONDS = 5;

echo "
<html>
<head>
<meta http-equiv=\"Content-Type\" content=\"text/html\" />
<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/default.css\" />
<meta http-equiv=\"refresh\" content=\"$REFRESH_SECONDS\">
</head>
<body class=\"chat\">";

$loop = mysql_query("
    SELECT
        C.mid,
        M.username,
        C.message,
        C.date
    FROM
        chatroom C
    INNER JOIN members M ON M.id = C.mid
    ORDER BY
        C.id DESC
    LIMIT $MAX_MESSAGES")
    or die ('Cannot load chat room messages ' . mysql_error());

while ($row = mysql_fetch_assoc($loop))
    echo "<span class=\"datetime\">" . date('g:ia', strtotime($row['date'])) . "</span>" . htmlentities($row['username']) . ": " . htmlentities($row['message']) . "<br/>";

echo "</body>
    </html>";

Displaying Other Members

Not only do we want to talk to other members we want to see them on the map. In order to do this we’ll need to check to see if the online flag is set to true. Whenever we login using our login form we automatically set this value to true. The only problem we have now is how to determine if they’re still playing or not.

Therefore we’re going to create a new script called online.php and call it every time someone moves their character around the board. We’ll use this script to automatically logout anyone who hasn’t been active recently and restore the online status to anyone whose currently still playing. So in a nutshell online.php has to do two things:

  1. Remove the online status from any player whose last login is more than 20 minutes ago
  2. Update the member’s last login date to the current date and time any time they interact with the game
/*******
* Check to see if there is another character in this spot
*******/
function hasMember($x, $y, $z, $mapid)
{
    global $_SESSION;

    $result = $_SESSION['database']->query("SELECT M.id FROM characters C
            INNER JOIN members M ON M.id = C.memberid
            WHERE C.active=1 AND M.online=1 AND C.x='$x' AND C.y='$y' and C.z='$z'
            AND C.mapid = '$mapid' LIMIT 1");

    $row = mysql_fetch_assoc($result);

    return $row['id'];
}

Once we’ve established a way to determine which members are still online and which members are currently offline we can modify our displayMap function to show other members currently on the map if there is no monster present. In order to do this we first have to find all active characters (remember they can have more than one character eventually) then check to make sure the owners of those characters are online. Once we know they’re online we can check the character’s coordinates to figure out whether or not they are on a specific map location.

Game Files

This lesson we implemented a chat room, created a script to update whether or not a member is currently logged in and wrapped it up by displaying those member’s characters on our map.

Play The Working Version!

Sign into Pits of Doom using the login below or create an account today! To really see this lesson in action it’s best if you open two different browsers and login to each of them (using the same browser with two windows won’t work!) to see other character’s that are current logged into the game.

Account 1

Account 2

Username: test

Password: test

Username: test2

Password: testing

Download The Source Code

Use the view source utility or download a .zip archive.

Lesson Concepts

Member interaction is a huge part of an online game with any kind of social or interactive quality about it. In pits of doom we’d like to be able to trade/buy weapons and fight other members so it’s important that they be able to communicate and see other characters on the game world. In the next lesson we’ll look at updating our chat room so you can click on another member’s name to view more about their characters and send them private messages.

Go Back to Lesson 9 or Continue to Lesson 11