So, I decided to add some more basic combos in. Since I said it might be difficult coming up with interesting ideas for combos, one might wonder how I have already added some more into the game. Well, what I said was only half true. There have been some combo effects that I knew would be put into the game from the start due to the design of the enemy types. While this isn't so apparent without knowing how the game technically works, it will make perfect sense eventually. The total working combo effect count is now six. There are six more that I know I will be adding in for sure and that are also based on the design of the enemy types. After those six are finished the difficulty in producing more new combos will begin.
I might have added more, but unfortunately I was stumped once again by the strange Xcode warning/error combination where prebinding is disabled because of unresolved symbols, but the unresolved symbol(s) are not listed! It's simply blank! This problem is a big pain to deal with, as you have to go code hunting and see what changes you've made that might have possibly broken the build. Incidentally, while I was adding two new files to the project, I mismatched the source and header files. So, I simply renamed them. One would think this would go over all nice and dandy with Xcode, but it didn't. After a good chunk of time I finally decided that the code I had added didn't break anything, and removed/re-added the files to the project. Like magic the build succeeded and worked fine.
This is an experience to never forget. Hopefully if I run into the same kind of issue I'll remember it just might be stale project links (or whatever it may have been).
While adding more content to the dictionary of the game (just placeholder stuff) I noticed that I was doing some silly stuff like assigning strings to contain values that they defaulted to anyway. With this realization came a great opportunity to clean up some junky code that was absolutely unnecessary. Needless to say, adding new items to the game dictionary is a bit easier now. That's always a plus. Also, with the new content I added I was able to see how real-time the dictionary features were. Let's just say that stuff will register as unlocked in mid-gameplay. That means the user can escape out to the main menu, check out the dictionary, and go back to playing the game. Very cool, indeed.
In conjunction with adding new items to the dictionary, I've finally started adding some new combos to the game. This part is going to take a lot of work. Not only is it going to be tough to come up with neat and interesting ideas, it's going to be difficult to keep everything balanced--not having combos make the game incredibly easy and such. For the most part I haven't added any new combos. So far I've only worked out making some base classes that each combo class is going to have to implement. There are still a few details that need working out. To be honest, I might not be coding any of the combo effects until I flesh all of them out in a document, to see how they might play with one another and effect the overall gameplay mechanics.
Whether or not I'll put out a preview of the game without combos is still up in the air. I really want to get rid of those old screenshots, too. They are definitely not current anymore!
I added the one finishing touch that the high score screen needed: a confirmation message about clearing the high score table. This was a pretty basic update that didn't take too long to complete.
After doing so, though, I hit a pretty confusing roadblock. Playing with some packfile stuff (and using packtools), I noticed that packed files via the packer were no longer able to be read by my game. This, in itself was a big issue. I was certain that the packfile reading code in my game wasn't to blame. Something had to be up with the packtools... and something definitely was. They were currently unable to unpack any files I had made a few months ago. I was dumbfounded as to why they were acting this way.
Of course, I cleared them out and rebuilt them. It appears that when I was using them from my dock in OS X (drag/drop goodness), they were creating the init file within the .app, and not the .app's containing folder. Fortunately, this wasn't an issue that broke their operation in the past. All previously generated packfiles were perfectly fine. The trick that fixed this little issue was enforcing that the programs change the working directory to the executable's current directory. One can never assume what the current directory will be when running from a gui as opposed to the command line. I inadvertently made this mistake when I recently began using the applications from the drag/drop world as opposed to through the command line interface.
So, obviously, I have updated
PackTools to version 0.3. All that was added was a fix for changing the current working directory. It is cross platform across Windows, *NIX and OS X. There's a bit of #define goodness to determine which separator to look for: "\" or "/". Other than that, the PackTools operate just as they should, and correctly for all it's worth. Additionally, I've included some OS X icons that can be used for the PackTools if you so decide to turn them into .apps. I whipped up the icons quickly so I could differentiate between packing and unpacking when I put both apps in my dock.
Through testing things out in the Windows world I actually found a lot of problematic code within the high score class. I was inadvertently subscripting an array to one more than the number of elements it was actually holding. Needless to say, reading from that location in memory yielded much different results under OS X than Windows. This issue wasn't a true show stopper, but it would prevent high scores from triggering properly when checking against a high score table.
All in all, though, everything works as it should now in the Windows world. There are a few quirky things such as the tilde key showing up as backquote on a Mac keyboard vs Windows keyboard. I only use that key for debugging, so it's not really a problem in itself. That simply means that any time I'm doing stuff on Windows and want to cheat, create tons of enemies, boost my score, or any other debugging related stuff, I have to change some code around. It's not so bad. Everything else works perfectly fine otherwise.
There are a few issues that have been sitting around in my To-do list that I'd like to clear out before continuing on any new stuff. These items include a few design related issues that may or may not be quick to resolve.
All-in-all I'm very pleased with the pace of progress lately. Although I'm not tackling large amounts of issues with each update, I am still getting a considerable amount of work done. By keeping the amount of work I do in between updates on the lighter side I am able to maintain a good balance of motivation and interest. It also definitely helps reduce burn out.
There's lots to report tonight! There now exists an extremely basic "Game Over" screen that essentially consists of the text "Game Over" in the upper left hand corner of the screen. Everything else is just plain black. The screen fades in and out, and that's about it! I wanted to have something there to show that the game has ended, and this will definitely do the trick. If the player has a high score at the point of dying, they will be prompted to enter their initials and then the game over screen will appear. If not, the g.o. screen will appear immediately. One nice thing about this whole setup is that the functionality for showing a death animation already exists. I simply have yet to whip up some artwork of the player dying. This is something I'll add at a later stage.
You might think I'd stop here, but, no. I have also implemented the high score screen! Finally! The screen is, like everything else I have been adding these days, extremely basic. It just displays a very boring-looking list of initials and their corresponding high scores. Two options are available on the screen, one for exiting the view and another for clearing the high score database. One little thing that still needs implementing is a confirmation dialogue that will pop up when the user chooses to delete the current high score table.
With all of this stuff finished, it's about time to do a bit of testing on the Windows side of the world to make sure everything works as expected. I will have to do some more robust testing than the usual "let's simply see if it runs." I'd like to be confident that everything in regards to high scores works properly and flawlessly. Once testing is done I'll have to take a look at my current To-Do list (which, honestly, doesn't have that many unchecked items on it any longer) and then decide what the next big step is in terms of development.
There are a few time consuming tasks, mostly art related, that I could delve into, but they aren't that high on the priority meter. I may very well use the stage of the game as a small testing bed for whether the playability is actually fun, or leaves something to be desired. With most of these features intact users will be able to let me know what other options of features should be added, and which should be beefed up. As always, packaging everything up and getting it ready for any kind of testing (even testing done by a select few, hand picked, individuals) is time consuming. I'll be fleshing out more of the details regarding this as the days progress. First, I need to see how the windows portage/testing does.
There's lots to report tonight! There now exists an extremely basic "Game Over" screen that essentially consists of the text "Game Over" in the upper left hand corner of the screen. Everything else is just plain black. The screen fades in and out, and that's about it! I wanted to have something there to show that the game has ended, and this will definitely do the trick. If the player has a high score at the point of dying, they will be prompted to enter their initials and then the game over screen will appear. If not, the g.o. screen will appear immediately. One nice thing about this whole setup is that the functionality for showing a death animation already exists. I simply have yet to whip up some artwork of the player dying. This is something I'll add at a later stage.
You might think I'd stop here, but, no. I have also implemented the high score screen! Finally! The screen is, like everything else I have been adding these days, extremely basic. It just displays a very boring-looking list of initials and their corresponding high scores. Two options are available on the screen, one for exiting the view and another for clearing the high score database. One little thing that still needs implementing is a confirmation dialogue that will pop up when the user chooses to delete the current high score table.
With all of this stuff finished, it's about time to do a bit of testing on the Windows side of the world to make sure everything works as expected. I will have to do some more robust testing than the usual "let's simply see if it runs." I'd like to be confident that everything in regards to high scores works properly and flawlessly. Once testing is done I'll have to take a look at my current To-Do list (which, honestly, doesn't have that many unchecked items on it any longer) and then decide what the next big step is in terms of development.
There are a few time consuming tasks, mostly art related, that I could delve into, but they aren't that high on the priority meter. I may very well use the stage of the game as a small testing bed for whether the playability is actually fun, or leaves something to be desired. With most of these features intact users will be able to let me know what other options of features should be added, and which should be beefed up. As always, packaging everything up and getting it ready for any kind of testing (even testing done by a select few, hand picked, individuals) is time consuming. I'll be fleshing out more of the details regarding this as the days progress. First, I need to see how the windows portage/testing does.
I drilled out a basic high score initials entry screen tonight. I was honestly amazed at how easy it was to implement. With the way I had my system designed, mostly in regards to starting a new game and having my logic function pretty open for setting up usable return values, it was a cinch! Currently it displays three initials (AAA) on the screen in the overused Allegro font, along with an "end" item. The current selection lights up red, and the user can select a letter by pressing up/down. Pretty basic stuff.
The screen is in a pretty presentable state. It uses a custom font and handles all input as one would expect it to. Unfortunately, it uses only the arrow keys as input. I'm torn as to whether I should make it use the current user assigned keys. I'm leaning against that for now, as I'd like all menu driven interfaces to use the arrow keys, the enter key, and escape. Of course, if a joypad is installed and in use, I would have that be able to control the menu systems. This is something I'm going to look into. Additionally, there is no text notifying the user that they've achieved a high score.
On top of all of that, there still isn't a proper "You have died," or "You lose" message that appears. I'll be adding one of these in soon. Once all of that is done, it's on to the one last thing that needs to be done in order to have high score stuff truly complete: the high score table viewing screen.
The high score class was integrated into the score manager class and works exactly as one would expect. When the player "dies" the current score is checked, and written to file if it is indeed a high score.
There's still a lot to do before I can mark of high score stuff as being fully implemented, though. I need to create some sort of method for inputting either a full name or a set of initials from the player when a high score wants to be written to file. Using three initials to mark a high score as your own is what I'm leaning toward at this point. I've envisioned a very cool looking version of inputting initials in my mind. Of course, inputting initials is never too exciting: you pick the current letter and scroll through a list of available letters, numbers and/or symbols. What I mean by "cool looking" is visually appealing and stylistic. For now, however, it will probably be bland and very basic looking (as usual, that is until I can gather some talent in the art department).
I also still need to implement the high score viewing screen. For this I probably won't take up too much time doing fancy graphical stuff either. I'm really pushing towards just getting something functional for the most important aspects of the game now, and refining it to look nicer and nicer as time goes on.
What I'm really concerned with at this point is whether people will think this game can succeed as a whole and, of course, is fun to play.
I decided against splitting the high score class between a plain C-style i/o version and an Allegro packfile version. Instead I made the class handle both types of file operations. There is no difference in using one or the other besides calling a different constructor. Other than that, they operate in exactly the same fashion and use all of the same accessor functions in order to give the user information about a high score table.
Now that I have that done I simply need to integrate it into the score manager of my game and implement a proper working high score viewing screen. I don't know for sure yet how I will be storing the name that goes along with the high score. I believe that, more than likely, I will use an "initials" system, but that may change. The problem with doing real keyboard input is that the default Allegro dialog stuff is kind of ugly. I think if I do choose this route I will end up writing my own routines to handle the keyboard input.
Balancing is going along okay. It's very difficult to gauge just how challenging the game is, so I'm going to leave it as is for now until I can have some close friends test it out and see what they think. My original thoughts about what values I could use for certain aspects of the game were off by a huge amount! Needless to say, the game with the values I did have in there before I took a good look at balancing was essentially impossible!
I've moved onto getting the high score stuff to actually write a score table to the disk and show a list of scores in the high scores screen. I've run into a bit of a predicament, though. While I have a class that manages writing/reading high score tables, it wasn't written to support Allegro's packfile functionality. This is something I would like to have it support. Unfortunately, it seems a bit overdone to have a packfile version and a regular C-style file i/o version. Since Allegro uses a PACKFILE structure and, obviously, pack_* routines, I would have to have two versions of "technically" the same code.
I think my main course of action will be to make a good copy of my plain C-style high score class and make a separate version that works only in Allegro packfile mode, either writing the file encrypted with a password, or in plain readable format. It shouldn't be too much work to make the change.
I fixed a minor issue where customized keys weren't being set properly. If custom keys were set in the options screen and a game was resumed / started, the effect of changing the keys would not take effect until the game was restarted. I fixed this by remapping the keys soon after giving them new values.
Some older bugs and issues that had been lying around for a while were also fixed. One of them had to do with "communication" between two objects. Put more simply, an object of one type was dependent on information from an object of another type. I finally formalized a solution on how the two could communicate without circular dependencies. Each object type needed to know information about the other, but were unique enough that they should remain two separate objects. I'm glad to know I have this issue smoothed out. Prior to my fix I was using some "magic number" goodness, which is really bad. There is still a bit of magic number stuff in my solution, but it can't be helped: it depends on placing a specific sprite at a visual (only) location on the screen. There's no real way to calculate the value other than modifying the sprite structure to take hotspots that can be used for any purpose. This isn't something I need to add to my sprite class just yet.
I had a fun time playing with level balance today. It was my first real attempt to make it seriously work properly. I'm going to be spending a lot of time tweaking values here and there until it seems be work out decently. Of course, this will all change once other people who aren't used to the game start playing. High score implementation will have to wait until level balance is complete.
The graphical part of resuming or starting a new game once one is already in progress is essentially complete. I could add more eye candy to it, but that's absolutely unnecessary at this point, so I am going to leave it as-is. In doing the entire resume/new game fix I had to implement a dialog window that gave me the opportunity to see something that was lacking from my text bubble class for a long time: instant text! Up until now, the text bubble class was only able to display a text bubble with letters that appear one after the other. The resume/new game text bubble needed to have the text appear immediately. To make a long story short, I added the ability for the text bubble class to create text bubbles in which the text appears immediately after fading in. It works very nicely and was pretty easy to implement.
In doing more tests of starting a new game after one has already been started I noticed a few more areas that were not being reset. These required minor changes and are now fixed.
While actually playing the game just for fun I stumbled upon a most obscure and hard to discover bug! To get this bug to show itself, the player has to dash--and while dashing jump, and while jumping use the special teleport ability all in one sequence. This only happens if the player is moving from left to right. If pulled off correctly, the player can get stuck in midair and appear that they are running in the right direction, unable to use any controls to do anything. I was quite surprised when I stumbled upon this one. I'm glad I did, because it would be a tough one to track down if someone other than myself had produced it. The main problem at hand was simply not setting a flag to a false value in the event that a teleportation is occurring.
And just like that a month has flown by. I could always attribute the lack of updates to school work and the transition into my new job, but that's only a portion of the reason. The rest of it can be attributed to a sever black hole of motivation!
I was able to get working on some stuff today, which is nice. I implemented the ability to resume or start a new game once a game was already in progress. It turns out that I needed to add a lot more stuff than was necessary. Originally I was going to have the function that handles all of the title screen stuff reset values to a "level 1" state, but that turned out to be more hassle than it's worth. There's a lot of stuff that has to be kept track of during the main game loop, which was just too much to pass to the title screen function. It just looked a tad ridiculous. Instead, I changed the function from returning TRUE/FALSE to returning three different values instead: a normal ok, a quit request, and a new game request for when a game is already currently in progress.
Using this method I was able to simply check the return value of the function and process what needed to be done accordingly in the main game loop, where I already had access to many of the structures that keep track of the main game data. It works out quite well now. Unfortunately, though, I still haven't put in the graphical component of it. As of right now, only the textual component of the option for starting a new game changes into "Start/Resume game." Then, after that, there's a nice invisible selection of "Start a New Game" and "Resume Game," along with a nice message about the fact that there is already a game in progress. I still have to, of course, make all the graphical content for this but, that's how it will work at least.
It wasn't a huge chunk of progress I made, but some progress is definitely better than no progress at all. After implementing that there are a few bugs on my list that need fixing up. They mostly require the addition of a few functions that will do extra work once the options screen has been exited. Once all of that is finally finished, I might take a look at properly implementing high score stuff. All of the framework is there. I simply need to have the score get saved and add a proper score viewing board.