Worklog for Foppy
Wizard Battle 2Return to Worklogs
| The game is finally finished. I have to say I dropped some features, to avoid spending another year on the same game!|
At the last moment I have made a change that I think makes it more fun: the wizard now never stops walking. All other units stop while attacking, but I found that in this manner the wizard would never reach the other side, and games would last forever.
The game can be played in HTML 5 and Flash formats on my website:
There's also an Android version:
Wizard Battle 2 on Google Play
And here's a final video! :D I'm playing from the left.
- shorter fireball reload time
- unit selection graphics
- special wizard attack: wizard blast
- icon for special attack by wizard
- AI: also use wizard blast
- particles for fireball
- particles for hit by wizard attack
- title screen with buttons to view instructions, start game
- instruction screens
- ice ball
- levels: cpu points now always same as player points
The fire ball is now the only special attack launched from the base.
The game will have no levels, and no scoring system.
| A second w.i.p. video, I play from the left:|
| I am growing increasingly impatient to finish this game... therefore some ideas have been cancelled. On the other hand I will be happy to still complete the game. It would be a waste of time not to, and I enjoy the way it turns out and plays on Android.|
The player can now launch rocks, fire balls, and ice balls. The computer controlled opponent can launch only rocks for now.
Another big change is in the unit point return system. Previously, you would earn big bonus points for reaching the other side. This is still the case. However, a unit getting killed would still return all unit points to your base. Your or the enemy's number of points would never go down. This made for a difficult upstream battle against a computer player: even if you had many more points, the fact that the CPU player would get all points back for his killed units allowed him to instantly launch those units again, blocking your army.
The new approach is: when a unit is killed, you get back all points minus one. This point goes to the opponent. This new system will gradually wear down the reserves of a losing army.
- button for launching ice ball
- AI also launches rocks (ice and fire balls still to come)
- rock, ice ball, and fire ball do big damage on direct hit
- rock, ice ball, and fire ball also create quake that hurts nearby units
- special attacks share one reload timer, indicated by bar
- when unit killed: all points minus one back to owner; one point goes to enemy base
- cancelled dragon unit
- cancelled troll ranged attack
- cancelled blood on battlefield
- cancelled extra hit/death animations
| The control method has again been changed, after the switch to Android. I have added on-screen buttons for launching units and for launching special attacks. The buttons are in a vertical bar. The player can select whether this bar is at the left or right edge of the screen. The player can also select whether he or she plays from the left (moving right) or right (moving left).|
- warrior rage bonus: after killing enemy: extra energy, higher attack rate (and tinted red)
- added on screen buttons for: launch rock, launch fire, launch unit
- button on title screen to start game
- button on title screen to start cpu vs cpu demo
- button on title screen to set position of button bar (left or right edge of screen)
- button on title screen to set player base (red, playing from left, or blue, playing from right)
- two player game
After doing away with one-button controls, and adding special attacks, it became difficult to keep the two player version, given the controls required. For an Android version I could use touch controls for two players, but there would be many buttons on screen. The question then is, how many people will play a two player game on a miniature screen. And I am also still keeping a Flash/HTML 5 version in mind, which is again difficult to match with the Android/touch controls. A PC version would then require either two mice, or keyboard + mouse, or a large number of keys on one keyboard... which is why I decided to remove the two player game.
| After having created an Android version of my game Doggy Bounce I have decided to make Wizard Battle 2 an Android game too. The control method will have to be revised again, to using touch control, comparable to mouse only control, I guess. (In creating the Android version I will still keep the option to easily make a Flash version in mind.)|
The screen resolution will be changed from 640*480 to 800*480, in principle making for a wider battle field. This should not be a big problem. Units can be made to walk faster to compensate, if necessary.
Currently the game is creating and deleting game objects when required, but I have read that it may be better for Android to create the objects beforehand, and not really delete them afterwards but just put them in an inactive state, for recycling. I will continue as normal now and when performance is going down I will implement this strategy!
| Although I've always liked the one-button controls, I am considering changing them. Launching units and (in the future) fireballs at the right spots can get a bit tricky with the automatic up/down movement. I noticed that I was more or less cheating the system, making the base stop and keeping it at a certain spot (cycling through the units) because I wanted to launch a unit there but didn't yet have the points. That is not really a bad thing to do, but to achieve that result in this manner shows that the control method is a bit lacking. I am thinking about adding keys for up and down. I also experimented with left and right for cycling through units, but that may make it too complex. So what I will try next is: up/down keys for movement, holding down space bar for cycling through units, releasing space bar for launching the selected unit. (In the case of a two player game, two sets of three keys need to be defined that do not interfere with each other.) |
| The game is far from finished but I am already looking at ways to make it fun to play. (It is never too early to start looking for ways to make a game fun to play...) The launching of units in response to what the other side does, can get a bit boring. It can even result in a very long game where neither side manages to get units across and gain an advantage.|
Therefore there have to be more factors that influence gameplay. I have already made the units move faster; this will make the game more exciting for the human player, causing him or her to make more errors. I have added the troll class that sends units flying left and right, making the battle field more dynamic. (An enemy wizard being hurled to a lower or higher row can be dangerous instead of an advantage.) Fire balls to be launched from the base should add an option to directly attack enemies or areas. A new dragon unit will make for more variation in unit types.
Another way of adding variation is to give units special abilities. The first has been added:
- archer forest bonus
As an archer moves through trees and bushes, he will turn greenish. (The colouring is done with SetColor.) When in this state, his fire rate will go up, firing precision increases, and other archers/wizards will have more trouble hitting him. This makes the trees and bushes into gameplay elements rather than just scenery. Next step will be to make the AI also use this information. I am now thinking about other special abilities to be added for the warrior and wizard.
- small delay between unit launches for cpu player, resembles human play
- units lose energy when landing after flying
- randomize attack speed
- randomize time between attacks
- units slow down a bit when hit
The delay between launching units for the AI player resembles the speed at which a human being would press and release the space bar to launch units. I noticed that as my units came closer to the other side of the battle field, the AI was able to keep them from reaching the edge by reintroducing enemies again and again at a very high rate. By adding a small delay after each launch, this problem is reduced.
- depth sorting of projectiles
- wizard attacks with orb projectile
- troll sends opponents flying
- new class TParticle
- some blood effects when hit, using new particle class
The game up to this point can be seen in this video:
- removed TCreature class
The idea of adding neutral creatures has been scrapped. I was playing the game and the screen quickly became filled with units, and it seems that to also have neutral creatures running around would make it too hectic. This means there is no need for a creature class anymore, since the only class extended from that is the unit class.
The unit class is now directly extended from the entity class, as are the classes for projectiles, trees, and particles. Depth sorting is done in the entity class, the result being that all on screen objects are correctly depth sorted.
- new unit type: troll
- warrior attacks have effect
- archers launch arrows
- arrows can stay attached to target after hit
The bushes were added using the same class TTree, just using different graphics. TPlant would have been a better class name in that respect.
Trolls are in the game and even attack other creatures, although this attack has no effect yet and needs to be changed, because at the moment it is a result of the TTroll class being a copy/paste version of the warrior! Just as with the trees it cost me some time to make them look nice, they looked extremely ugly at first. I had to simplify the drawing to make it look acceptable. There's a picture of the bushes and trolls on my Foppygames facebook page:
The arrows did require a new class of course. In the original game no depth sorting at all is done, but in WB2 it is, so I thought arrows should also disappear correctly behind trees etc. In order to make this easy they should be extended from my TEntity class, which manages a depth-sorted list to which the arrows could then be added. The wizard will also need to fire some kind of projectile, which will behave almost the same as an arrow, so I first created a base class called TBullet, extended from TEntity. TArrow is again extended from TBullet (as will be the wizard projectile).
I read somewhere that to create a good game you have to start out with a basic mechanic that is immediately fun. In the case of Wizard Battle 2 this was not really the case. In fact after months there still is no game! So let's hope it all turns out fine and challenging gameplay magically appears at some stage!
| Trees have been added. The single tree graphic that the game now has looks like this, but smaller:|
It took some work to get it to look nice (it's remarkably easy to draw ugly trees), and to give it some contrast with the background, which could perhaps be improved, but I am fairly happy with it.
A class TTree was added to represent the trees. The trees and creatures should be depth sorted correctly. I was already using a list of creatures to sort those, but I could not just throw the trees in that same list, because they are of a different class. Therefore a new mutual parent class was added, called TEntity. Now the game uses a list of entities, which can be creature or tree, and this list is depth-sorted.
In addition TCreature still has its own list of creatures (though this list is not depth sorted anymore), because the AI and collision/nearness code needs to be able to quickly scan through the list of creatures and not be bothered by trees or other game objects inbetween.
Now for other plants I think I will use TTree, but just with different graphics. So bushes will also be trees, and act the same, if they act at all! The trees are at the moment randomly distributed over the battlefield. This is a good starting point. For bushes, it might be nice to have them clustered in groups (like I did in my Ranger game) and perhaps have a tendency to be close to trees. Having tiny "forests" on the map could be interesting in gameplay, for instance if an army is walking through and that forest is put on fire by the enemy. But it could also remain a largely cosmetic feature, because it looks good to have units walking behind trees and bushes. The idea of giving archers an advantage when attacking from cover passed briefly through my mind but this is the dreaded feature creep that should be avoided! Go away, idea! >:|
| I have made a list of all things that still have to be added to the game and that I could think of.|
As the game progresses I will mark each point with words such as "done" or "cancelled". :)
- new unit type: troll (done)
- new unit type: dragon (cancelled)
walk / attack / hit animations:
- warrior walk animation and attack animation (done)
- archer walk animation and attack animation (done)
- wizard walk animation and attack animation (done)
- troll walk animation (done)
- troll melee attack animation (done)
- troll ranged attack animation (cancelled)
- warrior hit/death animation (cancelled)
- archer hit/death animation (cancelled)
- wizard hit/death animation (cancelled)
- troll hit/death animation (cancelled)
the actual attack logic, including arrows flying and units receiving hits:
- warrior attack (done)
- archer attack (done)
- archer arrows in targets after hit (done)
- wizard attack (done)
- troll melee attack (done)
- troll ranged attack (cancelled)
- hit effects (cancelled)
- blood effects when hit (done)
- blood on battlefield (cancelled)
- maybe dirt clouds for walking, falling (cancelled)
other game objects:
- trees (done)
- bushes (done)
- grass (cancelled)
- special attack bar (done)
- special attack rock (cancelled)
- rock leaves craters (cancelled)
- special attack ice (cancelled)
- special attack fire (done)
- fire leaves burned spots (cancelled)
- fire on battlefield (cancelled)
- fire on units (cancelled)
- ice on units (cancelled)
- fire unfreezing units (cancelled)
- ice putting out fire on units (cancelled)
- rocks on battlefield (cancelled)
- trolls pick up rocks for ranged attack (cancelled)
- AI: plan defense where needed, not all focus on one row (done)
- AI: plan attacks too, not just defense (done)
- title screen with buttons to view instructions, start game (done)
- instructions screen(s) (done)
- level structure (done)
- next level screen (cancelled)
- game over screen (done)
- game completed screen (cancelled)
- maybe have cpu vs cpu demo running on title screen (cancelled)
- credits (cancelled)
- sound effects (done)
- title music (cancelled)
- in-game music (cancelled)
- option to toggle music on/off (cancelled)
- points for completed levels (cancelled)
- time bonus at end of level (cancelled)
- local hi-score (cancelled)
- Kongregate hi-score for Flash version (cancelled)
- tile system
Up until now I was using a tiled background. This would enable the use of different surfaces (grass and mud) and different walking speeds. However it came to me that different walking speeds would interfere with the simple nature of the game, what with units overtaking each other. In addition, the AI would have to take the "roads" on the map into account as well, and since the weak AI is a problem already in the original game, making the game more difficult is not a good idea. So I decided to remove all tile-related code from the game! But before I did so I used it one more time to create a full-screen background image. Now I can add details to this single image that would have been harder to add in a tile system, because it would require unique tiles.
- been busy making the object oriented code more "correct"
I have a TUnit base class from which classes such as TWarrior and TWizard are derived. In the constructor of TWarrior, I call upon the constructor of the base class TUnit. However, the characteristics of a warrior, such as speed and range, would be stored in TUnit, in an array! And I would pass a parameter along to the constructor of TUnit, telling TUnit that it should use the warrior-related data from the array. This is of course rather lame and ugly. I have changed this so that only TWarrior contains the warrior-related data (in the form of constants), and these data are passed to TUnit. Now TUnit knows nothing about warriors and wizards, except what it is told, as it should be.
- proper sword-swinging animations
In Wizard Battle the attack animations would be made up of a series of image frames, such as a sword at different angles. In the sequel this is replaced by coded animations: the same sword image is drawn at different angles, describing a smooth arc. This is for the warrior unit.
For the archer unit, I have added the drawing of bow strings from the hand holding the arrow to the tips of the bow, using DrawLine(). As the hand and the bow move while walking, and the drawing command is constantly using the correct start and end point for the lines, this looks dynamic. Now I will add the actual attack animation, pulling back the arrow and releasing it. Next will be the wizard attack.
Plan for other features:
Planned full list of unit types:
- giant troll
- fire breathing dragon
The troll will send enemies flying. It can pick up rocks and throw these at the enemies too, so it has ranged and "melee" attack! The dragon will have a ranged fire attack and will itself be fire-resistant. (It will attack other dragons with a melee attack. Now that I write it down it begins to sound complicated, two types of attack, but perhaps it's not so bad.)
These are projectiles launched from the base position with selectable power, which decides how far they will fly. They can be launched when the new "special attack" bar, which is filled automatically over time, is at the required level. So this is unrelated to the points that are used by the normal units. (However they will be accessible through the same system of "hold down space bar until desired unit/attack appears". This list will therefore become longer. It should not become too long of course! Maybe the list will have to be traversed at a higher speed than in Wizard Battle 1.)
The special attacks have different abilities:
Rock: Just a rock, it will hurt/kill what it hits. Pieces of rock that remain can be picked up by giant trolls to be thrown at enemies.
Ice: Like a rock, but it will also temporarily freeze what it hits. (I suppose trolls could also pick up pieces of ice and throw these at enemies, freezing them...) Ice can also put out fires on the battlefield and on units.
Fire: This can start small fires on the battlefield. It will also hurt enemies and put them on fire, which will drain their energy. Such fires can be put out by a blast of ice. Frozen units can be unfrozen by hitting them with fire. (These relations between game elements is nice but may be getting too complex. I have to experiment with the basics and, if I'm not bored of it by then, the extra rules and see what is more fun.)
| I am taking a break from Wizard Battle 2 to work on another game, which will most likely be a single-screen top-down racing game with guns, also programmed in Monkey. In writing Wizard Battle 2 I reached the point where units attack each other on the battlefield, and adding interesting animations turned out to be a bit of a task. The boring way in which the warriors were hacking away at each other slowly started to reflect my boredom during programming. So I will continue working on that hopefully with renewed interest after making this racing game. :D |
- separate classes THumanPlayer, TComputerPlayer
- computer player launches units
- units slow down when on overgrown tiles
Up to this point I was using one class for the bases. A variable was used to indicate whether it was controlled by a human or computer player. That approach of course means that there are a number of If and Select statements to separate the human from the computer logic. Then I thought "why not extend the base class into two separate classes" (this being a Monkey project), so that's what I did, giving me THumanPlayer and TComputerPlayer, based on TBase. The human player just reads the keyboard to see if a unit should be launched. The computer player uses a few other classes:
This is an array that stores a number for each horizontal tile-row on the screen. The number represents the difference between the two armies in that row. A positive number means the army from the left has more troops there, a negative number means the army from the right has the upper hand. Different unit types bring different values into the equation, so a strong unit could count for two weaker units.
The computer player uses the force table to create a list of targets. A target is a row that needs attention because the other side is winning there. It scans the force table and for every row where the enemy has more unitpower, it adds an object (TTarget) to the target list. The list is sorted from large threat to small threat. Now as the computer base moves up and down it checks at set intervals if it happens to pass by a row that is also in the target list. If so, one or more units are launched there to make the enemy's advantage go away.
Now what I want to add is the option for the computer player to not only respond to what the human play does (which would lead to only defensive play) but to also take the initiative by adding units on rows that are not under attack. It should preferably only do this if enough unit-points are left to use in defensive locations.
TTargetList was originally implemented as a static class, using globals and functions, because I was thinking about "the" computer player. Then I realized that it would be fun to have two computer players play each other, as in a demo state. So now it's a normal class, of which every TComputerPlayer object can have its own instance, without globals that are shared. (For the force table this is not necessary as it is a neutral representation of the two armies.) Now it has become even more important to add initiative to the computer player, as otherwise a CPU vs CPU battle would not be very interesting to look at! ;)
| After a doing search on google for "warrior with sword and shield" I found this image:|
I have used it as an example to try and make the warrior look nicer. Here is a picture with the new one on the right:
Maybe some more changes are needed, changing the hair color or the color of the helmet. This is now the basic look of the warrior, but later on there will still be variations for their heads (re-introducing the old helmet as it looks nice with the visor) and maybe their swords and shields.
- correct depth-sorting on creatures
I wanted to sort the list of creatures on their Y values so that creatures towards the bottom of the screen are drawn last, overlapping creatures higher on the screen. However, since the units in Wizard Battle 2 never change their Y values (they only move left/right) I don't need to sort the whole list, I only need to insert new units at the right spot in the list based on their Y. This will change if/when I add neutral enemies that do move vertically. I could just decide for them never to move vertically either! :)
Looking in the documentation for a method to insert an object in the middle of a monkey List, I couldn't find it. Therefore I have created a custom linked list, plus a method to add a new creature on the right spot based on its Y. They are now drawn correctly from back to front!
- force table, used by AI
- launching units costs points, remaining points displayed using bitmap font
- red and blue wizards
- units stop to attack first enemy in range
- grass tiles have correct edges
The force table is an array representing horizontal rows on the screen from top to bottom. When a wizard launches a unit, points are added to the force table on that row. The wizard from the left adds positive points, the wizard from the right adds negative points. While debugging these values can be printed to the screen as in the picture below. The CPU player will use these values to decide where to launch new units.
Units now stop to start attacking the first enemy unit in range. They don't actually attack yet so they just stand there. Each type of unit has its own range of attack. This mechanic actually works on the level of TCreature (of which TUnit has been derived) so when at a later stage neutral creatures are added (also derived from TCreature), these will also attack and be attacked by TUnits. This means your forces cannot ignore neutral creatures. Perhaps an automatic exception will have to be made for cases where a neutral creature is already fighting with an enemy unit. Attacking the neutral creature at that point would mean you're helping the enemy...
The grass tiles now have correct edges for all different ways in which they can border non-grass tiles. I have created a separate image file for every configuration. You would think that one file holding a frame for each case would be more logical, but I was already using the different frames to represent graphical variations of the same tile.
| In Wizard Battle 1 the main body, arms and head of the units are more or less one fixed image. In order to be able to have them move separately while walking, and perhaps even remove them when hit, I have changed the system to use separate images for head, body, hands and feet. As the feet move forward and backward relative the the body while moving, this same movement is applied in slightly modified fashion to the head and arms, so they bob along. Separate images also means it's easier to add different versions of one body part, without the need to also include everything else again in the new picture. For example, I plan to add a number of heads so that not all warriors have the same yellow hair and identical helmet...|
The units of the left and right army will be recognizable not only by their direction, but also by a marking color, either red or blue. In the case of the warrior unit, this will be used on the shield they are carrying. It is still the only unit I have added, as seen in the picture below!
I have also been experimenting with making the tiles look nicer. The next thing to be added in this respect is different tiles for the transitions between over-grown (green) tiles and clear (brown) tiles. There should be a green tile for every possible edge, such as bordering to brown on the left, right, left and right, etc.
| In Monkey I feel more tempted to use classes and derived classes than in Blitz 3D, if only because Blitz 3D doesn't have classes as such. After having written a class TCreature, featuring a basic movemement function, I derived a class TUnit from it. (These will be the battle units moving towards either side of the screen.) I was adding all kinds of fields to TUnit in order to differentiate between a warrior, an archer and a wizard, when I realized I could also derive new classes from TUnit for those. So now I have TWarrior, to start with, which is the unit carrying a sword.|
Of course I now needed the characteristic movement of the feet as seen in the original game. (And recycled in my game Ranger...) I keep track of one variable fFootDX that holds the horizontal position of the foot that is on the ground, relative to the unit's body. The negative value of fFootDX is applied to the other foot. Then there's a variable fFootToggle (1 or -1) that decides whether the left or the right foot is the one currently on the ground. In the move function of TUnit (which calls the basic move function of the class it was derived from) fFootDX is updated. Once it reaches a value that is greater than the size of the steps the unit is taking, the value is reset and the other foot is now made the one on the ground. (The height of the foot that is not on the ground is computed in another function, using the Sin() function from the Math module so that the foot moves in an arch.)
Method move:Void() ' store current fX Local oldX:Float = fX ' move unit, changing fX Super.move() ' foot is moved back by amount moved fFootDX += (fX-oldX) If (fFootDX >= fMaxFootDX) Then ' switch to other foot fFootDX = -fMaxFootDX fFootToggle *= -1 End If End Method
The value added to fFootDX is equal to the distance the unit has moved as a whole. So if the unit moves 2 pixels to the right, the foot on the ground is moved 2 pixels to the left, relative to the unit. The effect is that the foot will appear to stand still. In the original game I was using some computation that was not so much connected to the movement of the unit, so the feet would appear to slide a bit. With this new approach it looks more realistic.
| While recreating the basics of the game in Monkey, I decided to add a tiled background instead of the original single background image. This will allow for graphical effects and interaction between units and background, based on the type of tile they are walking on. Currently there are two types:|
a) ground (brown/yellow)
b) grass (green)
Walking on "grass" will slow the units down, compared to walking on "ground". A the start of each game, the tile layout is automatically generated, featuring vertical border areas left and right and a random number of horizontal "roads", with random interruptions.
The tiles are sized 40*40 (units are 32*32). Drawing the 640*480 tiled background compared to drawing the single background picture seems to slow down the game on HTML5, but on Flash it still runs smoothly.
Now I have some additional new features in mind:
- units go slower/faster based on underground
- ability to launch rocks, fireballs, iceballs from base
- rocks make craters (new tile type) which slow down units
- iceballs freeze units and put out fires
- fireballs defrost frozen units, burn other units and create fires
- bushes, trees, slow units down, can also catch fire
A picture of the new game so far, with the tile system and moving bases:
| After my first game in Monkey, Doggy Bounce, I have started work on a sequel to my 2004 game Wizard Battle. The original features two wizards launching warriors and archers, as well as the wizards themselves, onto a battlefield from either edge of the screen, in order for them to reach the other side. If one of the wizards manages to reach the other side, that wizard has won. The characters are launched from a base that moves up and down automatically, so in the end only one key is needed: the period the key is held down determines which type of unit is created upon releasing the key. This was actually an entry in a so called "one-switch" game competition.|
Wizard Battle 2 will be programmed in Monkey so I can also create HTML5 and Flash versions to be played in the browser. The first stage consists of recreating the original game. The original game was 800*600, the sequel will be 640*480, with slightly larger units.
New features will then be added:
- new graphics, sound, music
- larger units
- faster gameplay
- more interesting AI
- new unit(s) such as perhaps a dragon
- possibly some spells for the wizards
- neutral enemies such as wolves roaming the battlefield
A video of the original game:
And a picture of the original game:
|Blitz BASIC Founders Fund|