Showing posts with label Game Design. Show all posts
Showing posts with label Game Design. Show all posts

Tuesday, January 14, 2020

Video Poker, Part 2

Selecting the Cards


Now the player is in a position to select cards to use. We need a way of letting the player know that the card is selected which is why we have the draw movies. This movie is a single frame movie which contains the word “DRAW” in bold red letters. It is placed over each of the cards and is set to be hidden until made visible. These movie clips were placed in the “Info” layer on the first frame and, if you recall, were hidden in the game initialization method. The movie clips are labeled, “draw1_movie,” “draw2_movie,” “draw3_movie,” “draw4_movie,” and “draw5_movie.”

The logic to handle selecting and unselecting code was already written above but before the game can actually let the player select or unselect a card the game needs to tell the program that selections are allowed. We also need a way for the player to tell the game that it is finished selecting cards so the game can continue. This is the select button on the bottom right of the screen which we add in frame 50 and name “draw\_btn”.  On frame 50 we tell the global video poker game class to activate card selection and the select button using the following two lines of code.

this.stop();
videoPokerGame.activateSelectButton();

The activateSelectButton method is a function that we need to write in the global script. It simply sets the global variable “selecting” to true and then activates the draw button to enable the player to start the game. Clicking on the draw button calls a handleSelect event which simply removes the listener from the button and continues playing the video poker movie.

VideoPokerGame.prototype.activateSelectButton = function()
{
this.selecting = true;
this.drawHandler = this.handleSelect.bind(this);
this.vpMovie.draw_btn.addEventListener("click", this.drawHandler);
}
VideoPokerGame.prototype.handleSelect = function()
{
this.selecting = false;
this.vpMovie.draw_btn.removeEventListener("click", this.drawHandler);
this.vpMovie.play();
}

The movie from frame 51 to frame 155 handles the drawing of the cards which we will cover next.


Drawing the Cards


The drawing of new cards to replace selected cards is done on a per card basis so that Adobe Animate CC can animate the cards being replaced. The code to handle the drawing of the cards is similar for all the cards so we can create a simple utility function to handle the drawing. As this function needs to be accessed by code in different frames, we will make this utility function part of the VideoPokerGame class so the code is in the global script. As you can see, this function simply removes the draw state, hides the draw movie, and then sets the card’s value to the next card in the deck.

VideoPokerGame.prototype.drawCard = function(slot)
{
this.drawMovie[slot].visible = false;
this.hand[slot].setCard(this.myDeck.draw());
}

The draw animation consists of the card being removed followed by the new card being moved into place. This is simply a motion tween going from the full sized card to the small card hidden at the bottom of the screen. This is followed by a small card at the top of the screen motion tweened to a full size card. For the “FLCard” layer the removal tween is on frames 56 to 65 and the drawing tween is on frames 66 to 74. The “Lcard” layer has the removal tween on frames 76 to 85 and the drawing tween is on frames 86 to 94. For the “CCard” layer the removal tween is on frames 96 to 105 and the drawing tween is on frames 106 to 114. The “Rcard” layer has the removal tween on frames 116 to 125 and the drawing tween is on frames 126 to 134. Finally, the “FRCard” layer has the removal tween on frames 136 to 144 and the drawing tween on frames 146 to 154. The Figure \below shows the second half of the video poker timeline where drawing happens.



Right now all the cards are being drawn, and the value of the drawn card is the same value that the card already was. To fix these problems we are going to need to add some java script as well as a few more labels. Let us start by adding some code to the “Code” layer of  frame 55 which was labelled “Draw_1.” This code simply checks to see if the card is one of the cards that was selected to be replaced and if it is not skips over the replacement animation for this card. 

if (this.draw1_movie.visible == false)
this.gotoAndPlay("Draw_2");

If the card is not being drawn, we are done. If the replacement animation plays, however then we need to draw a card to replace the draw card. Once the card has been removed from the screen, we can then draw a card. This is done by calling the function we created earlier in this section. Notice that we use the array index of the card in the function, which is one less than the card that we are on. This is one area where API design can bite you in a project. If this was a team project where non-programmers were calling our API then using the semantics that the artist was expecting would make sense. In this case, we could have had the draw card function assume that the caller was referring to the human number and deduct 1 from the passed number. Ideally you would want to document decisions within the API documentation, but surprisingly this rarely happens and has bitten me a number of times when working with third-party libraries. 

In addition to the code for replacing the card, on Frame 66, we add a draw card sound to the Sound layer so that the sound of a card being drawn is played while the card is being animated in.

playSound("drawwav");

The above procedure is used for the other 4 cards with the draw sound being played on frames 86, 106, 126, and 146. The code is probably self explanatory, but for the sake of completeness I will show the code.

Frame 75 which is labelled “Draw_2”:

if (this.draw2_movie.visible == false)
this.gotoAndPlay("Draw_3");

Frame 86:

videoPokerGame.drawCard(1);

Frame 95 which is also labelled “Draw_3”:

if (this.draw3_movie.visible == false)
this.gotoAndPlay("Draw_4");

Frame 106:

videoPokerGame.drawCard(2);

Frame 115 which is also labelled “Draw\_4”:

if (this.draw4_movie.visible == false)
this.gotoAndPlay("Draw_5");

Frame 126:

videoPokerGame.drawCard(3);

Frame 135 which is also labelled “Draw\_5”:

if (this.draw5_movie.visible == false)
this.gotoAndPlay("Results");

Frame 146:
videoPokerGame.drawCard(4);

Finally we extend all layers to frame 155, label this frame “Results”. Calculating the results of the hand is the most complicated part of the game which we will cover in the next section.

Calculating the Win


The results of the hand can now be calculated. While this work is all done in a single function, the work is kind of complicated. For that reason, I will be breaking the function into a series of sections so I can better explain the logic behind the function. It would have been possible to break down the function into a number of smaller and more specialized functions, which may be a good idea as it simplifies the logic but at a cost of a lot of overhead and duplicate code. If I was going to refactor this function, I would turn it into it's own class so duplicate code could be reduced and the steps broken into separate private methods.

