Below is the DevDiary (development diary) I started in January 2011, posting almost an entry a day. This quickly turned into “too many entries to manage or navigate” and half a year later, I grouped the entries by 10 a post.
Entry 1 or how I started making a quick XNA game
Jan 15, 2011
Well, it’s about time I get off my ass and contribute something to the Indie gaming scene. On retrospective, I couldn’t type that sentence with a straight face. Everyone and their mom is making games nowadays since on-line distribution advent. Anyway…
It will be set in medieval times and it will be an RPG! I shall call it the ”Land of Magic” and it will be about wondrous adventures into treacherous lands filled with fierce goblins, mysterious elves, legendary dragons, courageous nights, and other miscellaneous beings from Tolkien’s repertoire. Innovation shall not pass!
Now the intro aside, the real reason I am writing this is because my attention span is terrible. I am alt+tabbing to YouTube every 5 min for more cat videos. So hopefully keeping this edit window open and documenting my progress will motivate me enough to finish what I started. And let’s make things interesting and set a deadline — how about 2 weeks?
Some background: I’ve programmed quite a lot and have started a decent number of various projects/games alas finished almost none of them. For this one, I am going to use XNA 4.0, C# under .NET 4, and Visual Studio 2010 (+ReSharper).
Off we go!
Let’s start simple. A 2D overworld. This means a fixed width/height 2D square map for terrain. Each square can be a certain type of terrain, like meadow, dirt, or sand. From programming point of view — we make static class World, and keep a 2D array of Tile class instances. Each Tile has a certain TileType class reference. For now, we’ll have 3 TileTypes — grass, dirt, and water.
As for the graphics, I’ll keep different things (terrain, unit, icons, etc.) separate. So for Tiles we’ll have a tilesheet (tile spritesheet) divided into 50x50px squares. Each TileType will know where its graphic is located. So 10 min later:
Now rendering is easy beyond setting up basic draw logic — just 2 nested for loops for x and y, placing sprites at their locations. Here’s a World with random tiles:
Next step: pan/scroll/drag the world. Keeping it simple: pressing and holding right mouse button should do it. Think ”Transport Tycoon” or ”Settlers II”, or even ”Sims”. For this a static class Camera stores X and Y offsets. Holding the mouse button down tells the Camera to adjust the point it’s looking at by how much the mouse has moved. Rendering is then straightforward — we just apply this offset to every World sprite we draw. Easy, peasy.
This reminds me Windows doesn’t actually printscreen the cursor, so that screenshot was pretty pointless. But you know what they say? There’s nothing that can’t be solved with a custom cursor:
Units and players
Now let’s populate our world with… something (the important thing is that I have planned and designed beforehand). We shall create a Unit class and a corresponding 2D array in the World. Of course, most of the array will be null, but this really comes down to rendering, A*, and other map operation efficiency. I don’t want to iterate some Unit collection each time I need to see if a certain square has a unit on it. And I also will assume no more than one unit may occupy a square at a time. That’s a bit restricting, but flying/underground/whatever units can have their own array if I ever feel the need for that. Finally, like TileType, each unit has a UnitType, potentially common with other units. So goblins have goblin UnitType, knights have knight UnitType, etc.
Yes, yes, I often wish I wasn’t so freakin’ good with graphics myself.
Now, we want to keep track of which units are ours, which are enemies, which are other players. Thus a Player class is born. Each player has their unit reference and each unit may have a player reference. Slightly redundant, but if we keep the code clean, this shouldn’t make huge problems. Here’s an obvious idea — color-code the players so we can see who owns what in the world. And would you look at that!
How about some UI? What do we need? Health, money, experience, level. Well, that was a bit of a backwards thinking there. ”Units” need to have current health, max possible health, experience, level, experience needed for next level, and bunch of other stuff. Let’s call this Stats and make each unit have a personal instance of Stats. Now, this way UI can display our user’s unit’s stats. Anyway, the icon sprite sheet:
And without further ado:
While we’re at it, let’s make a time counting system. I think this game will end up being (unfinished in my todo folder) turn-based, since that’s the easiest way to implement it. Think ”Heroes of Might & Magic” or ”King`s Bounty: The Legend”. Besides, I want the user to play at their own pace, without worrying too much about what opponents are doing. Think Civilization.
And for a final good measure, let’s add an FPS meter, so I can see when some feature start eating up too much time. I am on a crappy laptop with integrated graphics card, so that’s quite good.
Between getting the blog up and making the game skeleton, I think it went pretty well. Today’s summary: 17 classes, 4 sprite sheets, and 0 code comments (well, actually -5 or something if you count the ones I deleted from XNA default empty project).
A couple more tweaks here and there and I’m ready to sell millions. Millions!!! *runs off arms flailing*
Entry 2 or how I made a bunch of pixels move
Jan 16, 2011
Ah, yes, day 2. I guess this means I should be working on this to-be-awesome game. But seriously, why do I promise myself these things? I still haven’t planned this beyond “whatever comes to my mind”.
So the next logical step would be making the units move. I’m not sure yet if I will make this turn-based or real-time. But since I want the game savable/loadable, the movement info will have to be stored in the World/Units.
The only thing about me is the way I walk
Before anyone can “walk” anywhere, we need to be able to specify a tile/coordinate. So let’s highlight the current tile under the mouse with a marker:
Camera class will handle the coordinate calculation. Quite simple in our case, just take away the camera offset and whole divide by 50. Which would produce:
(…and would also remind me to keep water out of under units.)
And now the fun part — the actual movement. Now we could force the player to move square by square themselves, but that’s a bit of a dick-move. Instead, the user should be able to click a target square and the game would calculate the best path. Think Jagged Alliance 2 or Avernum, or even HoMM. Time for some path-finding! Don’t you just love the smell of A* in the morning?
Now here’s a dilemma. If I reuse my old A* code, I can’t say I made all the code (full game) between the self-imposed time interval; yet if I don’t reuse the code I am essentially rewriting an almost self-contained algorithm… again. Well, I ”could” reuse the code and then take a break for a day, claiming I am making A*, right? After all, my old code is nice, debugged, and optimized, with binary heaps and whatnot. *self-convincing completed* I promise to waste some time on beer drinking to compensate for this ludicrous act of cheating.
I present to you A* (Euclidian distance):
(It’s so awesome even the player’s unit’s graphic leveled up)
Now I am not so sure I even want to make this turn-based. I guess I am not making multiplayer (ha-ha-ha, multiplayer, like >1 person will ever play this) anytime soon, and if I don’t implement global time sensitive events, then I am still not restricting the player’s pace and instead making the world seem alive even when the player is idle.
So how does a unit move/animate? I suppose we need to know where we came from and how many steps from how many needed steps have been taken. So every unit will have a little instance of a Movement class. This movement will be set every time a unit is free to move and has somewhere to go to. So let’s make a unit keep its target coordinates and then A* every time for path. That would be a Command class.
So every time user clicks somewhere we give out player’s unit a command to move to that X, Y. At every update/frame the World will Live() and iterate through all units and either make them Move() or make them Act() — i.e. decide what to do. Units that can Act() and have a Command will then try to move if needed/possible. This makes units “independent” of the World in decision-making (will come in later with AI). So, anyway:
Not that I can prove that the unit actually moved. I could have just ‘shopped it or changed the starting coordinate for all you know. But let’s pretend that I didn’t and make the transition “smooth”. This is basically drawing the sprite in between the fixed tiles. For this the rendering is straight-forward — the unit sprite is offset proportionally to how much the unit has traveled from its origin. Both these values are stored in the Movement class for the unit. And we end up with:
Now the final touch is to rotate the image — for now just change a direction state to left or right. Based on that, the image can be flipped horizontally easily:
I like big tiles and I cannot lie
Okay, enough serious game logic stuff, time for some visual enhancements. Let’s make tile sprites 50×75 and overlap the last 25 between tiles. This way we can make tile vertical border transitions a bit nicer:
Now that I look at it, it is time for a map editor. rand(3) can do only so much for a realistic terrain. Now, we don’t want normal game playing interfering with map editing. Time for a small finite state machine with two states — playing and editing. Now input processing can be split into playing or editing based on the state.
First, let’s rename icon spritesheet into UI spritesheet and add an empty button:
In fact, let’s make a Button class and store it’s location/caption and have a function to see if the mouse is inside it. This way we can dynamically create/destroy buttons and check for user clicks. After all, I bet there’s gonna be a bunch of various interactive buttons in the end.
Same game state applies for buttons — we can have a collection of buttons for each state (playing or editing) and have a static Buttons class only return and Renderer render only the ones currently relevant.
And we’re done
Summary: 23 (6 new) classes; unit movement; map editor; states; still 0 comments. I suppose not too shabby for a day. Soon this will be so epic everyone will be shouting… wait, what did I name the game again? *runs off to read the first post*
Entry 3 or how I committed NPC murder
Jan 17, 2011
Who starts drilling and sledge-hammering at 9am? Seriously. There is a special corner in hell reserved for these people. Today’s objective: making things die.
First thing’s first. Any (potential) action in-game must provide feedback to the player, and the sooner, the better. That is called good game design. *smug face* In this case we need a few new cursors or rather supplement icons for cursor:
Now, depending on whether A* finds a path/monster, we can choose the appropriate cursor image:
Rendering loop calls its own A* path-finding every time mouse moves between tiles or World triggers an update (such as, when units are spawned/despawned/moved). This way, the info is always up to date.
Now we also want to indicate how much life the mobs have without additional moveovering. For this, a health brick can be used:
OK, not very impressive. But wait until you see ”this”:
Now, we also need to actually show mow much health they got:
This is a bit tricky, as higher level units can have lots of health and we don’t want 50 bricks above every mob. This is actually quite well done in some RTSes, like, C&C, Warcraft 3 or Starcraft 2. But then again, these games often have stronger units being bigger and the health bar can effectively accommodate that.
I keel you
So how would combat work? Or better yet, how ”can” combat work and what method do I want to adapt. Keeping an RPG/overworld point of view, the combat can either “happen” right there on the map (think Civilization or any RTS) or in a separate window (think HoMM, or Final Fantasy, or any Japanese RPG).
Now, real-time combat on the map can be either turn-based (i.e. everything pauses while two unit combat is resolved — Civ style) or real-time (i.e. some units are fighting while some are moving around — RTS style). This approach and the latter variant seems to be more appealing to me and less immersion altering. Besides, I don’t think I can afford secondary graphics for fighting screens. And if I was to reuse the same sprites, then I might as well do it all in the actual map.
So let’s modify our Movement class to be Action class with possible action to move or attack. There is little technical difference — one (attack) allows targeting enemy-occupied squares, while the other (move) forbids.
Next question: how would a melee attacking/defending unit animate? A quite simple and nice-looking solution is to make both attacking and defending unit move slightly towards each other (i.e. towards the common border/corner of the tiles). ”But” this would prevent units attacking at the same time — that is, where would defender go to if attacked from 2 sides? I really don’t want to get into flanking and attacking from behind.
So a better alternative is to make the attacking unit temporarily advance towards its target, inflict some damage, and back away entering a short cooldown. Any other units attacking and defending will also be able to do the same. Granted, sometimes units might get mis-aligned and move “out of the way” from attackers. I might just do little cartoon fight clouds and hide the fact that I can’t animate.
Oh, look, 5 paragraphs and no pictures. Here’s some bloody action:
(well, okay, not really bloody and not really action either; the mobs don’t even resist and disappear upon death)
Come to think of it, I need to make my units bigger. Dammit! Tiny sprites were at least partially masking my inability to draw. There:
Now the game feel ”much” more epic! Actually, let’s draw some more mobs!
Now that is a fugly thing. Intentionally, of course.
Finally, let’s make scrolling combat text! Or to rephrase, have a small floating text above a mob which shows for how much it gets damaged/healed for:
Hmm. May be the health bars should be under the mob not above it? Especially, since mobs may have differing heights. Oh well, will do this tomorrow or something.
No specification, no design document, no plan, no deadline objectives — this should really backfire soon.
Entry 4 or how they moved, talked, and died
Jan 18, 2011
Even if I am doing what I like and it is progressing nicely, self-imposed schedule still feels like work. And the more you code and implement, the lesser the changes seem. Alas, I don’t give up easily (yes, I do) and today’s opportunities shall be embraced.
Let’s improve our terrain and path-finding a bit. This involves telling A* to not rely on a single target cell state (e.g., occupied, impassable, etc.) and instead query the World about a transition between 2 specific cells. So a cell may be accessible, but not from every direction. This will allow restricting certain movement, mainly diagonally past two impassable cells:
Implementing this, we get:
Health and dying
Right, now let’s optimize mob health a bit.
Let’s make average mob base health — 15. This is the health at level 1 and can slightly differ depending on mob type. Rats might have this at 9, golems at 18, etc. Let’s also make the default number of health blocks 5. This means for every 3 health point, we draw 1 block. Weaker mobs will automatically have less blocks and stronger mobs — more. Thus, the player gets an immediate feedback on mob’s health based on their displayed health block count.
Now, this also has to be adjusted by level. Let’s make max health point increase 5 per gained level. So level 1 — 15; level 2 — 20; level 3 — 25, etc. Therefore, each block represents 1 more point per level. Therefore, the number of blocks won’t change for the average mob, yet the variations among same level mobs will still be apparent.
In above implementation, green things are stronger than your average mob, while the fugly gray ones are weaker. Now let’s murder some:
Yay! Video game violence is fun.
But, although it is hard to admit, not everyone in the world is hostile. I know, bummer, right! So let’s make the mobs either hostile or friendly. Which brings up another issue — are any mobs hostile to any other mobs? Can NPCs turn on the player? Can player befriend or anger a certain group of mobs? All this can potentially be done with a Faction class assigned to each mob. So what exactly is the difference between Player and Faction, you may ask? (well, you probably are just skimming through pictures, and don’t give a crap how I structure my classes) There isn’t any difference, and we may just assign a player to every mob/group. This way, mob AI can even be implemented as derivatives of the Player class. Here’s each unit with their player/faction assigned:
Now let’s color these properly — blue for user, red for hostile, and yellow for neutral:
(pretend the prolonged brown thing is a mouse)
Let’s make someone to talk to (don’t worry, there will be an option to kill them too). In fact, everyone should be killable. I give to you, crazy old hermit; let’s go talk to him.
Oh, whoopie, I guess we forgot to implement “talking” and beat up an old man. Guess it’s time for a new action type, new command, new cursor… See how much more stressful communicating is to beating things.
Talking means dialogue, means scripting. Although we may just have certain units that don’t trigger dialogues. Just a floating speech bubble:
Hey, let’s make inventory!
Well, drawing that bag took significantly longer than anticipated, including making button have types with preset texture sprite locations. So did the item classes, item types, inventory class and assigning unit inventories. Here’s an ugly potion that looks like a fire hydrant:
I think it is time to call it.
Entry 5 or how little thing take all the time
Jan 19, 2011
This game serves as a proof of concept more than anything. The concept that I can focus and work on long enough to call it (feature) complete.
Would you like a bag?
First, let’s focus on important things, and make bag graphics change on mouseover:
I guess I’m working on inventory then. I will keep it simple and have an inventory be a number of available slots for items that can be potentially placed there. Let’s drew a slot:
Now, we want to keep track if inventory and which inventory is open at any time. Clicking the bag should open/close the user player’s inventory. We also want to be able to open several “inventories”, e.g., chests, bags, corpse loot, etc. So a static UI class will keep track of all open inventories or containers.
So, here’s user “bag’s” inventory space:
Now let’s place and render a potion (malformed canteen) in the inventory:
Let’s also highlight the currently mouse-over’ed slot. By the same logic, it will be possible to detect mouse clicks in the inventories and potentially move things around.
Well, well, well, my generic RPG is shaping nicely. And by generic I am referring to the lack of a single feature not present in at least a dozen other RPGs/MMORPGs — what I have are the blandest, most straight-forward versions of basics. My game is so square.
I made the World save its state. I need to get over the “my game is bland” phase, so I won’t draw anything — at this point any graphics I produce will be fully emo. So nothing to show for saving really, it’s just a bunch of XML-spitting code, that jots down every non-static variable value into a save file.
I pity the prop!
Thankfully, the emo phase was short-lived and we’re back to joyful, happy times. Let’s populate our world with some objects. We’ll have to call them props, since “object” is a reserved C# word. A little counter-intuitive, but props can potentially have inventories, various action triggers, change or transform, be beneficial or dangerous, etc. So ranging from graves and urns to demon summoning altars.
So here we go again. Prop texture, prop render functions, prop array, prop class, prop type class, type collection container, initializations… A-a-anyway, here’s a tree:
Let’s chop it into firewood!
Incidentally, we probably need to add this to navigation restrictions. Each prop can be either “passable” or “non-passable”, i.e. whether the units can stand in the same tile as the prop. Secondly, each prop can be either “diagonally passable” or not, i.e. whether units can sqeeze diagonally past such prop. For example, one can walk between trees, but not between a tile-wide column.
(That’s a well, by the way, for those who fail at prime art recognition) Here’s the implementation:
Also, I improved my map editor.
Why does the terrain feel so much like Warcraft 2. All I’m missing is a gold mine and some peons. Work work.
You know what would be cool? If the world wasn’t square and was angled, i.e. isometric. And if units moved freely instead of in squares… hmmm…..
Entry 6 or how I made units move… again
Jan 20, 2011
There comes a time in every project, when you look back and realize that what you’ve done is cool; but you could have done it better. Don’t fear the revamp! Worked for Half-Life 2.
I stand where I want!
Let’s do something tricky today. Fixed-location units are boring. Even transitions between tiles is just a rendering method; while the actual unit’s location is a fixed X/Y coordinate. So how would we make units able to move freely?
Well, first of all several units have a potential to occupy a single tile. Therefore, we cannot use a 2-dimensional array for this and have to keep a list of units in the world (without bothering about performance for now). Secondly, each unit is to be defined not by X, Y but by X, Y and SX, SY, which stands for shiftX and shiftY. These represent the unit’s distance from the center of the tile. For simplicity and rendering ease I will make the World tile “size” equal the tile sprite pixel dimensions — 50×50.
So now the units, instead of moving between tiles, move freely in any direction, by adjusting the SX and SY values. Once these go below -25 or above 25, the X,Y changes.
So the exact unit movement is as follows:
* Find A* path to the target and go to the next tile on the path.
* Keep proportionally adjusting SX and SY to move towards the next tile’s center
* Upon reaching the next cell, find new path and repeat.
Note that since units can “cut corners”, it is necessary to have path-finding move around obstacles. This given a “smooth” result even with 90deg turns along the way.
Further optimization and path smoothing means dropping tiles from path if the preceding and following tiles have a clear line of sight (movement). So tile #5 can be dropped if #4 can see #6 directly. This means the units can move between distant tiles in non-45deg bound paths.
Attacking now means moving towards the target via path-finding, except when near, in which case moving straight towards the target. Attacking is then staying within attack distance and “swinging” at the target. To avoid swing at every frame, units have an additional cooldown timer, during which no further actions can be performed
Let’s make AI. Or to be precise — npc/mob script. Calling it “AI” is a bit over-optimistic. Let’s make the mobs attack our player unit when it is near.
Eeek! Get away from me!
Now, this isn’t WoW, so we want the units to collide with each other. Each unit has a size value, which determines how close other can come to it. Basically, any two units that are closer then they are allowed (their sizes allow them) to be, get pushed apart.
I should probably also rotate the mobs since I drew the knight ass-first.
Finally, come to think of it, the less the squares, the easier it is for A* to squeeze a path through. That is, the ideal mob size is exactly 1 tile. So let’s make out tiles smaller. Should not be too hard. First, make the tilesheet into 30×30 sprites. Then convert all rendering and camera multipliers from 50 to 30 and 1:1 to 5:3.
Well, that was much easier than anticipated. Now a little tweak to props:
And we’re done. Here’s the current unitsheet/propsheet/tilesheet:
Today, I spent most of the day re-implementing the movement/combat system. But iteration is a good thing, especially as I’m doing agile development.
Now all I need is some artistic slave monkeys to draw me some proper arts.
Entry 7 or how the map was drawn… again
Jan 21, 2011
I’ve come to the middle of the journey… of the two weeks of the (initial) development. I might actually take this further. Watched a bunch of YouTube videos to see what other people have been doing and … wait, didn’t I say I am doing this to avoid watching YouTube videos?
Down with 2D
2D is boring. I should elaborate on a statement like that. Square 2D is boring — everything is going to be facing left/right/inwards/outwards — i.e. at straight angles. This is visually unappealing, and human eye is very good at detecting patterns, so the square nature of the game will be obvious. This is where isometric view comes in.
Isometric world basically entails remaking the following:
- Each rendering coordinate (X and Y) is now dependent on both tile’s X and Y location in the World, instead of just one of those as it is with square world.
- Mouse cursor location similarly depends on both X and Y values, as well as the shape of the actual isometric tile.
- Finally, mobs and props have to render their within-tile shiftX and shiftY positions proportional to both X and Y representation of the World.
Several hours later, I give to you:
Wait, why did I even make things 30×30 px yesterday if I just converted everything again.
Well, OK, I actually cheated like I did with A*. I have already done several half-games with isometric projection and have a bunch of re-usable code. But a fresh ground-up rewrite would take me day or two fiddling with all the funky coordinate math involved. So I cheated; I’ll repent with more beer.
For those interested, the world starts at 0,0 with the top-most tile. The X direction (width) goes to the bottom-left direction, while Y (height) to the bottom-right. This doesn’t really make any difference for anything besides sprite rendering coordinate and mouse location calculation. A*, all movement, etc. is still governed by World rules — i.e. 50×50 unit tiles aligned in a square grid.
The actual tiles are 52×26 pixels wide. The actual sprites are 50 pixel wide though and last two pixel columns are empty so that the tiles align nicely and don’t overlap anywhere.
Here’s a little explanation image I did ages ago:
And how mouse coordinates are obtained:
This is what the tileset looks like now:
Here’s a comparison between the two methods (square vs isometric):
Entry 8 or animation
Jan 22, 2011
Unfortunately (for me), the majority of games are judged by presentation and not complexity. This is best seen when flashy casual games beat mainstream titles in scores/praise. So today I focus on more “shiny” things — animation.
Health bars suck
First though, what I don’t like right now is that HP bars looks extremely clustered. After some testing, they definitely need to be “floating” above the mob.
May be slightly translucent bars will be better?
Nope, still a clusterfuck. Well, may be this has more to do with mobs swarming around the player character. But 4 attackers shouldn’t be so unrealistic. May be make mobs wider and make health bars even smaller?
OK, screw this, good enough for now. I need to stop nitpicking things and get major parts implemented. Someone might say — “hey, hey, why don’t you completely remove the health bar, like modern games do”, to which I can only reply — “get your casual gamer ass out of my yard.” This game has a niche target audience and health bars/points is a crucial feature.
Time for some hardcore animation done. By which I mean, change a tiny part of a sprite to make it “fake-move” and tell everyone I have animation. Still, it is more than many games have, even released ones. (think Civilization 1/2, Colonization; even X-COM had like 3 frames).
So let’s do this:
Although, the “animation” is just 3 frames — stand idle, start swing, and contact; this actually livens up the scene a lot. The implementation is just an attack swing timeout that every unit enters after swinging a weapon.
Let’s animate props as well. By default the props would not animate. Optionally “animating” flag can be set with a number of frames and animation speed. Let’s make a campfire:
Not that I can show this, but it does animate with 3 frames in-game and looks decent. As decent as a 10 min sketch can look. Oh, shush, this is a concept demo.
You know what this game lacks? And no, not a better author. It lacks walls/fences/barriers — all that fancy stuff that can go in between tiles. Not that anyone was really thinking “I only wish something went between tiles.”
So several classes and 30 min in Photoshop later:
The actual wall spritesheet (wallsheet) looks like this:
The World now has 2 arrays — for X and Y walls. Each tile can have neither, either or both.
Path-finding is a bit trickier now, as we must make sure you can’t pass through both walls if present on the tile, including diagonal movement. Little hacking later:
Now only if mobs didn’t attack through walls :)
The base unit logic for attacking is as follows. First, find a path to the target. If there is a path, then follow the path if it is longer than 1 tile or attack if close to player. If there is no path, then either attack if close or wait if far.
Now, since the unit is always to move if the path > 1 tile even if the target is in the next tile, the mobs won’t attack through walls. Not tooo difficult.
Still, while A* works great and units colliding push each other around, this isn’t true for props/walls/terrain. e.g. — a unit can be pushed into water, solid objects, through walls. So you can cheat the obstacles, but only as long as someone else does it for you. Fun.
I also made some drafts for dialogue script/system and dynamic conversations with triggers and stuff. I have not done any implementation, but it does deserve a mention as this is the first feature I am designing beforehand.
It’s funny how implemented features always require a different timespan that you expect. Such as, doing animation took less time than making wall logic. And in the end, few players would actually appreciate the logic behind wall avoidance/collisions versus a little glitch in animation sequence.
I’ve got 7 spritesheets and 39 classes. That may be an overkill for some, but the classes remain in a hierarchical structure. Any changes break the code minimally (think converting 2d->isometry or fixed tile->arbitrary position). It is also very easy to build upon this. Still 0 comments.
Entry 9 or math and graveyard
Jan 23, 2011
Making graphics is slow. And human eye is too damn good at detecting inconsistencies. No depth, gameplay, or story can save you if you are outright ugly.
First, I have to fix mouse -> world coordinate conversion. I have the world -> render implemented for unit rendering (sine they have fine shiftX/Y withing their X/Y), but not mouse click to world location. Currently everything relies of mouseX/Y tile. The “world tiles” are 50×50 units big, whereas the a rendered tile is 52x26px big.
Some funky math and formulas later, here’s an examples of mouse -> world -> render conversion. First Camera calculates where it thinks the mouse is pointing in the world. Then the Renderer draws a pointer at that location in screen coordinates. Matching results means everything’s shiny.
Now, what this means that the user can send his unit to any accessible location, and select mobs that aren’t in the middle of a tile or even if several mobs are in the same tile, which often happens.
You know what I realized? Walls between cells suck! There’s so much complexity in an additional movement and collision changing entity that behaves completely different from anything else. The game should be kept simple, so I will convert every wall into a prop instead. This only means I will need props to be flagged as either round or square.
So here’s walls as objects:
Now I’m sad that all the wall code had to be dumped, so I drew some graves:
Time to improve the editor to actually be able to handle tiles/props/unit properly. Both addition and removal.
There’s still a couple of problems present. First of all, unit collision is at times weird. Units next to other objects can get confused and act weirdly. Since A* works with tiles, sometimes a space which can be squeezed through is considered impassable. Since all enemies attack the player at the same time, they start to push and shove, so end up randomly running around some obstacles after being pushed away.
This can be partially solved by improving the collisions to not push unit around but prevent units to move if they are about to collide. So that could be implemented by some DoesCollide(x,y, sx,sy, size) method. This can also be used to test if mouse cursor world coordinate is truly accessible and not just free. It is arguable which is better — units not moving or units moving randomly.
Secondly, cursor location only identifies units, whose world projection matches that. As in — to attack a unit, you have to click it’s highlight, not its full graphic. The only solution I can imagine is do a little loop, testing the coordinates below the current position in case some unit is there.
Entry 10 or shadows and lights
Jan 24, 2011
Short day. Well, technically, the length of the day was the same. The duration of perceived time, however, equals the time I spent working on the game.
First of all, I need to fix unit selecting. Currently, only unit base location (i.e. flat projection on the ground) is counted as unit’s location. Of course, this is not how intuitive gameplay works. For this, a loop is needed that checks a number of coordinates below the mouse and looks for any unit tall enough with a base location at these coordinates. If found, then the mouse is obviously hiving “over” a unit’s sprite:
Currently, even with all unit collision rendering and mouse coordinate calculation and path-finding at each frame, the game runs at 380 fps at 854×480, which is good for this crappy laptop. It runs at 85 fps windowed and 110 fps full-screen at 1680×1050. This means that processing logic takes up much less time than the actual rendering.
Let’s make shadows. I don’t want props and units have shadows by default, as that would only make dark/bright environments looks weird with equal shadows and shadow angles for all objects. Of course, all the sprites are 2D and there’s no 3D data for anything, except mob height. So I will cheat and make shadows all the same (or several types), and dynamically adjust the size based on object/mob size.
Here’s some round shadows:
I obviously need additional shadows for square objects and wall. Also, light emitting objects (campfire) should not have shadows.
Environment lighted in the same ambient brightness is boring. So let’s make “light” Here’s a very simple way to light the terrain, simply add a black tint with translucency based on tile’s illumination:
The problem is how obvious it is to spot tile borders (think ”Jagged Alliance 2” or ”X-COM”).
Wait, why is it dark?
Where the hell did the day go? I haven’t ”really” done much. Although I did do 3 pretty cool features. I guess you may consider today the compensation for reusing A* and isometric math.