This is the time of year when things are the most hectic so I apologize for the lack of progress in Dozen Days of Tiles. I will continue the series next week and plan on releasing the first episode on Blazing Games in March. I am only going to create half the episodes as 2012 will be devoted to a 12 part game. Yes, the end of the world is overused but I want to do a series around that theme anyways. Besides, Alein the Alien has been idle too long.
Merry Christmas (or whatever else you celebrate) and have a happy new year everyone.
Saturday, December 25, 2010
Sunday, December 12, 2010
DDTe1 Hour 2 to 4 - Tiles
Creating the tiles necessary for sudoku seems like a simple enough process. After all, only 10 tiles are needed. However, the check mark note system needs to be incorporated into this as well as the hint system. This makes the task a bit harder to accomplish. My decision was to got with 40 tiles. 10 for normal (blue), ten for incorrect (red) ten for correct (green) and 10 for locked (black). I am also considering an additional ten for locked but incorrect but for now am not going to bother with this but may do so later if time permits.
The easiest way of implementing the tiles would be to use text. This would not have the visual impact that I want so instead the ImageLayer class will be taken advantage of to create to display bitmap tiles that can be made as fancy as desired. The tiles were quickly created in fireworks using a nice marble image for the backdrop. This image was created quickly but may be touched up a bit later. Likewise, it will be easy to replace numbers with other symbols if so desired.
Next, the Sudoku.Tile class was created. This holds the state of the tile, the current value of the tile, if the tile is locked, and two arrays of 10 representing the state of the checkboxes. While I could use 9, because all the labelling starts at 1 I figured it would be less confusing to me to have element 0 being unused and elements 1 through 9 representing the actual number. A ImageLayer is used to draw the tile and 9 additional (small) image layers are used to represent the notes.
The combination of the two sets of numbers determine which color to set the note tiles to, if they are displayed. The decision to show them or not is dependent on the value that the tile is set to. If this is a non-zero value, the hint tiles are all made invisible. Otherwise, visibility and color get determined by the two check arrays.
The next step is to actually make it possible to set the notes and value for tiles. There are no built in user interface components in the HTML 5 canvas so I am going to have to either roll my own or use HTML markup outside of the canvas to handle things. This decision will be the topic for the next post.
The easiest way of implementing the tiles would be to use text. This would not have the visual impact that I want so instead the ImageLayer class will be taken advantage of to create to display bitmap tiles that can be made as fancy as desired. The tiles were quickly created in fireworks using a nice marble image for the backdrop. This image was created quickly but may be touched up a bit later. Likewise, it will be easy to replace numbers with other symbols if so desired.
Next, the Sudoku.Tile class was created. This holds the state of the tile, the current value of the tile, if the tile is locked, and two arrays of 10 representing the state of the checkboxes. While I could use 9, because all the labelling starts at 1 I figured it would be less confusing to me to have element 0 being unused and elements 1 through 9 representing the actual number. A ImageLayer is used to draw the tile and 9 additional (small) image layers are used to represent the notes.
The combination of the two sets of numbers determine which color to set the note tiles to, if they are displayed. The decision to show them or not is dependent on the value that the tile is set to. If this is a non-zero value, the hint tiles are all made invisible. Otherwise, visibility and color get determined by the two check arrays.
The next step is to actually make it possible to set the notes and value for tiles. There are no built in user interface components in the HTML 5 canvas so I am going to have to either roll my own or use HTML markup outside of the canvas to handle things. This decision will be the topic for the next post.
Sunday, December 5, 2010
DDTe1 Hour 1 - Planning
As tempting as it was to take the day off and play Recettear, work has finally begun on Dozen Days of Tiles. I happen to be a big fan of the Sudoku puzzles that appear in the free paper that is delivered here so while solving the puzzle in todays paper thoughts of how to create my own sudoku player game started coming to mind. I grabbed a piece of graph paper and spent about an hour planning out the game. This is probably more time than I usually spend planning out a small game such as this. Usually scratches on scrap paper is what my planning for small games consists of. Larger projects, especially when multiple people are involved, require much more planning but a game that can be finished in under 24 hours of development time shouldn't need much planning otherwise you may be too ambitious with your plans. As I am separating the player from the puzzle generator I am hoping that I am not being too ambitious with this project but we will know for sure soon enough.
Even before starting on this project, I had decided to separate the generator from the player. The reason for this is that clearly the generation of random sudoku puzzles is going to be a difficult enough task on its own without the requirement of having a player component as well. The player should be designed so it can easily accept the puzzles generated from the generator, have other puzzles (hand created or from third parties), and even a blank puzzle so the player can be used for playing puzzles from a newspaper without the user having to create some type of data file.
As a player of the game myself, the requirement that I have, one which the computer sudoku games that I have seen often fail at, is being able to easily mark up the blank tiles. I tend to write the possible numbers down and if it is clear that some numbers must belong to one or two tiles (required by a row or column, for example) will underline those numbers. My thoughts would be to solve this by having a notes block that appears for the currently selected tile. If the tile is empty then the notes will appear as mini-tiles within that tile.
Here is the planned layout for my sudoku player. I think it is clear enough how it will be used, but I am biased. The next step is to start creating the basic tile class which will probably take a few hours.
Even before starting on this project, I had decided to separate the generator from the player. The reason for this is that clearly the generation of random sudoku puzzles is going to be a difficult enough task on its own without the requirement of having a player component as well. The player should be designed so it can easily accept the puzzles generated from the generator, have other puzzles (hand created or from third parties), and even a blank puzzle so the player can be used for playing puzzles from a newspaper without the user having to create some type of data file.
As a player of the game myself, the requirement that I have, one which the computer sudoku games that I have seen often fail at, is being able to easily mark up the blank tiles. I tend to write the possible numbers down and if it is clear that some numbers must belong to one or two tiles (required by a row or column, for example) will underline those numbers. My thoughts would be to solve this by having a notes block that appears for the currently selected tile. If the tile is empty then the notes will appear as mini-tiles within that tile.
Here is the planned layout for my sudoku player. I think it is clear enough how it will be used, but I am biased. The next step is to start creating the basic tile class which will probably take a few hours.
Sunday, November 28, 2010
Recettear
My original plans for this weekend were to start working on the first episode of Dozen Days of Tiles. I still am up in the air as whether I should start with my Mah Jongg effort or if Sudoku would be the better starting project. Sadly, neither have been started as Steam has their Thanksgiving sale going on and one of the games on sale (92% off) was an indie story pack that contained a game I wanted. Since the pack was less than the cost of the single game, I grabbed the pack and a game called Recettear caught my eye. It was different enough that I figured I would install it on my windows machine and try it out for a few hours. The game was so enjoyable that I am writing this post about it since it ate up my DDT time.
You play the game as a young girl named Recette. Your father ran off to become an adventurer and left you in debt. To pay off your debt, the fairy Tear is helping you turn your house into a store. Because the town you live in is a haven for adventurers, it is an item shop. While you can buy items wholesale, the fun of the game comes from hiring adventurers and then going into a dungeon to "acquire" the items so you can sell them for a 100% profit.
The game is surprisingly addictive. The only real complaint that I have about the game so far is the weekly payment. It is a skewed payment scheme where the first payment is 10000, the second 30000, the third 80000, the fourth 200000 and a final payment that I haven't seen yet but from the progression would guess 500000. While the idea here from a designers perspective is to keep the game challenging, I think the game would have been more enjoyable if the debt could be paid off at a slower pace. When I screwed up and was not able to make the 200000 payment, I discovered that instead of having to go back to an earlier save and replay the week the game would automatically restart you on day 2 but with all your stock and experience. Still, I think a better approach would have been to tie the expansion of the store to the debt. As each chunk of debt was paid off (minimum payment perhaps but small enough so game could be played leisurely) a store upgrade would start causing the loan to start again.
Still, for a low cost indie game, this is quite a fun title. My recommendation, however, is not to start on this game if you have other things to do as like many strategy games this game has a one-more-turn syndrome that causes hours to mysteriously vanish into the game.
You play the game as a young girl named Recette. Your father ran off to become an adventurer and left you in debt. To pay off your debt, the fairy Tear is helping you turn your house into a store. Because the town you live in is a haven for adventurers, it is an item shop. While you can buy items wholesale, the fun of the game comes from hiring adventurers and then going into a dungeon to "acquire" the items so you can sell them for a 100% profit.
The game is surprisingly addictive. The only real complaint that I have about the game so far is the weekly payment. It is a skewed payment scheme where the first payment is 10000, the second 30000, the third 80000, the fourth 200000 and a final payment that I haven't seen yet but from the progression would guess 500000. While the idea here from a designers perspective is to keep the game challenging, I think the game would have been more enjoyable if the debt could be paid off at a slower pace. When I screwed up and was not able to make the 200000 payment, I discovered that instead of having to go back to an earlier save and replay the week the game would automatically restart you on day 2 but with all your stock and experience. Still, I think a better approach would have been to tie the expansion of the store to the debt. As each chunk of debt was paid off (minimum payment perhaps but small enough so game could be played leisurely) a store upgrade would start causing the loan to start again.
Still, for a low cost indie game, this is quite a fun title. My recommendation, however, is not to start on this game if you have other things to do as like many strategy games this game has a one-more-turn syndrome that causes hours to mysteriously vanish into the game.
Sunday, November 14, 2010
DDT project starting
A few years ago I started the Dozen Days Pentalogy. This was planned to be a set of 5 series of a dozen small games. Each game in the series would be developed in a day. I originally started this project after hearing about a game in a day competition. As a lot of the games on Blazing Games were developed with a very short time-frame, this seemed right up my ally. The first series of games were developed in Flash and actually done in a day. This was not very easy to schedule and things like family problems made it harder for me to justify locking myself up for a day. For that reason, the second series was set up to be a maximum development time of 24 hours which could be spread out so I could work on it whenever I had a few hours to spare. This was done in Flex, which is a more code oriented variant of Flash (it produces the same swf files that Flash does) as I felt it was more open to being open-sourced as the tools were freely available while Flash Professional is very expensive. The last two episodes of the second season, however, were my attempt at moving to HTML 5.
It is now time for me to start on the third series of games. The remaining categories that I plan on covering are Tiles, Cards, and Board. All three are interesting and are the type of games that should be able to be created in a short period of time. Still, my current interest in Sudoku and Mah-Jongg means that I have decided that the third series is going to be tile-based games.
There are going to be a few changes on how I create these games. First, I am going to use my BGLayers library and develop the game using HTML 5 (no big surprise here). Second, while the time limit will be 24 hours, this will only apply to work on the code. As I finish up a block of work on a project, I plan on writing a detailed post about the work. The time spent writing these articles will not count towards the time-limit of the game. I will, essentially, be developing the game "live on the Blazing Games Development Blog" though may get a few weeks ahead of the articles if I am on a roll and can put the time in. Finally, some of the games may be broken into two or three separate games. For instance, Sudoku will have a player project which will be separate from a generator project.
I hope the few of you who actually read this will find this interesting.
It is now time for me to start on the third series of games. The remaining categories that I plan on covering are Tiles, Cards, and Board. All three are interesting and are the type of games that should be able to be created in a short period of time. Still, my current interest in Sudoku and Mah-Jongg means that I have decided that the third series is going to be tile-based games.
There are going to be a few changes on how I create these games. First, I am going to use my BGLayers library and develop the game using HTML 5 (no big surprise here). Second, while the time limit will be 24 hours, this will only apply to work on the code. As I finish up a block of work on a project, I plan on writing a detailed post about the work. The time spent writing these articles will not count towards the time-limit of the game. I will, essentially, be developing the game "live on the Blazing Games Development Blog" though may get a few weeks ahead of the articles if I am on a roll and can put the time in. Finally, some of the games may be broken into two or three separate games. For instance, Sudoku will have a player project which will be separate from a generator project.
I hope the few of you who actually read this will find this interesting.
Sunday, November 7, 2010
Animating the Canvas part 10: Cleaning up the Dirt
Creating a library is a bit different type of programming than normal application creation. When you are creating a class for an application, the only thing you have to be concerned about is that it meets the needs of your application. When creating a library, you have the extra burden that not only must your class do what it is suppose to do but it has to be flexible enough and bullet proof enough to be used by other people who are unrelated to your project. Lack of protected and private variables, as well as the namespace issues, makes creating a library in JavaScript more challenging. My goal today is to go over BGLayers and try to clean it up so it will be useful to others. At this point I highly doubt anybody is actually using my library (other than myself) so I don't have to worry about backwards compatibility. The biggest part of this effort will be to make protected variables more obvious so other programmers will know when they are messing with a variable they shouldn't be. From my brief examination of other JavaScript projects, I have noticed that the underscore is often used to indicate a protected variable. This is common enough and the underscore is distinct enough that it should be adequate to act as a warning to people wanting to modify variables directly. It's not the best solution but it is easy enough of a change.
The Dimension and Point classes don't have any changes necessary. The Rectangle class does have a bit of confusion in it. The contains function is for points while the containsRect is for rectangles. This could be confusing and result in someone using contains with a rectangle parameter and never getting proper results back. To eliminate this possible problem, I am changing contains to containsPoint. To make it even friendlier, both of the contains functions will take advantage of different parameter sets so point and rectangle objects can be passed to the respective functions as well as raw coordinates.
The layers class is where we have a lot of variables that should be private. The logical size of the layer is used to determine the real position so changing it outside of the class will not be noticed resulting in incorrect results. As there currently is no way of altering this, a changeSize function will be created. The logical position variable is similar, but already has multiple functions that modify it so the only new function needed here is a getPosition function. The real position, children and dirty rectangle variables are already adequately handled with functions. The solid variable, on the other hand, is really layer dependent and should not even be seen by the user. Visibility, though, is important so a setVisible function will be added. The only variables left "visible" to the user then are the background color and id. I suppose changing the background color should force a redraw so I will add a setBackgroundColor function and make it protected as well.
Finally, for the ImageLayer class, both the clip and image variables should probably be protected. I debated if it was wise to allow changing the image but ultimately decided there was little harm in allowing it so a setImage function has been added.
With this bit of cleaning up, I think that BGLayers is good enough for now. Certainly, as I am using the library internally, it will have enhancements added to it over time so expect the occasional article about new features in the future. As for future posts, I want to focus on the creation of games so have decided that this blog will be used as a detailed journal for the development of a number of future BlazingGames.com games. More on that next week. The source for the BGLayers library can be found at http://www.blazinggames.com/other/openLibrary/html5Libs.
The Dimension and Point classes don't have any changes necessary. The Rectangle class does have a bit of confusion in it. The contains function is for points while the containsRect is for rectangles. This could be confusing and result in someone using contains with a rectangle parameter and never getting proper results back. To eliminate this possible problem, I am changing contains to containsPoint. To make it even friendlier, both of the contains functions will take advantage of different parameter sets so point and rectangle objects can be passed to the respective functions as well as raw coordinates.
The layers class is where we have a lot of variables that should be private. The logical size of the layer is used to determine the real position so changing it outside of the class will not be noticed resulting in incorrect results. As there currently is no way of altering this, a changeSize function will be created. The logical position variable is similar, but already has multiple functions that modify it so the only new function needed here is a getPosition function. The real position, children and dirty rectangle variables are already adequately handled with functions. The solid variable, on the other hand, is really layer dependent and should not even be seen by the user. Visibility, though, is important so a setVisible function will be added. The only variables left "visible" to the user then are the background color and id. I suppose changing the background color should force a redraw so I will add a setBackgroundColor function and make it protected as well.
Finally, for the ImageLayer class, both the clip and image variables should probably be protected. I debated if it was wise to allow changing the image but ultimately decided there was little harm in allowing it so a setImage function has been added.
With this bit of cleaning up, I think that BGLayers is good enough for now. Certainly, as I am using the library internally, it will have enhancements added to it over time so expect the occasional article about new features in the future. As for future posts, I want to focus on the creation of games so have decided that this blog will be used as a detailed journal for the development of a number of future BlazingGames.com games. More on that next week. The source for the BGLayers library can be found at http://www.blazinggames.com/other/openLibrary/html5Libs.
Monday, November 1, 2010
Animating the Canvas part 9: Getting Dirty Quicker
When I was first starting to learn to program, I was told three steps to follow in order to create good programs. The first step is to get your program running. The second step is to get it running correctly. The final step, which is often not needed, is to get it running fast. In the old days (the 1990's) programmers were more concerned with speed (100MHz was fast!) so a lot of programmers would optimize their code before the program was even running. Often, the optimizations used would make their code messier making it harder to actually get the program running correctly or at all.
The big trick to optimizing is simply the knowledge that in the normal course of running only a small percentage of the code being ran is responsible for the bulk of the time. If you can find the parts of your program that most of the executing time is taking place in, you can optimize those areas and gain a fair bit of speed. Tools like FireBug make this very easy as they have tools that do the tracking for you.
Once you know what code needs to be fixed, the key question becomes how to speed it up. My advice would be to learn Assembly language (aka Machine code). While you may never need to use it, which is unfortunate as it is great fun to code in, knowing what the machine is actually doing at a low level will give you a much greater appreciation for what is going on with your program. Another technique, which I don't do as much as I should, is to simply use the debugger to single step through the function in question. This can give you a huge insight into what is going on.
BGLayers have two parts that need focus on. First, is the adding of dirty rectangles. Next is the rendering of things. The addDirty function is relatively minor CPU wise, but during my discovery at how poor Canvas Clipping is I noticed a lot of Rectangles were being created needlessly and wanted to reduce this. Creating a new instance of an object has some overhead to it so avoiding doing so will speed things up. Right at the start of addDirty, a new instance of a rectangle is created. This was done to support null parameters which add the entire layer, but when you consider that the function will call the same function until the parent is reached, this can be very inefficient.
The problem is that a new instance of the rectangle passed has to be created as it has to be altered to assure it is pixel aligned. While this alteration is minor but could muck up the rectangle if it is used by unrelated parts of the program. When we start clipping the dirty rectangle we use recursion to call the function causing many unnecessary rectangles to be created. The solution is to eliminate the recursion. This is easily done by simply having an array with a list of rectangles that need to be clipped. Initially there is only the initial rectangle in this list. If it is clipped, new rectangles get added to the list instead of having to call addDirty. This eliminates the recursion.
With these simple but major changes, the program is run and no noticeable difference in run time. Well, at least I know there will be less garbage collection. My point about not optimizing where there is no need has proven itself as I wasted almost an hour for no gain. Still, I am happier with the code as recursion has been eliminated making the code nicer.
Next, we try to speed up the part that is taking up over two-thirds of the cycles in my tests. Namely the draw self function. This again leads me back to ancient times (the 90's) when the big bugaboo in graphics programming was drawing pixels multiple times per frame. In those times, accelerated graphics cards were hit or miss and accessing video memory was costly. Things have changed today but eliminating unnecessary drawing is still a good idea. In fact, this was planned from the beginning and is why there is a solid variable to let the renderer know if a layer is solid. Anything underneath a solid layer is not going to be seen so if the portion being drawn is contained within the solid layer, only that layer and any layers above it need to be drawn. This is done in the render function, which the drawSelf function is called from. The rendering code has been changed to only call drawSelf if no solid layers contain the bounds being rendered.
for (cntr = this.children.length - 1; cntr >= 0; --cntr) {
if ((this.children[cntr].solid) && (this.children[cntr].findRealPosition().containsRect(bounds))) {
startDraw = cntr;
break;
}
}
if (startDraw == -1) {
this.drawSelf(ctx, bounds);
startDraw = 0;
}
for (cntr = startDraw; cntr < this.children.length; ++cntr)
this.children[cntr].render(ctx, bounds);
That simple change has a drastic effect on performance. DrawSelf now accounts for less than half of the drawing time. The next step will be to make the API friendlier. The code for this post is located at http://www.blazinggames.com/other/openLibrary/html5Libs.
The big trick to optimizing is simply the knowledge that in the normal course of running only a small percentage of the code being ran is responsible for the bulk of the time. If you can find the parts of your program that most of the executing time is taking place in, you can optimize those areas and gain a fair bit of speed. Tools like FireBug make this very easy as they have tools that do the tracking for you.
Once you know what code needs to be fixed, the key question becomes how to speed it up. My advice would be to learn Assembly language (aka Machine code). While you may never need to use it, which is unfortunate as it is great fun to code in, knowing what the machine is actually doing at a low level will give you a much greater appreciation for what is going on with your program. Another technique, which I don't do as much as I should, is to simply use the debugger to single step through the function in question. This can give you a huge insight into what is going on.
BGLayers have two parts that need focus on. First, is the adding of dirty rectangles. Next is the rendering of things. The addDirty function is relatively minor CPU wise, but during my discovery at how poor Canvas Clipping is I noticed a lot of Rectangles were being created needlessly and wanted to reduce this. Creating a new instance of an object has some overhead to it so avoiding doing so will speed things up. Right at the start of addDirty, a new instance of a rectangle is created. This was done to support null parameters which add the entire layer, but when you consider that the function will call the same function until the parent is reached, this can be very inefficient.
The problem is that a new instance of the rectangle passed has to be created as it has to be altered to assure it is pixel aligned. While this alteration is minor but could muck up the rectangle if it is used by unrelated parts of the program. When we start clipping the dirty rectangle we use recursion to call the function causing many unnecessary rectangles to be created. The solution is to eliminate the recursion. This is easily done by simply having an array with a list of rectangles that need to be clipped. Initially there is only the initial rectangle in this list. If it is clipped, new rectangles get added to the list instead of having to call addDirty. This eliminates the recursion.
With these simple but major changes, the program is run and no noticeable difference in run time. Well, at least I know there will be less garbage collection. My point about not optimizing where there is no need has proven itself as I wasted almost an hour for no gain. Still, I am happier with the code as recursion has been eliminated making the code nicer.
Next, we try to speed up the part that is taking up over two-thirds of the cycles in my tests. Namely the draw self function. This again leads me back to ancient times (the 90's) when the big bugaboo in graphics programming was drawing pixels multiple times per frame. In those times, accelerated graphics cards were hit or miss and accessing video memory was costly. Things have changed today but eliminating unnecessary drawing is still a good idea. In fact, this was planned from the beginning and is why there is a solid variable to let the renderer know if a layer is solid. Anything underneath a solid layer is not going to be seen so if the portion being drawn is contained within the solid layer, only that layer and any layers above it need to be drawn. This is done in the render function, which the drawSelf function is called from. The rendering code has been changed to only call drawSelf if no solid layers contain the bounds being rendered.
for (cntr = this.children.length - 1; cntr >= 0; --cntr) {
if ((this.children[cntr].solid) && (this.children[cntr].findRealPosition().containsRect(bounds))) {
startDraw = cntr;
break;
}
}
if (startDraw == -1) {
this.drawSelf(ctx, bounds);
startDraw = 0;
}
for (cntr = startDraw; cntr < this.children.length; ++cntr)
this.children[cntr].render(ctx, bounds);
That simple change has a drastic effect on performance. DrawSelf now accounts for less than half of the drawing time. The next step will be to make the API friendlier. The code for this post is located at http://www.blazinggames.com/other/openLibrary/html5Libs.
Subscribe to:
Posts (Atom)