The first thing that is done is the cards are sorted by their face values. Face values are calculated by using the modulus (remainder) of dividing the deck by 13. To make this work, the card ID is reduced by 1.

VideoPokerGame.prototype.findResults = function()
{
var sortedCards = new Array(5);
var cntr1, cntr2, temp, low, testA, testB;
for (cntr1 = 0; cntr1 < 5; ++cntr1)
{
sortedCards[cntr1] = this.hand[cntr1].getCard();
}
// sort, by face value
for (cntr1 = 0; cntr1 < 4; ++cntr1)
{
low = cntr1;
for (cntr2 = cntr1 + 1; cntr2 < 5; ++cntr2)
{
testA = (sortedCards[low] - 1) % 13;
testB = (sortedCards[cntr2] - 1) % 13;
if (testB < testA)
low = cntr2;
}
temp = sortedCards[low];
sortedCards[low] = sortedCards[cntr1];
sortedCards[cntr1] = temp;
}

Next, we prepare all the variables that we are going to need to find the results. We use pairFace to track which card we are trying to match for a pair or triple or quad. We assume at the beginning of our testing that we have a straight and a flush until either of these assumptions are proven wrong during our analysis of the hand. The run is the longest number of matching faces so a run of 2 is a pair, a run of 3 is three of a kind, and a run of 4 is four of a kind. The suit of the first card is the suit we are looking for in the other four cards to determine if we have a flush.

var pairFace = 0;
var isStreight = true;
var isFlush = true;
var longestRun = 0;
var numRuns = 0;
var targetSuit = Math.floor((sortedCards[0] - 1) / 13);
var curRun = 1;


To be a flush, all suits must be the same, so we simply check to see that the suit of the current card in the loop is the same as that of the first card. To see if we have a pair or better, we track the run length of the current card by counting how many cards in a row contain the same face value. As it is possible for more than one pair, we also count how many different face cards are matching. Likewise, to handle a full house, we need to know the length of the longest run of matching cards. Straights are simply a test to make sure that the face value of each card in the sorted hand increases by one (taking into account the fact that an ace can be in two possible positions).


for (cntr1 = 1; cntr1 < 5; ++cntr1)
{
if ( Math.floor((sortedCards[cntr1] - 1) / 13) != targetSuit)
isFlush = false;
testA = (sortedCards[cntr1 - 1] - 1) % 13;
testB = (sortedCards[cntr1] - 1) % 13;
if (testA == testB)
{
isStreight = false;
++curRun;
}
else
{
if (curRun > 1)
{
if (curRun > longestRun)
longestRun = curRun;
curRun = 1;
++numRuns;
pairFace = testA; // if only a pair, need to know face value
}
if (((testB-testA) != 1) && ((testA != 0) || (testB != 9)))
isStreight = false;
}
}
if (curRun > 1)
{
if (curRun > longestRun)
longestRun = curRun;
++numRuns;
pairFace = testA; // if only a pair, need to know face value
}

Analysing the results is the last stage of determining what the hand was. This is done by using the various variables that were set in the analysis phase above and going from the highest value hand down to the weakest hand checking at each hand to see if we meet the criteria for the hand continuing until we have met the criteria for a hand or have a high-card.

// Now analyse results
if ((isStreight & isFlush) == true)
{
if (((sortedCards[4] - 1) % 13) == 12)
{
this.message = "ROYAL FLUSH!!!";
this.lastWin = 250 * this.bet;
}
else
{
this.message = "Streight Flush";
this.lastWin = 50 * this.bet;
}
}
else if (longestRun == 4)
{
this.message = "Four of a Kind";
this.lastWin = 25 * this.bet;
}
else if (longestRun == 3)
{
if (numRuns == 2)
{
this.message = "Full House";
this.lastWin = 9 * this.bet;
}
else
{
this.message = "Three of a Kind";
this.lastWin = 3 * this.bet;
}
}
else if (isFlush)
{
this.message = "Flush";
this.lastWin = 5 * this.bet;
}
else if (isStreight)
{
this.message = "Streight";
this.lastWin = 4 * this.bet;
}
else if (numRuns == 2)
{
this.message = "Two Pairs";
this.lastWin = 2 * this.bet;
}
else if ( (numRuns == 1) && ((pairFace == 0) || (pairFace > 9)) )
{
this.message = "Jacks or Better";
this.lastWin = this.bet;
}
else
{
this.message = "Nothing";
this.lastWin = 0;
}
this.cash += this.lastWin;
return (this.lastWin > 0);
}

Of course, being able to determine the results of a hand is not of much use unless we do something with those results so in the next section we will actually call this method and handle the results of doing so.

Handing the Results


In the results frame we have code that will call the find results method we wrote in the previous section. This code goes to the bet loop immediately if the result of the hand wasn’t a winning hand, otherwise the movie continues playing to give us time to show the results.

var didWin = videoPokerGame.findResults();
videoPokerGame.updateText();
if (didWin == false)
this.gotoAndPlay("BetWait");

To make winning more exciting Video Poker machines have bells and whistles go off when you win anything. This is part of the psychology of gambling and is a reinforcement factor to make the player more excited so they keep playing the game. The bell sound I use is a bit more subtle but still emphasizes that the player has won something so that is placed in frame 156. 

Finally we skip over some frames (so the result message will be shown for a few seconds) and we then place our final “Code” layer key-frame, which simply contains one line of code which goes back to the “betWait” frame.

this.gotoAndPlay("BetWait");

With that we have a complete Video Poker game. For those who want to take this a bit further It is not that difficult to modify the game to support the different types of Video poker such as deuces wild or variants that include a joker. Likewise creating a better deck of cards and running the game at a high-definition resolution would also be simple enough to do.  For the more ambitious people out there, this could be expanded into a full poker game, possibly even a multi-player game.

