Showing posts with label January Engine. Show all posts
Showing posts with label January Engine. Show all posts

Tuesday, March 19, 2013

Dev Log: The January Engine's Existential Crisis


When I began working on the January Engine, I had only a vague notion of what I wanted: some kind of RPG using cards as a battle system.  I was really doing it to keep up on my coding skills.

After seeing that it was possible in a rudimentary way, I set the January Engine aside for some time, moving on to other projects that I was more excited about and had more detailed designs for.

Doom Monthathon Level
Like this.  Or The Vortex.  Or HeroQuest.  Or...
When I picked it back up, I switched gears and tried designing a unique card-based battle system that didn't just take RPG staples and cardify them.  I considered a board game or RTS hybrid, and begin working on coding that, giving the January Engine a second life.

But even then, that kind of dropped quickly, partly due to other work, partly because I was having some trouble designing the system.  I came up with some interesting mechanics on paper, but I never solidified them beyond the primary stages of concept.

This, of course, meant that programming could go very few steps ahead without hitting a wall of I-don't-know-what-to-do-next.

January Engine hex screenshot
And then things get weird.
As I've discussed previously, the art in my head can't come out in my hands.  The problem that arises from this is that whenever I start a project with high artistic ambitions, it's a guaranteed failure, especially if the art is a necessary component of the game.

As I began working on my second iteration of the January Engine (with a hex-based RTS slant), I imagined something much different; something impossible as a solo project, so that iteration could not possibly work.

I'm taking a step back (or three) and reevaluating truly what I want from the January Engine.  Sure, it began as coding practice, but I am not satisfied with that.  If that was all I wanted, I could open any programming tutorial and follow it, making silly things like cash register programs to keep my programming skills sharp.

