Creating game tools in HTML5

5. October 2012

I am about to embark on a bit of a sidetrack here on GameFromScratch.com, hopefully a few of you find it interesting.

 

Basically I am going to start looking at developing game tools using HTML5.  Tooling is a massive part of the game development process and traditionally i've used RAD client only tools like C# + WinForms in this capacity, but HTML5 is becoming increasingly appealing.  I have done a great deal of traditional web development, but nothing really like this.

 

My first project is going to be a dry run on a level editing tool.  I have NO intentions of actually using the end result in a production environment, it is as much a learning experience for me as anything else.  This unshackles me from spending time on stuff like… design, as I intend to throw away everything anyways ( famous last words? ).  Besides, until you have a solid grasp of what you are doing and what problems you are going to face, it's pretty hard to create much of a design anyways.  Now, if I enjoy the experience and the results, I will put a great deal of thought into the design of the finished product.  But when just trying things out, design mostly just gets in the way.

 

This is not the first time I have gone down this road, I've started a number of times and run in to the same problem over and over.  Too much choice, not enough knowledge to make the decision.  I always end up looking at frameworks, design patterns, libraries, toolkits etc, and always end up getting nowhere.  Even picking a client side JS library can consume weeks of your life, throw in a persistence framework, MVC or MVVM framework and months of your life are gone.

 

In the past I went down this road, I looked in to technologies ( such as YUI, Kendo, jQuery, Backbone, Moustache, Dojo, etc… ) and found strengths and faults with all of them.  What I didn't find is success…  This is an area that is anathema to me.  I like to research things, know my options going in and make a decision from a position of some knowledge.  Problem is, there are just too damned many frameworks and options.

 

So I am doing something I never do.  I am picking the technologies up front, and come hell or high water, I am sticking with them until the end.  Therefore for my upcoming project I am going to work with:

- YUI 3 for UI, controls, data, program flow, etc...

- EaselJS for graphics.

 

 

Why YUI 3?  Well because it is pretty much an all encompassing framework, it does about everything, taking decisions away from me.  I don't need to pick a client side technology like jQuery, nor a mobile suite like jQueryMobile, nor a back end like Backbone or ember, package system like require, etc…  YUI pretty much has it all out of the box.

 

Why EaselJS instead of a plethora of game/animation HTML5 libraries?  God knows there are enough of them!  Well, because I haven't used it and I intended to look in to it.

 

So, I am not saying either of these technologies are better than their alternatives, I simply don't have the experience yet to make such a judgement.  I am going with them because, well, they are there.

 

Hope you find the process interesting.

Design, General, Programming




Moai Tutorial Part 7: Tile maps so easy your mother could do it

3. October 2012

 

Not to make any assumptions about your mother’s computing abilities of course!  My mother is flummoxed by powering a computer on and its all down hill from there, so perhaps not quite easy enough *my* mother could do it.  But it is easy, really easy.  Really.  Easy.  This is just one of those areas Moai really shines.

 

If you are unfamiliar with the concept, a tilemap is pretty straight forward.  You have an image or series of images that hold the art for your game.  In this example, we are going to use a regular top down ( not isometric ) perspective and our image map is composed of tiles 32x32 pixels in size.  Your game map is then made up of a grid that says “at this location, draw this tile”.

 

First, the topic of the image itself.  That one, in the spirit of open source, I am ripping off someone else’s work! Smile  You may remember a while back Mozilla released a completely free HTML5 based MMO, BrowserQuest.  Well, we are going to make use of one of the tilesheets from that project.  This is the file right here (it is big).  This is massive overkill, but I like massive overkill.  Here is a shrunk down version of the image we are going to be working with:

image

 

The image is composed of 20 columns of 32x32 images and 98 rows of them, for a grand total of 1,960 tile images or cells, in a single image.  So, that covers our image, let’s take a look at the code:

screenWidth = MOAIEnvironment.screenWidth
screenHeight = MOAIEnvironment.screenHeight
if screenWidth == nil then screenWidth =1280 end
if screenHeight == nil then screenHeight = 800 end

MOAISim.openWindow("Window",screenWidth,screenHeight)

local viewport = MOAIViewport.new()
viewport:setSize(screenWidth,screenHeight)
viewport:setScale(480,320)

local layer = MOAILayer2D.new()
layer:setViewport(viewport)
MOAIRenderMgr.pushRenderPass(layer)