Have fun and when you are ready come back and explore the world of board games with Pent Up Anger.

Saturday, September 21, 2019

Creating the Deck class

Last section we created tests for building our deck class. Now we are ready to create a deck class. Initially we will create the code within the testDeck.html file but once it is functional move the code into the Deck.js file so it can be used by our various card projects. While it is certainly possible to create the code entirely within the Deck.js file and import that file, for prototyping it is often faster to write the code within the test file and iterate over the code before moving it to the appropriate class as during prototyping the structure of the code may change multiple times so keeping it outside of the main code-base until it is stable can make maintaining the project easier.

This class needs to hold 52 cards in a deck, deal out those cards, and shuffle those cards. First, we are going to need to create the constructor function for this class. This will just create an array for itself to hold the deck and fill that array with in-order values. We also set the index for where we are going to grab cards to the top of the deck.

spelchan.Deck = function()
{
this.cardArray = [];//new Array(52);
for (var cntr = 0; cntr < 52; ++cntr)
this.cardArray[cntr] = cntr + 1;
this.nextCardIndex = 0;
}

This means that we now have a deck of cards but running the test will still fail. While the card ids are in the deck, the deal method is not dealing them out! Dealing out a card is simply the matter of returning the card at the nextCardIndex while increasing the index.

spelchan.Deck.prototype.draw = function()
{
var rv = this.cardArray[this.nextCardIndex];
++this.nextCardIndex;
return rv;
}

Running the tests now show us that we are getting there but the shuffling is not sufficiently random enough to pass our test. This is because we are not shuffling the deck yet. We are going to need a way of shuffling the deck. Think about the different ways to shuffle a deck. There are many ways of shuffling, but most of them are inefficient as far as the computer is concerned. What our goal is, simply stated, is to make the cards in the deck appear in a random order. I realized that taking each card and swapping it at random with another card would be a very good way of shuffling as the computer can do this blindingly fast with really good results. While I came up with this algorithm on my own, my Algorithms teacher did tell me that I was not the first person to think of this and that this is like the technique that shuffling machines use.

spelchan.Deck.prototype.shuffle = function()
{
var cntr, temp, rnd;

for (cntr = 0; cntr < 52; ++cntr)
{
rnd = Math.floor(Math.random() * 52);
temp = this.cardArray[cntr];
this.cardArray[cntr] = this.cardArray[rnd];
this.cardArray[rnd] = temp;
}
this.nextCardIndex = 0;
}

Now when we run the test we see that all the tests have passed. We are now ready to start planning the tests we will be needing for a video poker game. There are other things that we could probably add to this class, but I have discovered over my years that it is easy to refactor and to add things later, especially if you have a testing framework to verify your changes don’t break anything. One tenant of Extreme Programming is to only write the code that you need. We have all that we need for video poker, so next chapter we will start working on a video poker game!

Saturday, July 6, 2019

Chapter 7 Overview

One nice feature of card games, is that once you have created a card game you are able to take advantage of existing assets and code to handle the cards so that creating other card games in the future is easier. In this chapter we are going to take advantage of this in two ways.

First, in ``Creating the Card Movie'' we are going to create a card movie. This movie will have frames for all the cards in a deck and will be able to display any specified card. While fairly simple to build, creating a deck of cards is a time-consuming process. Thankfully, we only need to do it once. After the card movie has been created, you simply need to drag it into the new Animate CC project to use it in other card games. You could also place it into a common library.

Next we are going to create some JavaScript classes. For the most compatibility, which probably is not that big of a deal as most browsers in use support ECMAScript 6 JavaScript code, we are going to use the older and most compatible way of creating classes. In ``Creating the Card Class'' we create the class for handling the cards while in ``The Importance of Testing'' we test this class.

Test driven development, which is a very common practice now, does things the opposite way so in ``Test Driven Deck'' we create the tests for a deck class and with the tests ready to go actually create the deck class in ``Creating the Deck Class''

Once we have these classes created we will be able to build our Video Poker game.

Saturday, April 6, 2019

Planning the Adventure

The basic theme behind nightmare maze is that you are lost in a maze and must move quickly from room to room before the evil Blue Screen of Death reaches you.  The maze in this game is consistent in the fact that the same door will take you to the same room, however it is not commutative meaning that the door from A to B does not necessarily go back to A. This means while there is a structure to the maze it works different then the real world, which is typical of dreams.

Mazes are fairly easy to implement. This maze, however, is not a linear maze. With a linear maze, you can use graph paper to plan out the maze. This is obviously not the case with a non-linear maze. Instead, a different type of graph is used for creating a non-linear maze. This graph consists of the rooms drawn as boxes with arrowed lines showing how the rooms connect. I used a variation on this having colored lines corresponding to the room the line is from.



As you can see by the above map, the links between rooms are fairly complex. However implementing the links is actually very easy. You can also see that there are a lot of ways of reaching the exit, but do to the fact that there is nothing highlighting the exit, a player could end up being stuck in the maze for quite a while.

The room approach is very common in adventure games as travelling between locations is a very common activity. Generally, when designing an adventure game, each location will be considered to be a room even if it is an outside location. This allows for rooms to be worked on independently of each other and for earlier computers that had a very limited amount of memory would allow for the computer to only have to load the drawing data for the room that the player was currently in then having some type of transition animation between "rooms" when the player left a room and the game had to load in the image for the next room.

From a programming perspective, having rooms that are connected together with lines allows us to represent the map as a mathematical graph in which each room is a vertex of the graph and the connections between rooms are the edges of the graph.  Graph theory, however, is not necessary to build an adventure game. All that really matters is that you are able to create a basic map of the locations within the adventure so that you can move between them. The map can also be used to plan out where objects are located in the world and what obstacles or puzzles there are in the game. This allows for a walk through of the game before you have even started any real work on building the game so that you know that the game is solvable.

