New Years Resolution: Game Tutorial Series
I realized recently that for a game development blog I don’t have many “games” on here, lol. So my new years resolution for 2012 is to make more open source games available by starting a game tutorial series. In this series I’ll be re-creating some of the classics (hangman, tic-tac-toe, etc) in first MySQL/PHP, then MySQL/PHP with jQuery/AJAX, and finally in Flash AS3. All of the code will be available under the GNU Public license so you can use, edit, and modify it as you see fit.
How Much Does It Cost To Create A Flash MMO?
Are you thinking about making a flash MMO? Want to know what it costs? Then you’re in the right place. I’ve been working on an MMO for the past two years and I thought I would share for anyone who is considering making their own. There are a lot of expenses I didn’t think about or plan for so maybe this will help you budget for your game’s future.
Flash Server
These range from about $500 to over $25,000. The cost depends on if you buy a commercial one, how many users are on the license, and how many developer seats you need. I chose a middle of the line, out of the box, software called SmartFoxServer 2X. It has many of the features I need/want for my flash MMO already built into it therefore saving me development time. It’s about middle of the line in terms of price and has been used successfully by large multiplayer games (Club Penguin, YoVille, PetPet Park). An unlimited user/developer license is a one time fee of $5,500 (and yes, some servers charge yearly fees or a % of profits).
Domain Names
This is probably one of the things you’ll overlook. Many games only buy a .com domain name when in reality you should have multiple variations on the name, .nets, .orgs, and other domain extensions. This helps ensure someone looking for your website can find it. A domain averages about $20 a year per domain and I have 5 of them, so $100 a year in domain names.
Web & Database Servers
While you probably won’t overlook this you certainly won’t plan for as many as you really need. For added speed you should cluster your servers and keep all your databases running on their own, separate server. You want top of the line servers to support the amount of traffic you’ll generate. Expect to pay over $300 a month for every two servers up and running. Some places offer packaged deals so take advantage of that if you can.
Graphic Artists
Unless you’re an artist yourself you’ll have to spend some big bucks to have someone start generating the art for your game. The price of graphics will vary depending on the size, DPI, detail and quality of the artist’s skill. It will also vary depending on how many images and artists you need. For fastest turnout you’ll need at least three or four artists and trying to hire artists with similar graphic styles is a must for a cohesive looking game. Expect to spend at least $5,000 a year per artist, or more if your budget allows.
Animators
Every good flash game needs animated graphics. Not only do you need artists you need animators too. Many of the freelance animators I’ve found are willing to be paid per frames on an animation. Costs per frame vary from $5 – $25 a frame. Expect your animations to have at least 8 or more frames per direction/action. So for a single walk animation, that has 4 different directions (north, south, east, west) you’ll have 4 animations * 8 frames each * $5-25 a frame for a total of $160 – $800 an animation sequence. Chances are your game will have more than one animated character or graphics.
Programmers
Whether your program it yourself or hire someone to do it for you programming is a large part of any game. There are a few tools out there to help if you want a quick “out of the box” type approach like OpenSpace and other game engines but these will cost you a small fortune. OpenSpace runs about $4,500 a license. Hiring a programmer, on the other hand, will cost you anywhere from $25 – $75 an hour and the amount of work they can do depends on their skills, speed, and turn around times. I do most of my own programming for my games but I’ve hired outside programmers for a few smaller pieces to save some time. Expect to pay out at least 4+ hours of work each time you use a freelance programmer at their hourly rate.
Game Designers
If you’re not the brains behind the design of your game then consulting a designer may help your game from “flopping” before hit the market. An experienced game designer can quickly point out obvious flaws in your economy, level/questing/rewards systems, and more. Usually you can find someone on a forum to bounce ideas off of but that also means the potential for Intellectual Property (IP) theft and possibly opening yourself up to outside competition before your game has even hit the market. I would recommend hiring an experienced game designer and having them sign a Non-Disclosure Agreement (NDA) before you give them any access to your game’s inner workings. Expect to shell out a couple hundred bucks for a consult but it’s well worth it.
Level Designers
If you game has multiple levels you may want to consider a level designer, or level design software. This makes it easy to implement new areas of the game and can possibly leave you free to do other things while your level designer slaves away at the more mundane stuff. Even though my game doesn’t have levels this is an expense you may want to consider if yours does. Having customized software developed for your game (or buying some) and/or hiring a level designer is another chunk of change out of your pocket.
Writers
You might have a fighting game but that doesn’t mean you won’t need a writer. Even if it’s things as simple as a user interface (UI), instructions, or start menu or little road signs a writer can help you use language that passes the Flesch Kincaid Readability Test and other readability tests. Did you even know these existed? A writer can also help you check for grammatical errors, succinctness, third person passive voice, and many common writing mistakes. For instance, does your children’s game use words that children in your target age group won’t understand? Hiring a writer to come up with all the text in your game is more expensive than hiring someone to edit it. Expect to pay a few hundred for a writer and prices for an editor vary based on word counts.
Background Music
Sure you can go the Facebook games route and have one background song that drives people nuts because it loops over and over again. Or you could purchase main stream music and/or have music composed specifically for your game. Prices vary drastically depending on your choices here. Custom music typically costs based on the length of the song. Quotes I’ve had for a one minute song are typically over $600 for a full license. Royalty free music costs twice as much as mainstream music and usually has other license limitations that must be followed but once you’ve paid for it it’s yours — even if it’s not unique. Using main stream music means you need to get a license from the BMI or the ASACP. While this might seem like the cheapest option at first (heck you can download a ton of songs for only .99 a piece) it’s also the most expensive ones. The BMI and ASACP charge depending on the number of daily listeners, number of song plays, and whether or not your users can select the song they want to listen to. On top of that they typically take a % fee of your yearly revenues.
Sound Effects
Most people remember the background music and forget the sound effects. A fighting game just isn’t the same without the punching and kicking sounds. While these are small sound files you’ll find that they add up fast. The better quality the sound effect the more it will cost. You may be able to save money by recording your own sound effects but that also means you’ll have to budget for buying sound equipment or paying for some sound studio time. Expect that your sound effects will cost anywhere from $5 – $25 each.
Language Filter Software
If your MMO is geared towards children you may want to consider purchasing language filter software. This may or may not be more expensive than writing your own language filters depending on the nature of your game. Third party language filter software typically specializes in stripping other suggestive/violent language which may also cause problems with children, as well as a bad language filter.
Marketing & Advertising
Most of your budget will probably be spent here. Unless people know about your game there’s no way they’ll visit and try it out. Online advertisement is probably your best bet and your costs will vary depending on what kind of advertising service you use. Pay Per Click (PPC) in my experience yields the best results. Pay Per View (PPV) may be more costly depending on the type of exposure you want your game to receive unless you’re using a fairly high bid on PPC advertising.
Newspaper and magazine advertising is also expensive. Expect to pay as much as $1,500+ for one large ad to run in one issue or as little as $200 a month to run a small (really small!!!) color ad. The cost depends on the magazine you advertise in and how much it’s in circulation. You can typically get a cost break if you decide to advertise in the magazine for the whole year.
TV and Radio advertising is even more expensive than print advertising. The costs are at least double and depends on the length of the commercial you’re running, the time slot it’s running in, and whether or not the station is creating the commercial for you.
Customer Support
Despite your best efforts your game will bring in a slew of emails. If you expect to answer all of these yourself you better have a programmer working for you. Sometimes I receive as many as 80 emails a day. There just aren’t enough hours in the day to answer all your email and program/manage your game. Hiring someone to answer email for you is an easy solution but it will cost you as well.
Payment APIs
While payment APIs like Paypal and 2Checkout are great sources of revenue they also cut into your profits. Expect that any payment API you use to process payments in your game will take 2-5% of each transaction you’re generating. If your game uses micro-transactions make sure you check with your payment API to see if they support specialized plans for such cases — this will save you some money.
SSL Certificates
If you want to seamlessly integrate payment APIs into your game you’ll need to have SSL certificates in place. SSL certificates are a yearly fee and who you purchase them from makes a difference in their safety assurance ratings and encryption levels/techniques. Expect to spend anywhere from $100 – $800 for one of these.
Traffic Reporting
Sure it seems mundane but you’ll want to know how long your members are playing, where they play the most, and how active they are on the website. With a flash game it’s harder to track these things because a lot of the code runs client side. There are several good traffic reporting APIs available for flash software that will save you time of creating something yourself. In addition resources to compute the traffic aren’t done on your servers, freeing them up for your members to use.
Site Maintenance
You might design your game to pretty much run itself but there will always be some type of maintenance involved. While this may not cost you anything if you’re programming the game yourself it also means money out of your pocket while you’re fixing things instead of adding new features, maps, characters, items, quests or events.
JQuery FIX: uncaught exception: Syntax error, unrecognized expression: #
This one threw me for a bit of a loop today so I thought I’d share. I couldn’t get my debugger to give me a line number for this error, however it turns out I had a double # sign in my jQuery code.
<script>
$("##myButton").click(function () { alert('You are pressing my buttons'); });
</script>
Notice the duplicate pound sign (#) in the ID reference for the button. Remove the duplicate pound sign and you should be good to go.
DOJO Grid FIX: Showing/Hiding Grid Causes Grid Headings To Disappear
DOJO has a quirky problem if you try to show/hide grids using Javascript or JQuery. This is especially trying if you have multiple grids on a page and you only want to display one at a time. If your column headers aren’t “fixed” they disappear once you hide the grid and then try to display it again.
The only way around this is to use the .resize() method on the grid reference after you try to show it again. This re-draw the grid with all the columns showing up again.
<script>
$("#showSubGridButton").click(function() {
$("#mainGridContainer").hide();
$("#subGridContainer").show();
refreshGrid(subGrid);
});
$("#showMainGridButton").click(function() {
$("#subGridContainer").hide();
$("#MainGridContainer").show();
refreshGrid(mainGrid);
});
function refreshGrid(gridRef) {
gridRef.resize();
}
</script>
MySQL Workbench FIX: Cannot start SSH tunnel manager error — even when using TCP/IP connections
I recently ran into this problem when I updated to the newest version of Tortoise SVN. This error was happening every time I tried to connect to a server, even if I wasn’t using SSH. So apparently when you update your SVN and it’s one that uses Python it sometimes removes a necessary system environment variable. So there are two potential solutions but only the second one worked for me.
Solution One – Fix the system environment variable
- Go to your start menu and right click on My Computer
- Select properties
- Click on the advanced tab
- Click on the Environment Variables button at the bottom
- In the system variables look for one that says PYTHONHOME
- If you find it, update the path to the location of where you installed workbench, to the python folder. For instance mine is C:\Program Files\MySQL\MySQL Workbench 5.2 CE\python
- If you don’t find it, then you need to add one with a variable name of PYTHONHOME and the path to the python folder in workbench
- Hit OK when you’re done
- Restart your computer
Solution Two – Uninstall and re-install MySQL Workbench
This is the only one that worked for me so I think my SVN changed more than just my system variable. Once I re-installed MySQL Workbench it and SVN were worked without problems.
AS3 Tutorial: How To Put TileList Pictures Beside Label Text
So I wanted to make a chat room list with icons formatted beside it and I thought, why not just use a TileList? It already shows images and scrolls so I’ll save myself some trouble. I thought it would incredibly easy and intuitive to change the layout of how the images/label were being displayed but BOY WAS I WRONG!! So hoping to save you the three days of research I spent trying to figure this out here you go:
1. Create a new as3 flash .fla file. Modify the properties and click on the settings next to where it says Actionscript 3. Uncheck the strict errors and warnings boxes.
2. Click on the components tab in the library and drag the TileList component onto the stage. Do the same for a Label component.
3. Delete the TileList and Label components from the stage. You’ll notice they are still available in your library.
4. Create a new as3 file called myTileList.as and put it in the same location as the as3 .fla file.
5. Find the properties section for the .fla file. Where it says class type in myTileList. This will tell the .fla we want to load this .as file when we compile and then execute our flash file.
6. Create three new movie clip objects called Mod_Icon, Reg_Icon and Speaker_Icon. These are the images that will show up beside the user names in the list. Now take a .png image and put it in an icons folder in the same location as your .fla and .as files. We’ll use this so you can see the difference in how to load external files and how to load display objects. Save your myTileList.fla file.
6. Now we’ll update the myTileList file so that it adds a TileList to the stage so we can do some simple interactions with it. Put this into your myTileList file:
/****
* File: myTileList.as
* Author: design1online.com, LLC
* Date: 9.4.2011
* Purpose: display a list of chat room user
****/
package {
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import fl.controls.Label;
import fl.events.ListEvent;
import fl.controls.TileList;
import fl.controls.ScrollPolicy;
import fl.controls.ScrollBarDirection;
import fl.data.DataProvider;
import UserListRenderer;
public class myTileList extends MovieClip {
//Labels
private var msg_lbl:Label = new Label();
//Lists
private var user_tilelist:TileList = new TileList();
/****
* Purpose: default constructor
* Precondition: none
* Postcondition: build what appears on the stage
**/
public function myTileList()
{
//add the TileList to the stage
user_tilelist.width = 170;
user_tilelist.height = 100;
user_tilelist.move(200, 40);
user_tilelist.columnWidth = 170;
user_tilelist.rowHeight = 30;
user_tilelist.visible = true;
user_tilelist.direction = ScrollBarDirection.VERTICAL;
/**
* this tells the tileList to use our userListRenderer class to
* change the way it displays each item in the list
**/
user_tilelist.setStyle("cellRenderer", UserListRenderer);
//this adds the list to the stage
addChild(user_tilelist);
//add a label to the stage to show what we've selected
msg_lbl.width = 170;
msg_lbl.height = 100;
msg_lbl.x = 200;
msg_lbl.y = 150;
msg_lbl.text = "Select a user above.";
msg_lbl.visible = true;
addChild(msg_lbl);
//Add an event listener
user_tilelist.addEventListener(ListEvent.ITEM_CLICK, clickUserHandler);
//Load the list
loadUserList();
}
/****
* Purpose: draw the users list
* Precondition: none
* Postcondition: user list has been updated
****/
private function loadUserList()
{
var dp_mod:DataProvider = new DataProvider();
var dp_reg:DataProvider = new DataProvider();
var dp_speak:DataProvider = new DataProvider();
var dp_users:DataProvider = new DataProvider();
var users:Array = [{name:"John", privileges:"mod"}, {name:"Amy", privileges:"regular"}, {name:"Lucas", privileges:"reg"}, {name:"Claire", privileges:"speaker"}];
var icon = Reg_Icon;
for (var u:String in users)
{
switch (users[u].privileges)
{
case "mod":
icon = Mod_Icon; //is a moderator using the movie clips we have in the library
dp_mod.addItem( {label: users[u].name, source: icon, data:users[u] });
break;
case "regular":
icon = Reg_Icon; //is a regular member
dp_reg.addItem( {label: users[u].name, source: icon, data:users[u] });
break;
case "reg":
icon = "icons/reg.png"; //you can also use a URL or a relative link to where this image is uploaded
dp_reg.addItem( {label: users[u].name, source: icon, data:users[u] });
break;
case "speaker":
icon = Speaker_Icon; //is a speaker
dp_speak.addItem( {label: users[u].name, source: icon, data:users[u] });
break;
}
}
//sort the lists
dp_reg.sortOn("label", [Array.DESCENDING, Array.NUMERIC, Array.CASEINSENSITIVE]);
dp_mod.sortOn("label", [Array.DESCENDING, Array.NUMERIC, Array.CASEINSENSITIVE]);
dp_speak.sortOn("label", [Array.DESCENDING, Array.NUMERIC, Array.CASEINSENSITIVE]);
//merge the lists
dp_users.merge(dp_mod);
dp_users.merge(dp_speak);
dp_users.merge(dp_reg);
//our final list is sorted by type and user name
user_tilelist.dataProvider = dp_users;
}
private function clickUserHandler(evt:Event)
{
/**
* We have to use evt.rowIndex to get the selected user from the
* TileList because the event fires before the TileList selectedIndex
* has been updated. If you're trying to get an item from the tileList
* and you're not inside one of it's event handlers you would use
* user_tilelist.selectedIndex in place of evt.rowIndex
**/
var selectedUser:Object = user_tilelist.getItemAt(evt.rowIndex).data;
msg_lbl.text = selectedUser.name + " is a " + selectedUser.privileges;
}
}
}
7. Create another as3 .as file and call it UserListRenderer. We’ll use this to change how our TileList looks so the pictures appear beside the label. Put this into your UserListRendererfile:
/****
* File: UserListRenderer.as
* Author: design1online.com, LLC
* Date: 9.4.2011
* Purpose: change the formatting for the user tile list
* so images appear beside the user name
****/
package {
import fl.controls.listClasses.ICellRenderer;
import fl.controls.listClasses.ImageCell;
import fl.controls.TileList;
import flash.text.*;
public class UserListRenderer extends ImageCell implements ICellRenderer {
public var desc:TextField = new TextField();
private var textStyle:TextFormat = new TextFormat();
public function UserListRenderer() {
//inherit the variables from the parent
super();
//we don't want to stretch our images to fit the size of the box
loader.scaleContent = false;
//change the cursor as if this was a button
useHandCursor = true;
//Create and format the text field
//that will appear beside the image
desc.autoSize = TextFieldAutoSize.LEFT;
desc.x = 24;
desc.y = 5;
desc.width = 150;
desc.height = 28;
desc.multiline = false;
desc.wordWrap = false;
addChild(desc);
//apply some styles to our text field
setStyle("imagePadding", 2);
textStyle.font = "Tahoma";
textStyle.color = 0x000000;
textStyle.size = 15;
}
/**
* Now we override the function that draws the layout
* so we can move the image beside the text
**/
override protected function drawLayout():void {
//adjust the icon for any existing padding
var imagePadding:Number = getStyleValue("imagePadding") as Number;
//offset the image in the box so it's not touching the top of it
loader.move(0, 4);
var w:Number = width-(imagePadding*2);
var h:Number = height-(imagePadding*2);
if (loader.width != w && loader.height != h) {
loader.setSize(w,h);
}
//re-draw the image
loader.drawNow();
//hide the original cellImage textField so we can display our new one later
textField.visible = false;
//display the new text box beside our image
desc.text = data.label;
desc.setTextFormat(textStyle);
//adjust the background
background.width = width;
background.height = height;
}
}
}
8. That’s it! You can load images from the stage directly into the tile list or you can load images from an external URL. I’ve created a .zip you can download that shows you how to do it along with figuring out which item is selected, changing labels and images, and sorting the list.