So with a new perspective on things, I'm going to give the January Engine another shot.  This time I'm designing a project that is somewhat code-heavy, but easy on the art.  I must force myself to keep the art needs as simple as possible, and any time I think about making anything more complex than EGA graphics (classic King's Quest), I need to stop and slap myself in the face.

Having the adage of "graphics so simple even I can make them" should reign in any wacky ideas of mine requiring beautiful art, and force the design to stand on its own.

Of course, even if you have the most amazing graphics in the world, game designers should pretend art doesn't exist, so they don't become over-reliant on it.  I have seen too many professional games with amazing graphics but lackluster gameplay, ending in a disappointing game.  Heck, that lesson should have been learned during the early 90's FMV detour.  Somehow every game designer has to relearn that concept (myself included).

But anyway, before I rant on about the industry, I'll go back to the January Engine:

I'll being hitting the reset button on it, and concentrate on coding something both challenging and interesting.  I've got some new ideas and I'm testing the waters in C++.  Right now things are frustrating, but that's more of the cold shock after jumping in, and once I get warmed up things ought to be smoother.

Tuesday, December 11, 2012

Development Log: January Engine - Week 7


Been a while with this project because I've been spending a lot of time with paper-and-pencil, which doesn't upload well.  However, I have the .swf in its latest state uploaded, which you can play HERE.



Changes from last time include: making the hexes you can't click on invisible, smoothing out scrolling (which can be done with the arrow keys or WASD), and cards at the bottom, representing your hand.  Refresh a few times to get either two Yellow Cards or two Green Cards.  If you do get them, you can pass your cursor over green/yellow hexes to see a popup which indicates that you can place green/yellow squares on the hexes.  (Well, you can't place stuff yet, but I'm showing that I have the code in place to understand combinations of cards).

Now, that's not particularly too much work done, code-wise, but I've done a lot of design work:

The game I am designing is a combo of Magic: The Gathering and am RTS.  Basically, you use simple resources which are in your hand (as shown in the demo), to combine and create units, buildings, and spells, and place them on the hex grid.  The units/buildings on the grid are represented by icons, but they can be expanded to view the stats of it in card format.

As for the goal of any given level, I have many possibilities, but I'm not sure which I like best.



This card shows you all of the possible stats you may have on a unit or building card.

On the bottom, the seashell-shaped swirls are health.  Any unit or building can have between one and five health.

The tricky things are on the left.  The large hex is the primary color of the card, and is the color hex you can place the unit/building on (if it's a unit that can move, all that matters is that it's initially placed on that color).  It is also the first color resource card you must use to place this unit/building on the grid.

The next six hexes below it are other resources needed, and they can be the same or different color as the primary resource.  Black indicates any color resource.  The majority of cards will take less than seven resources, and the hexes will simply be missing to avoid confusion.

The next three hexes, A, R, and M, with numbers inside, represent Attack, Repair, and Movement stats.  Attack is how many resources you must pay to attack another unit/building with this one.  Repair is the number of resources it takes to repair one health point on this unit/building.  Movement is how many resources it takes to move this unit/building (usually a unit) one hex space.  These stats are always black, so you can use any color resource to do it.

The bullseye and the human eye below represent range and sight, respectively.  If the unit/building can only attack in melee range, the range is one.  Sight is used to remove fog of war.

As you can see just by this one card, this is shaping up to be a radically different game than I began this project as, and I like it a lot more.

Tuesday, July 17, 2012

Development Log: January Engine - Week 6


O ho! Finally got back to coding, after significantly changing the design.

I've been spending a lot of time going over what I want to do with this, on paper, because I found that winging it was not as rewarding as I expected.  So now I've got some semblance of a design, and it is more than just making an RPG with cards.



The battle system will now work more like a combination board game and collectible card game.  You go through the overworld finding cool cards (just like before), but you use them in battle to capture hexes, upgrade buildings, and a ton of other stuff to get you points.  Whoever reaches a target number of points faster, wins.

Ultimately, it ends up sort of like a CCG/RTS Settlers of Catan hybrid.

Of course, little of that can be seen right now.  What is there is just a hex board, with black indicating placeholder hexes (which can't be clicked on), and other colors of hexes, which will represent resources and factions.

As you pass your mouse over hexes, a little box will pop up over each.  What I hope to do it have those boxes give you options of what you can do in that hex based on the cards in your hand (and sometimes you can't do anything).

You can also use the arrow keys to slide around the board, since it won't all fit on one screen.  I'll also add WASD controls next week, or make it move when the mouse reaches the edge of the screen, but that may be too annoying for both the player and myself.

There is also code for dealing a hand of cards and a player deck, but at the moment it won't display, so that'll probably be for next week.

In the meantime: You can "play" Week 6 here (though there's not much to play).

Friday, December 9, 2011

Development Log: January Engine - Week 5


I figured out the weird keyboard error in regards to flash games and WASD controls not working.  Turns out it's Comcast's Constant Guard that messes up keyboards, changes screen resolution, crashes Google Chrome, and a host of other problems.  Now that that's uninstalled, I quickly added WASD controls back.  (You can still use the arrow keys if you prefer, as well.) 

I had thought initially that the problem was a Flash or Chrome thing, but it was magically something that you would think would be completely unrelated.  If you have Constant Guard, uninstall it immediately.  The Norton product that comes with it will still be installed and working on your computer.

Beyond that, I spent the majority of the week working on the inventory system.  I knew I wanted the player to be able to look at their cards, open new booster packs they find, hold onto cards not in their deck, and swap out cards in their deck.  The player can't swap out cards, but the rest is functional.


As I created the inventory, however, I also came up with an idea to allow the player to change the rules.  The player will find rule sets that change some conditions, such as max health, max/min cards in deck, and may also limit what cards the player may use in their deck (I'll have to revamp the card system to allow another variable or twelve that limits which cards are allowed with which rules).

At present, there is only one rule set, so it's mostly just for display at the moment.

There is also functionality for unique quest items, although I have none to test yet.

One bug is that when you pick up a new booster, the inventory menu hasn't refreshed to show that you picked one up, so you need to check your deck to clear the top level inventory menu, then click OK, then the "New Booster" option will appear.  Currently, if I fix that bug, then a new bug pops up:  if you leave the inventory while checking your deck and then enter back in, you will see the cards you were looking at, plus the top level inventory menu overlapping.  I figure the refresh bug is a nicer bug to deal with.

Also, I am sure that you can get the booster from the first NPC an infinite number of times.  That'll be fixed next week.

I find that I spend a lot of time rearranging the code as I discover it's necessary to do so to implement a feature.  Oftentimes, before I can even implement the feature, I reorder the code, then spend an hour fixing bugs that have appeared as a result of that.  This is definitely due to the fact that I'm coding on the fly rather than preplanning or engineering it beforehand.  It's a lesson for the taking.

But I'm enjoying it; I'm learning how to hack things to fit my desires, even though I'm certainly not programming as the language was designed.  I think it's because I never got a strong education in object oriented programming; most of my programming skills come from learning Pascal in high school, and I can't say I was "taught" any OOP in college, so only traces of the structure and vocabulary stuck.  I understand the theory behind inheritance, for instance, but the implementation kills me, so I avoid the headaches that come with it.

I've heard of structures called Singletons, though I never learned them (they aren't in AS3 anyway), so instead of creating one for the inventory, I just made static variables, while the overworld and battle systems act as singletons in function, if not in name.

I also want to design the engine so that the user who wants to make worlds/levels can edit one file without touching the rest of the code, so the maps, npcs, enemies, card types, and more are all in one fairly clean file of variables that can be edited without too much trouble.  I bet this is terrible practice, so I may split them up soon, but hopefully it will remain as user-friendly as I can possibly make it.

PLAY WEEK 5 HERE.

Or read on to the next log, where things get mighty different after a hiatus...

Tuesday, November 22, 2011

Development Log: January Engine - Week 4


It took me a while to get back in the groove of programming the January Engine, but it's coming along now.  Unfortunately the holidays may cause sporadic updates on it.

I've added NPCs, which you can talk to by clicking on them.  Originally I had it so you walked up to them and bumped into them to talk, but I thought that was kind of silly.

"And he clicked the purple N, and the N talked, and he saw that it was good."
There are also health pools now (blue squares with "H" in them), which restore you to full health.  This is useful because now after finishing a battle your health stays the way it was when the battle ended, instead of automatically regenerating.

You can also die now.

I added some colors just so the screen isn't purely black-on-white, although when I start adding "real" placeholder art it will all change.  But in the meantime, the colors allow you to know what you're doing at a glance.  For instance, you quickly memorize the color scheme for the battle cards, so you spot a "Damage 3" card just by color without having to read it.

I also learned how to embed images, although I won't be adding any art until I actually learn to make something decent.  I tried making a simple dirt square a couple of times with bad to worse results.  A friend sent me a link to a Gamasutra article on 2D art for programmers, and currently I have yet to make any art remotely on par with the article writer's.  Basically, I'll add art when it looks better than the textfields.

I also restructured the code so the Overworld section is not in Main; it's its own class like the Battle Class, so pretty much the only things in main are the ENTER_FRAME check that determines if a battle should occur (and wipe out the Overworld) and bring back the Overworld when the battle is over.

I don't like ENTER_FRAME checks, because I feel like there is a better way to accomplish something.  ENTER_FRAME always seems to me like a waste of memory.  Instead of the event listener, I think there should be an event shouter, if that makes any sense.  Unfortunately, there is little in the way of making that work, so I just try to remove the ENTER_FRAME check whenever possible.

I also added an inventory button, which doesn't work, so don't bother.  I think I'll be making that functional for next week's log.  The inventory will allow you to look through your deck and see what cards you have.  Eventually I intend to make the deck customizable, so you can swap cards in and out to get a deck to your liking.  But that'll probably be much later.

So next week I think I'll be trying for that inventory functionality, as well as making the enemies move around.  I might also have art, if I'm not too frustrated by it.  I figured I could always make intentionally bad art, but it's tough to even get up to bad quality.

Thursday, October 27, 2011

Development Log: January Engine - Week 3


I took a break from working on the battle system to make an overworld map system.  I think that by working on both sections at once, I can bounce between them when inspiration strikes, and if I'm stuck on one I can just go back to the other for a while.

Colors!
Currently, the navigation system works as a grid where the player (the "P")  can move through empty spaces, but not into spaces with "X"s in them.  You use the arrow keys to move.

Ridiculous sidenote:  I wanted the player to be able to also use WASD controls, but there is something weird going on with keyboard commands in Flash recently, and it's not limited to just this.  It may be a Chrome bug or a Flash bug in general, but I find that whenever I play a Flash game, a host of problems occur when I try to use the letter keys, from the program thinking I'm holding down the button when I let go, to it thinking every key I press is the same key as the first I pressed, to the opposite problem where a single key changes to a new keycode every time I press it (so I press "wwww" and it comes out as "wert" etc.).  This nasty bug happens with every Flash program I use, so it basically makes WASD controls untestable, so I decided to just throw them away until Flash or Chrome or whatever the problem is fixes itself.  When this gets fixed, I will quickly add WASD controls to the engine.

Walking into an enemy (the things labeled "E1") causes a battle to occur.  When either the enemy or the player loses all their health, the battle ends.  (There is no game over screen yet, so even if the player loses, the player actually wins.)  Then the game goes back to the overworld, and the enemy is beaten.

The player can also move through the path to the left and end up on another screen.  The map system works kind of like the original Legend of Zelda, without the fancy scrolling.

And without the fancy... everything.
One bug to keep in mind is that the flash player needs to get the focus, so you need to click on the screen before you can use the arrow keys.  And for some crazy reason, you have to click every time you shift from one map to the next, which is a bug I'm still trying to figure out.

As for the coding itself:

I discovered the Vector data type, which is an Array of only one data type, while an Array can hold many data types.  Besides being more convoluted to declare, the Vector is less computationally intensive, I would have to guess, so most of the things I made as Arrays have been switched to Vectors.

Each individual map is a Vector of Strings, which gets created into the visual grid when the player moves into it.

To figure out which map to load as the player moves between them, I made a Vector of Vectors, which holds the smaller maps in order so I can just reference them by their location in the overall map.

I've got a few tasks to do for next week, including making the enemies move randomly around the map (or even follow the player to attack), making a game over condition, and fix a few battle bugs.  But the fun task that I'm looking forward to is making some NPCs with dialogue boxes that pop up when the player approaches.

Thursday, October 20, 2011

Development Log: January Engine - Week 2


Well, not much appears to have been done on the surface, because I spent the majority of the week cleaning code and making it smoother.

And the cards are shaped like cards.
Now, the enemy can do everything the player can do, and uses the same functions.  A simple Boolean keeps track of whether it's the player's turn or not.

I also created a separate message box (in the bottom-right) for most text.  The text above the health of the player and enemy are there mostly to show what their current condition is (stunned, confused, etc.).

I think some of the messages still go unseen because I don't have enough timers to wait between messages, so there still needs a bit of work to be done in figuring out exactly where the timers are needed.

I have also capped each character's health (at 10 for the test), so neither the player nor the enemy can heal above their max.

At the moment, the enemy chooses a card at random, which can result in the enemy doing some very silly moves, so eventually I'll have to come up with some AI for the enemy so they don't act so dumb.  They should act as if they have a five-card hand as well, and pick the best card for their situation.

The battle ends when one character loses their health, but since there is no overworld to go back to, it simply ends, and erases everything after a second.  I need to add a pretty win statement in the message box, but at the moment, have no fear when the screen goes away; it's not broken.

I currently have the win/loss check on ENTER_FRAME, but I think there ought to be a better way to do it, such as only when a character takes damage, but the win condition check is in Main, not in the Battle class itself, so things might get a little convoluted for a while.

I am finding I have to reference strings multiple times, and that always makes me a bit uncomfortable.  Often, a case will throw out an error because of a typo or change in vocabulary that I did not completely implement.

The "Confused" condition adds a secondary case (since if you're confused, either your move doesn't work or affects the opposite of the target), so I'm thinking of getting rid of it, just to simplify things a ton.  Besides, while confusing the enemy is fun, being confused is not, and I want all player actions to be playable by the enemy as well.

I've also added some code to make sure the player doesn't have duplicate cards (an odd recursive check ensures that the index of the card in the deck array is not the same as any other card in hand).

I think I had a non-recursive function originally, which lowered the odds of having duplicate cards, but did not wholly take care of the problem.  Now there should be no duplicates.  (The player may have more than one of the same type of card, because there is often more than one of each card in the deck, but since the player only has one Confuse card, for instance, the player should never get two of them in hand).

I think I may still have an error or two in the logic, because being stunned appears to last way too long (unless the enemy is stunning me multiple times, and the output is not particularly clear).  I have an int that keeps track of how many turns a character has been in a condition which -=1 each turn.

Man, I feel like I need to write daily notes, rather than summing up a week, because I forget what I've done since last week.

Thursday, October 13, 2011

Development Log: January Engine - Week 1


I have now created a simple card-based battle system.  The pretty pictures and epic music score comes later.  Also, the descriptions on the cards word-wrapping.  Details, details.

And the cards should probably be card-shaped.
Anyway, the player is given a starter deck of forty cards, and is dealt a new hand of five random cards every turn.  The player can choose among them what to play simply by clicking on them.  The odds of drawing some cards are very high (a card dealing two damage is 3/10) and others are very low (Confuse is 1/40).

I have currently created the most basic variety of RPG moves:

Simple damage
Heal self
Confuse
Stun
Block

All of these work (I think), except that Stun is a tad buggy (the enemy stays stunned unless you Confuse or Block).

Also, Block may appear to be ineffective, but Block only blocks one damage point, so if the enemy deals two or three damage, the player still takes some damage (normal damage - 1 for blocking).  Only if the enemy deals one damage does the player completely block the attack.

Sometimes you can't see what's blocking you.

(I'm sure that the system is horribly imbalanced and doesn't give particularly good feedback, but that doesn't matter at the moment.  Details, details.)

The enemy is also given a deck of cards and chooses randomly among them.  However, for this simple battle, the enemy can only do direct damage.  I will later add the same functions for the enemy (or clean my code and make the player and enemy functions one and the same).

Also, the player cannot see the card the enemy has chosen, and at present I am not sure if I want the player to actually see it, or just feel its effect.  I may play with that idea and decide what is best.

There is currently no win condition, and both the player and the enemy's health can go below zero, and it is next on my agenda to make victory and loss conditions.

As for the work done, I found it a small challenge getting back into the swing of coding AS3.  While I began with reservations about how much I would remember, much of it came back to me quickly.  Code is just like learning a foreign language:  when you have to use it after you've forgotten it, you remember more than you think you do.

English on the left, AS3 on the right.
But for problems with coding:

I am always annoyed at adding event listeners, because the function you put in as a parameter cannot have its own parameters (or if it can, I am not sure how to do it).

To get over this, I created a class called Battle which acts as a manager for the battle, not only holding various functions such as dealing cards, etc, but also holding variables which could not otherwise be passed.

The creation of timers to delay messages were similarly handled.

I've considered recreating my own versions of these built-in functions to fix that, but at the moment I'll take the path of least resistance and just walk around the mountain, rather than climb up it.  It may become necessary in the future to do so, but for the moment, as long as I am getting basic functionality, I'll worry about cleaning my code later.


(If the screen is magically green when you try to play, just refresh and that should fix it.  I think it's a Google Chrome bug but I'm not sure.  Other browsers may or may not have this problem.)

Thursday, October 6, 2011

Development Log: January Engine - Week 0


I enjoy a good turn-based, top-down, NES-style RPG, so I've decided to create my own RPG engine that takes that classic experience style and mixes things up a bit.  Or a lot.
This menu business is the first to go.
First, I will be taking a look at the battle system, as that is the heart of gameplay in an RPG.  I've decided to dispense with the menu-driven battle system, but keep the turn-based nature of old RPGs.

So I've come up with a simpler solution: make the battle system feel more like a CCG.  Instead of normal attacks, magic, or items, the player has a deck of cards, and randomly draws five cards each turn, and picks from them.

This card battle system also dispenses with MP, a notion that always seemed silly to me.

While this limits the player's options, it makes the interface simpler.  All the player has to do is select their card of choice, and all five are displayed up front, so there is no digging through menus.

Once the basic battle system is in place, I will move on to other aspects of RPGs, taking things one at a time, until a full engine is in place that can be used to make a small sample RPG that uses each function of the engine.

So next week you'll see how far I've come to creating the battle system, and you'll get to play what I have.  There won't be much in one week, of course, but the basic (placeholder) interface will probably be done, if not the functionality.