Once the map is planned out you then have the ability to itemize all the assets that will be needed for the game and can start work on building the art needed for each of the rooms. Building the rooms is what we will be doing next fortnight, but thanks to the nature of our maze this is a lot easier for this game than it would be for most other adventure games.

Saturday, March 23, 2019

Nightmare Maze Overview

In the flash version (as well as my original draft) of this book, the adventure game material was near the end of the book but as the game is fairly simple from a programming perspective, I have decided to move it to here. Nightmare Maze is actually the first episode of a 46 episode series called One of those Weeks, which I hope to be redoing using a 3D engine sometime in the future.

In "Planning the Adventure" we take a look at how the game was designed. Adventure games tend to break areas that the player can visit into rooms, with the word room being a generic concept so outdoor areas are also referred to as rooms. For this game, all the rooms in the game are in fact rooms so the next step to the creation of this game is "Building the Rooms" which covers the techniques used to build the rooms used in this game. While it is a little but unconventional, it works for this game and the basic concepts are the same for other adventures.

While it is possible to have an adventure game that exists in a single room, such as a puzzle room, our game requires movement between rooms. I am not taking about adding doors to the room, though they are what the players use, I am taking about the underlying code for moving players between rooms. This is covered in "Linking the rooms"

While mazes are often enough, for this game we have a villain, who also happens to be in all the other dream sequences in this series, so in "Enter the Nasty" we cover the mechanism for getting the villain to appear. This obviously leads to "Losing and Winning" where we cover how to handle the nasty getting the player as well as the opposite but related player escaping from the nightmare.

With the game finished, this only leaves "Final Touches" where the title screen for the game is added. This covers what we will be doing over the next six fortnights, but the game is already on Spelchan.com so feel free to play the game while you wait for my sections on how the game was created.



Saturday, June 30, 2018

4.1 NIM Design

While NIM is a very simple game, it is a good game to start learning game development with. The game is very straight forward in its presentation. The rules of game play are very easy to implement. Most importantly, at least for beginning Animate developers, the game requires only a minimal amount of JavaScript.

While I personally have no problem with JavaScript, I know a lot of Flash and now Animate developers who fear scripting languages. Games, by their interactive nature, require scripting. There is, however, no need to jump right into extensive JavaScript use. Our first project will attempt to keep JavaScript to a minimum.

We already know what the game is about from the description in the previous section, so what is needed is specific details on the game. There are three things that must be decided. What is the object that is being removed, how many objects are there to be removed, and how does the player remove them?

All of the questions can be answered pretty much any way the designer wanted and the game will still work fine. For the object, anything could work, though I look at the object as something valuable that the person would want the last one. To me I think of jewels or gems when I think of something valued. The reason that gems are valued is because they are rare. The bigger the gem the rarer it is. This means that if the last gem is a big gem then it is a very valuable gem.

The number of objects is simply a matter of how many can fit on the screen. Four rows of ten seemed to make sense, so for this version we will have 40 gems. This would also leave room for a space where the user could specify how many gems to take. As the only interaction the user has is select how many gems to take, the user interface is simply three buttons, with a text area to describe what is happening.

Using buttons to remove the gems is not the only way this could have been handled. An alternative interface would be to have the player click on the gem to be removed. This would be intuitive, especially if the allowable selections were highlighted in some way, but without use of JavaScript would be a huge amount of work.

Friday, August 22, 2014

NES Trivia Title and Results

From a development perspective, the title screen of the game is not that important. From a marketing perspective, it is vital as it is the first impression of the game that a player will receive. My personal opinion is somewhere between the two points of view. You want a title screen to be attractive but you do not want to spend too much time on creating the title screen. Some decent artwork and perhaps some simple animation will probably suffice for smaller projects. For larger projects with big budgets, some type of CGI may be what the project backer insists on.

For trivia, out title screen simply shows a graphical title while waiting for a button to be pressed. More elaborate games may have a menu of options. Different modes of play, options, credits, and instructions are possibilities. Handling a menu would be done similarly to how we handled answer selection in the main game. The different options simply jumping to a separate routine for handling the particular screen.

The only hard part of the title screen is displaying the graphical title. Once you realize that the graphics are just a bunch of tiles, it is not much of a leap before you realize that you can simply print graphics. The only real restrictions being that you are not able to use character 0 as that is the character that is reserved for indicating the end of a string, and that the length of the string be under 256 characters. In our case, most of the title image is empty space so we conserve ROM space by breaking the string into individual lines. It would certainly be possible to take advantage of the consecutive nature of screen memory to have multiple lines of graphical information in a string. Still, here is the code used for printing the N.E.S. part of the title.

CallClearScreen ' ',0,0

CallPrintStringAt titleNES1, 5,2,0
CallPrintStringAt titleNES2, 5,3,0
CallPrintStringAt titleNES3, 5,4,0
CallPrintStringAt titleNES4, 5,5,0
CallPrintStringAt titleNES5, 5,6,0

And here is the data for the print statements.

titleNES1 .db 30,10,32,32,32,30,32,32,32,30,30,30,30,32,32,32, 9,30,30,10,0
titleNES2 .db 30,11,10,32,32,30,32,32,32,30,32,32,32,32,32,32,11,10,32,11,0
titleNES3 .db 30,32,11,10,32,30,32,32,32,30,30,30,32,32,32,32,32,11,10,0
titleNES4 .db 30,32,32,11,10,30,32,32,32,30,32,32,32,32,32,32,10,32,11,10,0
titleNES5 .db 30,32,32,32,11,30,32,30,32,30,30,30,30,32,30,32,11,30,30, 8,32,30,0

The rest of the title screen is pretty much more of the same, though the press start and copyright messages are ASCII strings. Once the display is generated, we simply use the WaitForButtonPress and WaitForButtonPressEnd functions to wait to start the game.