local map = MOAIGrid.new()
map:initRectGrid(15,10,32,32)
map:setRow(10,0x0b,0x0c,0x0d,0x0b,0x0c,0x0b,0xc7,0xc7,0xc7,0xc7,0x0d,0x0b,0x0c,0x0d,0xc7)
map:setRow(9,0x2e,0x2f,0x30,0x31,0x32,0x0b,0x0c,0x0d,0xc7,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(8,0x41,0x42,0x43,0x44,0x45,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(7,0x55,0x56,0x57,0x58,0x59,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(6,0x69,0x6a,0x6b,0x6c,0x6d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(5,0x7d,0x7e,0x7f,0x80,0x81,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(4,0x91,0x92,0x93,0x94,0x95,0x0b,0x0c,0x0d,0xc7,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(3,0xa5,0xa6,0xa7,0xa8,0xa9,0x0b,0x0c,0xc7,0xc7,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(2,0xb9,0xba,0xbb,0xbc,0xbd,0xc7,0xc7,0xc7,0xc7,0xc7,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(1,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2)


local mapTiles = MOAITileDeck2D.new()
mapTiles:setTexture("tilesheet.png")
mapTiles:setSize(20,98)

local prop = MOAIProp2D.new()
prop:setDeck(mapTiles)
prop:setGrid(map)
prop:setLoc(-480/2,-320/2)
-- functionally the same as above
-- prop:setPiv(480/2,320/2)

layer:insertProp(prop)

And if we run this code, we see:

 

image

 

Ok, that’s a pretty cool amount of stuff on screen, for not so much code!  Let’s take a look at exactly what we did here.  Once again from the top ( one of these examples I am going to do from the bottom! ).  Once again, we are only going to look at the new bits, so if I fail to cover something, check out the prior tutorials, chances are I covered it then.

 

local viewport = MOAIViewport.new()
viewport:setSize(screenWidth,screenHeight)
viewport:setScale(480,320)

We’ve seen this many times before, but always in the past I’ve set setSize and setScale to the same value, this time I didn’t… why?  Well the biggest reason is, I defined the grid of map values by hand, which was a gigantic pain in the butt for a screen made up of a 15x10 array of tiles ( 480/32==15, 320/32==10 ), let alone a 1280x800 screen!  By setting the viewport to the actual resolution of your device, but setting the scale to your target resolution ( in this case, the iPhone 3g’s native resolution ), MOAI automatically handles the scaling for you.  This is a nice easy way to support a number of different screen resolutions without having to code each one by hand.

 

Speaking of the map values:

local map = MOAIGrid.new()
map:initRectGrid(15,10,32,32)
map:setRow(10,0x0b,0x0c,0x0d,0x0b,0x0c,0x0b,0xc7,0xc7,0xc7,0xc7,0x0d,0x0b,0x0c,0x0d,0xc7)
map:setRow(9,0x2e,0x2f,0x30,0x31,0x32,0x0b,0x0c,0x0d,0xc7,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(8,0x41,0x42,0x43,0x44,0x45,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(7,0x55,0x56,0x57,0x58,0x59,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(6,0x69,0x6a,0x6b,0x6c,0x6d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(5,0x7d,0x7e,0x7f,0x80,0x81,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(4,0x91,0x92,0x93,0x94,0x95,0x0b,0x0c,0x0d,0xc7,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(3,0xa5,0xa6,0xa7,0xa8,0xa9,0x0b,0x0c,0xc7,0xc7,0x0c,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(2,0xb9,0xba,0xbb,0xbc,0xbd,0xc7,0xc7,0xc7,0xc7,0xc7,0x0d,0x0b,0x0c,0x0d,0x0b)
map:setRow(1,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2,0xc2)

In the immortal words of Douglas Adams DON’T PANIC!  This looks a lot scarier than it actually is.  We are creating our map, which is a variable of type MOAIGrid.  Think of a grid as a 2d array of sorts that holds references to the tiles at each location.  Really that’s about what it does.  So we start of by initializing with a call to initRectGrid() passing in the number of tiles ( 15x10 ) and the width and height of each tile ( 32,32 ).  The next 10 lines are simply populating the grid with calls to setRow(), the first value is the row index, then what follows is a list of 32bit indexes in hexidecimal.  This is where the scary comes in.

 

Basically the top left tile in our image map is at 1 ( 0x01 ) and there are 20 tiles per row in the image we used, so the first image in the second row is therefore at 21 ( row count * row width + offset == 1 * 20 + 1 == 21 ), which is then translated in to hex, which is 0x15. 

 

So, basically we “draw” our map using image locations ( as a 1d index using the formula above, converted to hex ).  The MOAIGrid itself, row 1 is the bottom most row, which is why our grid counts down from 10.  Now let’s take a look at how we created our source image:

 

local mapTiles = MOAITileDeck2D.new()
mapTiles:setTexture("tilesheet.png")
mapTiles:setSize(20,98)

Pretty simple over all.  We create a MOAITileDeck2D.  Remember, a Deck is parlance for an image source, and in this case our source is a single image composed of dozens of tiles.  We set the actual image with a call to setTexture() and pass in our filename tilesheet.png.  We then set it’s size, letting it know it is made up of 20 columns and 98 rows of tiles.

 

local prop = MOAIProp2D.new()
prop:setDeck(mapTiles)
prop:setGrid(map)
prop:setLoc(-480/2,-320/2)
-- functionally the same as above
-- prop:setPiv(480/2,320/2)

Neither MOAITileDeck2D or MOAIGrid are display items, for the we need to create a MOAIProp2D.  We set it’s deck ( or source ) to our newly created MOAITileDeck2D mapTiles and it’s grid to our MOAIGrid map.  Finally we set it’s position with a call to setLoc.  This is an area of some possible confusion ( and why I showed the commented setPiv() as well ), because by default our prop will be at (0,0), which is the dead center of the screen.  However, the pivot point of our prop in the case is actually the bottom left corner of our map.  Therefore, we either need to move the pivot point to the center ( what the commented out code does ), or we position the prop offset from the center of the screen by half the width and height of the viewport.

 

You can actually accomplish a heck of a lot with just a bit of code.  Obviously in your case, you want want to use a tool to generate the MOAIGrid indices, doing it by hand is a PITA ( trust me! ).  Really though, the visual rendering of a top down RPG game just boiled down to a dozen or so lines of code!  Perhaps most impressively, this just scratched the surface of what MOAIGrid can do.

 

Coming Soon

General, Programming , ,




Binding a hotkey to an external tool in IntelliJ

2. October 2012

In this prior post I covered the process of configuring JetBrains' IntelliJ to work with Moai.  As part of the process, I configured a pair of External Tool menu items to launch your code in Moai.  This setup works well enough, but I am a keyboard guy and mousing up to the Tools->Moai->Run Moai… well, it's a pain in the ass.

 

So today I finally did something about it and configured a hotkey.  The process is relatively easy.

 

Open the IntelliJ Settings screen from the file menu, or Preferences if running on Mac.

On the left hand side, scroll down and locate Keymap.  Expand External tools, Moai ( or whatever you named it ), then double click the tool you want to hotkey.

External tools keymap

 

Select Add Keyboard Shortcut:

Now select First Stroke and hit the hotkey combo you want.  Warning, it will pass through system commands, so APPLE+SHIFT+W or ALT+F4 will try to close the window for example.  Keep trying unit you find a combo that isn't conflicting.  The below combo is APPLE+Control+R.

Setting the hotkey

 

Click OK, then Apply, then OK again, and your hotkey will be set.

 

Now in IntelliJ hit CTRL+Win/APPLE key + R and your Moai app should run.

General




Using ZeroBrane Studio with Moai ( it also works with LOVE)

27. September 2012

 

The author contacted me a few weeks up with a heads up that he had a Moai friendly Lua IDE in development and I said I would look into it… and well, I didn’t.  Things came up, then something else and something else and frankly it got pushed into the back of my mind.  In the end, that was a good thing too, as since that point in time the author has added auto-completion… a critical feature.

 

As of writing though, this feature is only available from the github sources.  So long as you have cygwin configured ( assuming you are working with Moai, you should already ), and git installed, the process is fairly simple:

 

cd /cygdrive/c/folder/to/install/to

git clone https://github.com/pkulchenko/ZeroBraneStudio.git

 

This will create a folder ZeroBraneStudio with all the appropriate files. 

EDIT (29/09/2012): Author made update, should no longer need to set permissions described below

There is another catch, git mangles the executable permissions on Windows.  The long answer is well… long, the hackishly easy answer is to run:

chmod a+x –R ZeroBraneStudio

 

There is one last catch, you need to set the MOAI_BIN environment variable to point to your MOAI host folder, either that or add it to your PATH variable.  ( I suggest the former ).  To set the MOAI_BIN path, simply open a command prompt and type:

setx MOAI_BIN c:/path/to/moai/host

 

You can of course set the environment variables using the System control panel, but this will require you to reboot your computer for the change to take effect.  SetX simply requires you close the console to take effect.

 

Now you should be able to run the Studio, just double click zbstudio.exe to start it.  Hopefully the author will have a new release soon, that prevents all of this ( except the MOAI_BIN environment variable that is ).  Finally run ZeroBrane and this is what you see:

 

image

 

 

So then… why?  What does ZeroBraneStudio bring to the table that SublimeText or IntelliJ don’t have?

 

That’s an easy one.  I mentioned the first one earlier:

 

image

 

Auto-completion!  After years of using Visual Studio, this one is a gigantic must for me.  Granted as I covered earlier, IntelliJ can be configured to supported auto completion.  But ZeroBrane Studio has a massive head up on IntelliJ, watch this!

 

image

 

This you cannot do with IntelliJ, and it is a gigantic advantage.  But auto-completion isn’t the only thing ZB brings to the table, ZeroBrane Studio has the ability to debug running code!  You can set breakpoints, step in/over and out, set watches and do dynamic expression evaluations, pretty much most of what you expect to see in a debugger. Oddly enough, this needed a Windows Firewall exception.

 

To debug your code, select a line of text to set a breakpoint then hit F9 to create a breakpoint ( a red stop sign will appear in the margin ).  Then select Project->Start Debugging Server.  Then select Project->Start Debugging or hit F5 to run your code and voila:

image

 

Code execution stops at your breakpoint.  Use F10, Ctrl+F10 and Shift+F10 enable you to navigate through your code. You can hover your mouse over a variable to inspect it’s value.  You can also right-click a variable and create a watch window like this:

image

Unfortunately you can’t drill down into an individual Lua table, but hopefully this feature gets added soon!

 

Perhaps coolest of all, ZeroBrane Studio enables REPL interaction.  You can open the console and interact with your code directly:

image

 

As you can see, you can interact with your values in real time, and here are the results in the output:

image

 

It also has the ability to analyze your code, and show you the plethora of stupid mistakes you are making:

image

 

Not everything is perfect.  As mentioned earlier, watch expressions cant drill down into Lua tables, hopefully something that will change soon.  Additionally, it would be nice if the Moai host could be added using a configuration setting instead of using MOAI_BIN, as it makes it difficult to change between runtimes ( moai, moai-untz, release, debug, etc… ), but this is a minor point.  It would also be nice to be able to control more via context menu’s ( add breakpoint, step over/in, etc ). The code syntax highlighting could be improved a bit as well.  Of course, as a straight code editor, it isn’t going to give IntelliJ or SublimeText a run for it’s money just yet.

 

 

That said, this is an absolutely invaluable tool for people working with Moai or LOVE, the debugger and full auto-completion guarantee that this is going to be a stable part of my toolset going forward.  Hopefully the author is able to add more detailed debugging information soon.  If you are working in Moai or LOVE, you owe it to yourself to check out ZeroBrane Studio.

 

Speaking of which, you can get more information here.  Keep in mind, MOAI auto-completion is currently only available in the source distribution, at least as of version 0.32.  Hopefully the new release is bundled soon.

 

EDIT:

I have spoken with the author, and it appears a few of my issues aren’t issues after all.

The system will check for Moai executable in your PATH environment
variable. You can also set "path.moai = 'd:/lua/moai/moai'" in
cfg/user.lua (see cfg/user-sample.lua for example).

 

EDIT2:

ZeroBrane actually can drill down details into a Lua table, in my relative Lua newbishness, I made a pair of mistakes.  First off, it only works on local variables.  Second, Moai does not return tables, it returns Userdata, which ZeroBrane currently can’t parse ( fingers crossed he figures out a way! ).

 

image

 

Here is the behaviour I was expecting to see, and exactly what I got once I defined the table as a local.

General, Programming , , ,




Device resolution quick reference

23. September 2012

This is one of those things I am constantly searching for, so I figured I might as well put something together so I end up on my own site!

 

The following is simply a list of devices and their respective screen resolutions.  I am writing this as much for me as anything else, but hopefully some of you find it useful too.

 

Device Name

Resolution

PlayStation Portable (PSP) 480x272
PlayStation Vita 960x544
Nintendo DS  2 x 256x192
Nintendo 3DS 800x240 upper screen ( 400 per eye, effectively 400x240 ). 320x240 lower screen
iPhone 3 320x480
iPhone 4 640x960
iPhone 5 1136x640
iPad 1024x768
Galaxy S2 480x800
Galaxy S3 720x1280
Galaxy Note 800x1280
HTC OneX 720x1280
Lumia 920 768x1280
Lumia 820 480x800
Transformer Prime 1280x800
Razor HD 1280x800
Common Resolutions by name
QVGA 320x240
VGA 640x480
WVGA 800x480
XGA 1024x768
WXGA 1280x768
UXGA 1600x1200
WUXGA 1920x1280
Television Resolutions
Standard Def NTSC (480i) 720x480 interlaced
Standard Def PAL (576i) 720x576 interlaced
720p 1280x720
1080i 1920x1080 interlaced
1080p 1920x1080
4K 4096x1714 ( varies by manufacturer )

Design, General