The results screen is rendered pretty much the same way though has the interesting problem of having to display the score. Thankfully the score is a single digit number. This means that to display it, we only need to add 48 to the number to get the proper ASCII value for the number. For numbers greater than 9 we would need multiple digits which adds the problem of no BCD or division functions for the NES. We will be covering software multiplication and division shortly, but it is a complex topic so it is nice that we didn't need to get into it before creating this game. Here is the code for displaying the score.

LDA SCORE
CLC
ADC #48
; the cursor is already at the appropriate position in the PPU so
; simply need to send the character index to the PPU
STA $2007

And that is all there is to trivia. Of course, having randomly selected questions and mixing up the answers so they were not always in the same order would be nice. This requires quite a bit of work as we need to delve into the topics of entropy, pseudo-random numbers, and software multiplication. Software division will be covered as well as we will need it for displaying multi-digit numbers which is something the target RPG will need for sure. There is a lot to cover before we can do the full version of trivia, though I may have a couple of other simple games before we get to trivia 2. But…that will not be done on this blog as the Blazing Games Development blog is being shut down. More on that, and where future home-brew articles will appear will be covered next.

Friday, August 1, 2014

Drone Defence Postmortem

It is a new month so time for my postmortem of my Blazing Games release for this month. The game is my first game created with OpenFl which is the flash-like library for Haxe. I am not sure why I decided to try doing a similar game to what I did as my Game Maker test game, but I did. The game needs a lot of polish yet, but for the limited time I put into it worked out great.

What Went Right

OpenFL is a flash-like library for Haxe. While Haxe already supports the Flash API for projects exporting to Flash, OpenFL expands this to all the other platforms that programs can be exported to. At least in theory. As I have done a lot of work using the Flash API, this is a great feature for me as it makes getting up to speed with Haxe much easier. If you are not familiar with Flash, this is probably not that big of a deal but it is still a decent library. I have tried a number of different Flash-like libraries for a variety of languages to various results. This library, from what I did with it, worked exactly like I expected (at least until I exported for HTML5) which was nice considering the learning curve that Haxe gave me.

Mixed Blessings

Haxe is a rather interesting language as instead of compiling to machine-language (or a virtual machine-language) it compiles to a number of different programming languages for a variety of different platforms. The idea here is that different platforms have different key languages for development. Windows is C++, IOS/OSX was Objective-C, Android is Java, the internet is HTML5 or Flash. The idea here is that you code in Haxe then fine-tune for each platform in it’s preferred language. It is, however, it’s own language with it’s own way of doing things. While similar to ActionScript, it is different enough to occasionally throw a wrench in the works. One of the nice things it does, which I wish C and all its decedents did, is automatically break switch statements unless you explicitly tell it not to. One thing I didn’t like is the requirement of iterators in for loops.

What Went Wrong

Unfortunately, as is often the case with projects still in development, there are issues with OpenFL. In my case, the HitTestObject method did not work in the HTML5 export. As this is essentially just a bounding box test, I replaced my hit test code with calls to check for rectangle intersections between the bounding boxes for the objects. The problem here then became there always being a collision. After checking the results of the getBounds function, I discovered to my dismay that the width and height of the object were the canvas size and not the size of the sprites. Worse, requesting the width and height of the sprite also returned the canvas width and height. These bugs don’t exist in the other export formats I tried so I ended up releasing the Flash build of the game instead of a HTML5 build like I was originally planning to. I will have to look into this issue a bit more as I really liked OpenFL and think if issues like this can be fixed this would be a great platform to develop for.

Friday, July 25, 2014

Designing NES Trivia

As I have said before, and have heard other people say as well, trivia is a trivial game to create. It consists of a set number of rounds. Each round has a question presented to the player with the player choosing the answer from one of a set number of answers. Once the player selects his or her choice, they are told if they are correct and an explanation of the correct answer is given.

This can be represented by a fairly simple data structure:
0..1 Pointer to label for the question string
2..3 Pointer to question string
4..5 Pointer to first (0) answer
6..7 Pointer to second (1) answer
8..9 Pointer to third (2) answer
10..11 Pointer to fourth (3) answer
12..13 Pointer to explanation
14..15 Correct answer number

The correct answer number only needs a single byte but uses a pair of bytes for the simple reason that this makes the structure 16 bytes. Powers of 2 are always nice to have as that allows you to take advantage of the bit-shifting operations instead of using more costly multiplication. When you consider that the 6502 does not have multiplication instructions, meaning that software multiplication needs to be done, this is a very important consideration. The actual implementation of a question looks like this:

questionInfo:
.dw q1_label, q1_question
.dw q1_answer0, q1_answer1, q1_answer2, q1_answer3
.dw q1_explanation, 2
; additional question info structures follow this...
; then we have the actual string data
q1_label: .db "One",0
q1_question: .db "The original Japanese version "
.db "of the NES was called?",0
q1_answer0: .db "Nintendo Entertainment System",0
q1_answer1: .db "Adam",0
q1_answer2: .db "Nintendo Family Computer",0
q1_answer3: .db "Nintendo Advanced Video System",0
q1_explanation: .db "The Nintendo Family Computer "
.db "became better known by the short"
.db "name: Famicom.",0

You will notice that strings are specially formatted to take advantage of the fact that the lines are 32 characters long. Extra space characters are added to fill out lines when necessary. While it would certainly be possible to write code to do the formatting for us, for this first version it is not necessary. The decision to write formatting code will depend on how much storage space is wasted by extra characters for formatting. When we get to the point where code to format text will take significantly less memory than will be saved by embedding formatting into the strings then it will be worth writing the code.

The game itself consists of three separate screens. The title screen and results screen are simple text displays with nothing special about them. The main game screen is fairly simple as well but has three separate phases of operation. The first phase displays the question and answers. The second phase has the user moving a pointer between the four different answers and determining which answer the user has selected. The final phase is determining the results of the user selection and displaying them as well as the explanation. Development starts with getting the game screen to work. Once it is working the game can be completed by adding the title and results screens. That is what we will be focusing on after next month's postmortem.

Friday, July 4, 2014

"First" postmortem

It is time for my Postmortem of the game that was recently released on Blazing Games. This game is called First as it is my first attempt at creating a game using RPG Maker VX Ace.

What Went Right

It is usually, if not always, wise to have a plan B. When the RPG Maker game competition was announced I knew I was going to attempt to create a game for it. A game that had a chance of winning would require a large time commitment so my plan if I was unable to finish was to forgo the contest and release my first RPG Maker game for July’s game. My first RPG Maker game was created months ago so it was ineligible for the contest. As the Blazing Games release for this month is my first RPG Maker project it is clear I never had enough time to finish the planned game. This was not a result of the game being over-ambitious but was a result of not having anywhere near the amount of spare time as expected. One thing you should always remember when scheduling projects is that unforeseen events (and for that matter, problems) will happen. In this case, the real game was roughed out but needed a lot of polishing before it could be considered a contender. With only a week before the competition deadline a decision on whether to reduce the amount of polish or go with my first RPG Maker project was in order. Had I known my Canada Day plans were going to be rained out, the choice would have been different.

The First game consisted of the player's home, the island map, and the Kobold cave. I quickly came up with a story, added the town and the related buildings, and modified the cave to fit the story. It is still a very simple game but still an entertaining fifteen minutes.

Mixed Blessings

RPG Maker VX Ace is actually a fairly nice tool. There is too much to discuss here so will discuss the tool next week. Using an existing engine saves you a lot of work at the cost of flexibility. While the scripting engine is very flexible and powerful, it is still a huge  amount of work to create a game that is vastly different from the base game that the engine was designed for. This has the unfortunate result that many RPG Maker games feel the same. This problem is true of other game engines, such as Unity and Unreal, as well. If you want your game to stand out, a lot of effort is required even if you are using an existing engine.

What Went Wrong

The biggest issue with the game is the size of the zip file. The reason for this huge file is simply that RPG Maker includes all the files in the resource manager even if they are not being used. This means that in order to get a smaller distribution file you need to manually remove the files that aren't needed. As I had expected RPG Maker to do this for me, no time was allocated for this task. Making this task trickier is the fact that I have very little idea as to which files are needed. Once you have worked with RPG Maker for a while this will probably be less of an issue. Of course, it is also possible that there is a way to get RPG Maker to do this work for you but I simply didn’t figure out how to.

Next week I will go over my thoughts on the RPG Maker VX Ace tool.

Saturday, May 31, 2014

NES Trivia Postmortem

For my Blazing Games June game I am releasing my NES Trivia game even though I have not yet quite got to it in the blog. See the what went wrong section for the reason for this. Needless to say, here is the postmortem.

What Went Right

The string library that was developed for general purpose use worked really well. Especially when the macros were used. Lots of the display-related code is very easy to understand thanks to the use of the PrintStringAt macro. While the StrNCmp function was never used in the game, it will be used in the sequel so the code was not wasted, just slightly premature.

Mixed Blessings

The whole reason for this game was to actually create a simple game fairly early in the series. As it turned out, there was a lot more foundation work that I had to write about before I could get to the meat and have a real game. Even at this point there are things that could be improved. The biggest being randomness. Right after that (before that for many people) is sound. Filling up the extra ROM space with questions and touching up the display finish off my list.

What Went Wrong

This was not the game I was planning on releasing for June. I was going to hold off releasing the game until we actually started creating the game in this blog. Unfortunately, the game I was hoping to release for June simply was too large for the amount of time I had available (and my Dad going into the hospital for a hernia operation didn't help). Using this game as filler material was my only option. Sadly the game I was developing is going to be delayed by at least a month as there is a big RPG Maker contest in June. While I suspect there are people who are far more knowledgable about RPG Maker that will probably win, there are real prizes for this challenge and I did want to try out the tool so this will be my June project. If the resulting game got enough interest, and especially if it won money, I would probably shift my focus to developing a full version of that game.

Friday, March 28, 2014

Coffee Quest 2600 postmortem

The Mini-Ludum Dare for this month had the theme of Demakes so I decided to create a version of Coffee Quest as it would be had it been created or ported to the Atari 2600. The link is http://blazinggames.com/gamejams/2014/MiniLD50/ but  it is going to be my April game. That means it is time for a postmortem.

What went right

For rendering the 3D view, the program emulates the play field graphics of the 2600 by having a function that takes the pf0, pf1, and pf2 registers along with 3 alternate values for the right side of the screen. While writing the rasterizer as if I was really coding for the 2600 took a lot longer than I like, it ensured that the resulting game was actually something that could run on the machine.  For me, the whole purpose of this challenge was to create a game that could actually run on real hardware. With a bit of work, it would be quite possible to create a full-fledged RPG along the lines of Coffee Quest IV on the 2600. Sure, the graphics would not be that great and a pretty big cartridge would have to be used but it is doable.

Mixed blessings

While the rendering is done the way it would have been coded for the 2600, the map is not. The map is 32x32 bytes which is far too large. If this was coded properly, the map would have been broken into a wall bitmap (which would have only taken 128 bytes of ROM) with an additional 16 bytes to hold the coordinates of the objects. The time taken getting the renderer working made this impractical so I went with a traditional tile map approach so the game could be finished over the weekend. As I know my reduced memory approach will work, this is not that huge of a deal as the game is clearly still possible.

What went wrong

I simply did not have the time necessary to create this game for the 2600 so had to roughly emulate the limitations of the system.  Having researched the 2600 before starting this project, I found the limitations of the platform really intriguing so was sad that doing this project for real hardware (or at least a properly emulated version of real hardware) was not practical. The problem is justifying the amount of time that would be required to create this game on a 2600 emulator. Even considering that modern tools allow for much greater efficiency in creating the game, I suspect that it would take at least a solid month of work to finish this game. With no real way of recouping the value of my time, this project is sadly not worth doing. If enough people were interest (or if someone was willing to sponsor the game) then I might reconsider this project. So, if anybody wants to see this project running on a 2600 emulator, email me at spelchan at blazinggames dot com and let me know.

Next week, partly as a continuation of this topic and partly to demonstrate how different machines can be when it comes to assembly language, I will be going over the Hello World program that I wrote for the Atari 2600. Just quickly going over what is required to do that simple program will give you much more respect for those poor 2600 programmers.

Saturday, March 8, 2014

The ASCII Connection

It is important to remember that the characters that make up a character set are whatever you want them to be. If you are using a memory manager, you may have multiple character sets and be able to swap them as needed. That means that there are no rules as to where letters appear in the character set or even if there are any alpha-numeric characters at all. If the game you are creating doesn't have any text in it, then there is no requirement to have any letters in the set. Even if your game has text, it may not be necessary to have the entire set of letters or you may even incorporate the words as part of other images.

All this freedom is really nice to have, but one thing to remember is that the assembler you are using to convert the 6502 assembly language code into machine language does have a format it uses. While this is not directly relevant to the resulting code that is produced, this fact can be taken advantage of to reduce the amount of work that you will need to do. You see, any strings that you use get stored as ASCII values. If you are not using ASCII then instead of using strings such as "Hello World" in your code, you will need to have a table of numbers with the numbers being the character indexes you used for the letters you want to display. This is simple but time-consuming work that is easy to avoid.

ASCII, which stands for American Standard Code for Information Interchange, is a rather old standard that was created in the early 60's to allow for a standardized way of transmitting information between computers. It is a 7-bit standard because 6-bits was insufficient for all the characters needed and 8-bits would require an extra bit be transmitted for every character which was deemed too costly. Remember that next time you send a multi-megabyte image to someone!

The first 32 characters (indexes 0 through 31) are control codes so these characters can be used for any graphics you want as they don't have a visual representation. 32 is the space character, 48 through 57 are numbers 65 through 90 are upper case letters, 97 through 122 are lower case letters and between these are various punctuation marks. This layout may seem largely random but if you convert the indexes to hexadecimal then you will notice that displayable characters start at 20, numbers at 30, letters at 41 and 61.

I am sure that if one looked, they would be able to find a NES ASCII Character set, but making your own set reduces the chance for any legal claim. Here is an image of my character set that I will be using as the starting point for the games that I will be developing. It is not the greatest character set, but is good enough for my needs. Any characters that are not needed can easily be replaced with other graphics, though I suspect that this will not be necessary for my projects.



Now that we have characters that can be displayed, we are ready to take a look at how to actually display things on the screen.

Sunday, February 23, 2014

Spikey Bird Postmortem

This post is slightly late as I wanted to create a game for Flappy Jam. I was going to do this last weekend but as is too often the case, things came up so my plans got postponed.

What Went Right

When I am coding a game, I tend to use the approach of just using placeholder artwork (generally coloured blocks and spheres) replacing it with art once the game is functional. Unity isn’t really a programming-based platform so this approach just didn’t feel right. Instead, the artwork was created first and plugged into the Unity project. This approach really worked well which probably isn’t too surprising as Unity is aimed at designers. The nice thing about this approach is you get something closer to the final product right away.

Mixed Blessings

Writing a script to generate the level on the fly is something that is right up my alley. Procedurally generated content in theory offers unlimited replay as no two games will be alike. In reality, the content always seems to be similar enough that the replay value is never as great as it should be. Controlling the difficulty is also not as easy as it would be with hand-built levels. When it comes to a graphical design tool you also have the disadvantage of not having the level visible until you are running the game.

What Went Wrong

One of the cardinal rules of Game Jams is “be familiar with your tools/language before starting.” I am not familiar with either Unity or with C# so developing a game using Unity with C# for the scripting language was probably not a wise decision. Of the 20 hours I spent creating this game, over half of the time was spent searching documentation and the internet for information. Minor things, such as finding the length of a list (C# Lists use Count instead of the length that I am use to) had to be figured out each time eating up not only the time spent in finding the answer but the extra cost of being knocked out of flow. That said, when you think about how quickly I could have created this game had I already been familiar with Unity/C# I can see why the platform is so popular. But if you are not familiar with the platform you are using, the short timespan that a game jam gives you is not the place to be learning a tool/language if you actually want to get something released.

My overall impressions of Unity are mixed. Lets face it. Unity is very much design driven while I am more programming driven. A lot of the way to do things in Unity are not the way I would do things but the power you are getting out of the tool makes it worth using. I can see how using Unity would make sense for a number of the projects that I want to do so I expect more of my games to be created with it in the future. That said, I am still at the very early stages of learning Unity with a huge amount still to learn.

Friday, January 31, 2014

Saga of the Candy Apple Scroll postmortem

My February game is my CandyJam entry so here is the postmortem.

What Went Right

Despite the rather long time that was theoretically available for the CandyJam entry, I knew that I would probably not have as much time as I expected and planned accordingly. Not counting the time spent playing with Unity (see mixed blessings), the game only took about 8 hours to create though had I been under tighter game-jam rules and had not been able to borrow artwork from some of my other games it would have taken a bit longer. I do not know what has been up with the last few game jams but having only part of the time to work on the game is a trend that seems to be continuing into this year! That said, if I did have more time to work on the game, I would spend the time working on my polishing skills as those are most definitely in need of work.

Mixed Blessings

It is never wise to try and learn something new when you are already under a tight deadline. I originally planned on using this project as my first Unity project as it is a very popular engine which may also be exactly what I need for some of my larger projects. I got bits of this project working and possibly could have finished it but things came up and the next thing I knew the end of the month was upon me. While it may have been possible to finish the game on time with Unity, I didn't want to take any chances so went with Flash. This gleaned enough knowledge of Unity that I should be able to create a simple game with it real soon.

What Went Wrong

Companies abusing IP laws. Technically this is not a problem with the project, yet, but the title of this game  very well could result in trademark complaints for using a common English word as part of my title. Far too often patent and trademark offices grant weak patents or trademarks and leave it up to the courts to decide if the patent or trademark are valid. This actually has the result of having the exact opposite effect that the trademark and patent laws intended. Instead of giving small companies the tools to compete against larger companies on a level playing-field, this gives companies with money (large companies) tools to attack companies without money (small companies) preventing them from competing. In the long term this is harmful to both innovation and consumers.

Friday, January 17, 2014

Planning my NES RPG Development Path

How much planning a project requires is largely dependent on the size/complexity of the project and the number of people working on the project. The more complicated the project, the more planning things out will make things go smoothly. It certainly is possible to complete a complex project without any planning, but the time required to do so will be significantly higher than the time that would be saved by proper planning. Planning doesn't need to take the form of formal documents, though if you are working with large teams a formal design specification document is probably a good idea.

I tend to design by working out what screens a game needs then breaking down each of the screens. After breaking down my NES RPG game I quickly realized that I could turn this project into a number of mini-games. These pieces could then be assembled together to form the core of the final game.

The first game is totally unrelated to the RPG but will have common code that will be used by other projects. It will be a simple quiz game. This will let me get my multiple-choice prompts working, number printing, random numbers, and some of the math routines. The 6502 does not have multiplication or division (other than bit shifting) so this has to be done in software.

Next will be a outdoor scrolling maze game. This obviously will be used for the game map screen. This will rapidly followed by a treasure hunt game using a scrolling covered map that only reveals itself as the player explores the map.

The final pair of pre-game mini-games will be the combat engine. This will be developed as a series of arena games. The first arena will simply be the combat with pre-determined characters and monsters. The second game will add the character stat screens and a store where players can buy equipment for upcoming battles.

At this point all the major parts of the RPG exist so they can be combined into a proper RPG. This will be broken into separate chapters so each chapter can be released separately yet be combined into a single larger final game.

Friday, January 10, 2014

Color Smash postmortem

When I heard about the New Year's Game Jam, I thought it would be perfect for my first game of the year. Unfortunately, I had some other plans for New Year's Eve which meant that I had a shorter period of time to develop this game. This is the postmortem for that game.

What went right

When I went to the NYGJ site to find out how the challenge worked, I noticed that they did not specify a theme.  Having the option to do anything is nice but if you can't decide what you want to do then there is little chance you will finish a project within such a short timeframe. Having a plan, at least in your head, is important for really time-restricted projects. Thankfully the site had a theme generator (1GAM had not released their January theme yet so I couldn't use that). While the theme I was given, click the button, was rather generic, it was enough to get me to focus on a whack-a-mole style of game.

Mixed blessings

Knowing that I was going to only have a short period of time to work on this game was both a disadvantage and an advantage. By anticipating a short development time I opted to go with a much simpler game than I would have liked to but it also meant that I was able to finish the game and even get a slight polishing pass.

What went wrong

Perhaps anticipating a New Years Eve party is what caused me to make a rookie mistake but a simple order order of execution bug stumped me.  With Flash, it is important to remember that the last playhead adjustment is the one that gets executed. This means a gotoAndPlay() followed by a stop() is not going to work well. This is a fairly obvious bug, but in my case things were a slight bit more complicated so obvious sequence was hidden from me.

For the lights I dispatch an event when an animation sequence finished playing then going to the default "off" animation to wait for orders to change the color of the lights. The problem is that the event dispatcher actually calls the event handling functions before returning. This means I tell my main game that it is time to start the next animation, which calls the light to set the color to the new value causing a gotoAndPlay() call to the appropriate color appearing animation. When the dispatcher returns, the light goes to the default off animation. Simply by moving the gotoAndPlay("off") call to before the dispatchEvent call solved the problem.

This bug is an important reminder that it is important to think about when things get executed. As the trend of having more cores instead of faster speeds continue, future speed gains will come from taking advantage of multiple cores, meaning that I expect to have to write more threaded code in the future. This makes order of execution issues even more prevalent.

Thursday, December 26, 2013

Schrodinger's Kitten Postmortem

My Ludum Dare 28 entry was a game-show style game involving kittens. As usual, here is the postmortem for that game.

What went right

Kittens. What? That's not a good enough explanation? When the theme was announced my first thought was "great, another theme that almost any game could meet with only minor changes." Then I started thinking of all the possible games and not only were there too many options to choose from but most of the ideas were too big for a weekend. With a need to narrow things down I went to One Game A Month and picked one of their three December themes. Kittens lead me to thinking about Schrödinger's cat which lead me to zombie kittens. Not entirely sure how this led to a Bayesian logic game but that is what came into my mind.

Mixed blessings

One of my biggest weaknesses is sound. Having a Gameshow theme allowed me to at least have sounds that I could actually handle. The results were not what I would call good, but neither was it overly bad. I did learn the importance of having a decent mike as my headset clearly does not qualify. The biggest issue was as I moved there would be clicking sounds caused by head-motions. I tried using audacity to remove the clicks but there were still some clicks that snuck through. Considering I had to use myself as voice talent, I don't think I did too bad. I tend to speak in a monotone so had to put effort into making sure that wasn't the case. I didn't quite get the Gameshow voice I wanted but I am not entirely sure what is wrong. I am thinking it is an issue with my delivery speed but I am not a sound guy so that is just a guess.

What went wrong

Time management was by far the biggest issue this time. Part of this was my fault as I really had a hard time getting into my programming groove so spent far too much time with distractions. Part of my time loss was the result of interruptions. Phone calls, relatives with computer problems, and neighbours that can't comprehend what a game jam is took up a good chunk of my time.  Considering the time of year, I suppose this is to be expected.

Overall, this was not too bad of a game but could have used a bit more graphical polish and a theme song. One of these days I am going to have to start playing with some of the music software I own. Then again, considering my sound skills, the world may be better off if I don't.