Entry 61 or artsy stuffs

Apr 7, 2012

Besides tedious bug fixing and iteration, drawing is the slowest bit. But the results can be appreciated better. You don’t really see fixed bugs, but you do see a new tree.

Here are some of the props we have with a few more variations:

Not exactly stellar, but now it doesn’t look all monotonous when there is just 1 flower type and 3/4 variations is more than enough to build a cool propped terrain. (P.S. the shadows are missing, so they don’t sit great, but it’s WIP.)

Since we never finished the “new” collectors, time to revert to the old ones (from end of October last year) with a “painterly” facelift:

I think they are quite cool. They are different in looks to towers and keeps, but that’s what happens with >1 drawer and style. Not that I can call myself that — this took forever and still is.

Here are island houses (library, brewery, telescope, pub):

In addition to most of Phil’s work (library, pub, base for others), I worked a little on missing/incomplete bits getting these ready for “final art” stage. (I swear I’ve said that a dozen times.) I’d really love these to have damaged/destroyed versions, that the player can upgrade to renewed ones, but that’s half the work of drawing full ones…

 

Entry 62 with things that make mobs better

Apr 11, 2012

I guess it’s that time again — coding. Oh and I wish it was the exciting kind…

Leave as you entered

I hate to cheat, but… consider current keep implementation. Mobs (blue) spawn at a certain point on the map and then proceed to the target keep. They spawn at regular intervals and thus preserve the same distance between each other (green). The target keep assigns each mob a “keep spot”, where they will stand once they arrive (cyan). This is a per-designated circle around the keep to make it look pretty. Some time later the keep needs to send the mobs away for further attack. The problem is that the distance from the mob spots to the road obviously varies, whereas the attack frequency doesn’t. So mobs end up at different distances from each other (red). Here the image:

I hate to cheat, but… I have to. It’s a little too much to do a path-finding to the road to determine when to release the mob just so they group nicely. So instead I just teleport them to the keep exit, so they “spawn” roughly at the same spot. But now it’s all kinda crap. They arrive nicely, but leave messy. So might as well make them all arrive nicely. This also solves a couple other issues, like what happens when the keep runs out of spots for incoming mobs.

Well isn’t this exciting! </sarcasm> On the plus side, this means I could have custom spots on the keep itself, like guard units or something (since there isn’t a valid path “over” the keep). That would be pretty cool.

Welcome to the party

Everyone say “hi” to Blob and Delta:

Phil’s made two new mobs in Maya, and with some clever toon shading and UVing made them look almost not out of place. I guess it’s time I implement shadows for mobs to make them sit proper.

Button shadow

So here’s blobie with a button shadow:

You can actually now tell which frames are above or below ground, i.e. when he’s jumping. Comparing with the previous image you’d almost think how could we not have shadows before. Yep, the power of “small” things. Obviously, the button shadow itself is just a simple sprite:

I resize it based on mob (type) size, so different mobs get differently scaled shadows:

There are 2 alternatives for button shadows. One is that each mob type gets their own shadow, which is probably more work than it’s worth. The other is that each mobs’ each sprite (or at least each direction) get their own shadows, making them very realistic. Unfortunately, this is definitely more trouble than it’s worth. (And I won’t even mention shader based shadows or whatnot.) I think simple drop button shadow works pretty well.

 

Entry 63 or slow evolution of towers

Apr 15, 2012

I’ve posted this a little before, but here are a few of the “areal” projectile mechanics and stuff. Air tower + ash tower = ash projectiles being blown at enemies:

I fixed the shadows, lights, ranges, etc. for once. Similarly a tremor tower stomps the ground and nearby plants produce more gas clouds, also blown by air:

Here’s the inferno tower. It doesn’t look like much and the projectile is pretty lame, but it’s an area effect. It has a short range, so it’s best placed in corner and such.

Originally, we wanted to have waves of fire and stuff come from the tower itself, but that’s a bit on the complex side and the sprite requirements are pretty steep at best.

Here’s tornado tower spewing out tornadoes one at a time. These are also aoe damage and can be affected by wind (air tower). We have a few cool ideas what to do with them.

Tornado lives far longer than any other projectile. Even longer than ash/poison clouds. So I made additional transitions for these two — grow and fade. Small, new tornadoes quickly grow from nothing to full size and expiring tornadoes slowly fade away.

Here’s a superunit in works. Look at these subtle details and intricate features!

 

Entry 64 with superunit

Apr 16, 2012

So we are making a “superunit” — a big (possibly upgradable) unit that will serve as player’s offensive force and defensive when idle. This means the unit can capture keeps. However, it needs to time the attacks well, otherwise it risks being overwhelmed and destroyed. When I say “it”, I mean the player.

Superdirect the superunit to a superpath

Firstly, we need to be able to send the unit to a keep or coordinate. This is pretty easy since enemy units already do this and I’ll reuse the class with a few adjustments. Obviously, we need to be able to select it first (ignore the magenta debug border):

Now, clicking anywhere on the map tells the unit to go from “idle” to “goto location” mode with a couple sanity checks.

So here is the unit target locator. I think it should be pretty big/obvious and always visible, as this is basically player’s main unit — i.e. player. Need a better graphic though.

So A* works like a charm for me. The world is neatly broken into tiles, each tile has a specific weight (how hard it is for unit to move in it), and all objects have a per-tile pointers for quick access to see which tile houses what. In addition to all the collision detection, I can pretty much make paths exactly the way I want them. Except our superunit is special — it can walk on any passable terrain without wanting to choose roads:

And this works nicely, a pretty direct route is chosen for the unit to take. This is now also useful to units that are not attacking and following the roads, but are going for a nearby unit/tower/keep/spot.

Here’s another useful thing, zone borders:

I don’t know if I can make them look much prettier than this. Since everything is tile based, so are the border sprites. It’s pretty complex and time consuming to try make smooth lines that actually align as well. Such would need to cross tiles that aren’t even neighboring other zones and do all kinds of weird and processing intensive stuffs.

 

Entry 65 or keep garrisoning… again

Apr 16, 2012

I already discussed this, but there’s lots of logic now behind units being garrisoned at the keeps. I convinced myself to cheat and teleport them, and it works sorta well. Unfortunately, this looks crap and breaks some state related stuff. And now we need superunit to interact with these units in various ways. So I guess we are doing this the hard way.

Keep in, keep out

This is the typical scenario — enemy units/mobs (red) arriving by road (beige) at the keep (blue):

The units are going to the keep’s entrance (black bridge), not the actual spots right away, as that might break some path-finding, especially if the road curves near these spots and going straight is quicker than going to the entrance first. Then they go to their assigned spots.

Note that path distance L1 (closer spot) is less than L2 (farther spot). Obviously, it takes longer to get to the far spot than it takes to get to the near spot. But we don’t care, it’s just arriving and it doesn’t look that messy. Now the units are at their spots and all is dandy:

Now, if the units leave like they entered — go to spot and proceed to next keep — it will cause a serious mistiming. Assuming keep sends a unit every 1 sec, it will send that unit 1 second (black) plus path-time seconds (red) later:

So the units will leave the keep roughly 2, 3, 4, 5, 4, 3, and 2 seconds after being triggered. This means units will have different distances between them and we really don’t want that. So what I do is, when precalculating keep spots, I also store the distance and add penalty for units closest to the exit:

So this way, everyone leaves at the same time and we keep this nice illusion of wave/column.

Unit states

Obviously, units need a little more memory on than “go there”, namely “why?”. That’s a very simple way of saying I’m using states. For the above exercise, there are 4 states shown in different colors:

Red is “goto keep”. Magenta is “garrison keep”. Aqua is “defend keep”. Green is “leave keep”. Yellow is “goto keep” (but with different parameters than before). A simple reason why units need this is because they are very simple. They are on a need-to-know basis — they don’t know about keeps or enemies, or pretty much anything else, they just know how to find a path. So we need to keep track of why we came here and what we will need to do once told to — i.e. current state. Other basic stuff units are told are target keep and target coordinate. And this works very well. The best benefit is that I can code behaviors independently or equally, depending on the state. So I may choose to take state into account when deciding where to go next, but I will ignore it when animating a lightning zap.

Attackus nearbyus

If one follows closely, then an obvious comment is: surely, this can be simplified. Just make “goto keep” and “defend keep” and set the path-finding via the waypoint. Well, whoever you are, consider this:

The defending unit needs to attack some pesky stickman nearby. This would actually happen every time the superunit gets near a keep. But in this case we cannot attack while in “garrison keep” or “leave keep” states, because the game expects them to take a certain time and free up the space for further actions. It happens rarely, but is possible. I also don’t want units dieing in states which affect the keep without my precise control. So we only want the unit to attack enemies (orange) when already garrisoned (aqua). This way, nothing will mess with our arrival/departure.

Entry 66 with a keep capture progress indicator

Apr 17, 2012

We needed a progress bar or equivalent shown in the game world above a keep that’s being capture. A simple thing, right? Riiiight. Well, firstly we decided it should be a variation of radial design, mainly because a horizontal/vertical bar are too big and the text doesn’t quite center on them without some problematic issues. Anyway, here are a few radial progress bar ideas Phil proposed:

So I chose the last (simple version of the second) one for now. This sounds great… in theory. Even with a little work we can make pretty decent sprites for this:

Background, foreground, and indicator.

Now the fun part: you can’t exactly crop a sprite under an angle, it’s all rectangles. So how do I fill in the bar gradually when it makes an arc? Well, here’s my journey from empty sheet to post-implemented version:

The gist of it is that I split the foreground sprite into 3 parts — first 12%, middle 76% and last 12% of the arc. Then I draw the first 12% growing up, middle 76% growing rightward, and last 12% growing down:

The little bubble on top hides the fact that the sprite is being cut horizontally or vertically and, more importantly, the bit where two sprites “join”. Here’s the implemented almost seemless version:

So simple, yet so … well, at least I can’t complain I have nothing to write about. Anyway, time to make the units actually do their thing.

 

Entry 67 with wind shader

Apr 20, 2012

Since our air tower is the boringest one and has no visible wind indication, I’ve been working on a cool shader effect:

This is basically a wavy distortion (heat wave) with a sin/cos applied to the source coordinated. This means I sample the pixels which are [-1..1] * size away from the actual location. Applying a time-based offset to sin/cos, shifts the wave and eventually loops back (i.e. goes a full wave). This looks pretty cool when animated and obviously hard to describe.

So for air tower, firstly we need a “wind” mask — a simple texture that paints in the pixels that need to be distorted in this way, plus some transparency and blurred edges for smooth transition. The mask is just three black button shadows of varying sizes/transparency.

Now applying the texture to the shader:

It’s pretty subtle on a screenshot, but quite visible when animated.

Other towers are also slowly getting upgrades/polish (so to speak). For example, the fire tower got it’s head/stream/effects tweaked. I mean it’s gotta be somewhat better, right:

 

Entry 68 with many menus

May 4, 2012

So much stuff  that needs doing is now… fluff. I can code half a day and then in the end go — well, what can I show for this? Ummmm…. yeah. I guess Phil’s sprites is the only consolation when we get some visual stuffs.

Menus

So, first, of all, new menus and controls. So there go my old sprites… again.

Here’s an options screen and some more fluff:

Overworld

Phil’s also made a nice little graphic and accompanying sprites for the overworld/map:

This is basically the mission screen where you can start available missions and replay old missions. It still needs more fluff to it, but we’re getting there.

Nothing more visual at this point. I’ve been remaking the collectors, but I’ll post that when they’re done. And I don’t think I have the patience to go into the codey tedious bits. May be I’ll post some of that stuffs later.

But yeah, no kidding about last 20% being 80% of work…

 

Entry 69 with projectile flinging

Jul 5, 2012

Between moving houses, doing garden work, and working on my secret project™ I’ve slacked off on blog posts. Admittedly, most of work is (as I mentioned) tedious tweaking and bugfixing.

Predictaments

One almost-mandatory feature is anticipation/prediction of enemy position before a projectile is fired. It is easy to just fire at the enemy where it is now (and hope for the best). However, enemy location almost always changes while the projectile is in flight.

A naive way of firing is to not predict anything and let it land behind the enemy and still register a hit. This is how I did it at first, but it looks retarded. It almost hits the next mob with the time it takes for certain projectiles to finally arrive. A less naive, but weird way is adjusting the projectile as it flies. So if the mob moves, we change the angle slightly. This works fine in most cases, but is very obvious when firing a stream of projectiles or when mobs get extra close to a tower. So this won’t do.

Here’s how it’s done proper. So if the enemy was at green position I when the projectile was fired from brown location I, then we have to aim at position II. This means guessing that the enemy would have moved that distance (orange arrow). Guessing is relatively simple — look at the enemy’s angle and offset the target by a distance proportional to the full distance to the enemy. In this case, this might be a 20% adjustment — so if the total distance is 200 units, the the projectile is fire 40 units ahead of the mob.

As a side note, I could just use the A* path the units are following, but this seems too complex. Besides, firing ahead without fancy path-finding looks natural. If the mob turns, the projectile “misses”. (It doesn’t technically miss, since it always lands on the target as long as it is alive so that I can avoid any precision errors and not worry about 100% precise math/prediction.)

Vulcano tower

I’ve been long thinking how to make the vulcano tower work best. The way Phil drew it from out early concept stage is that is has four separate turrets pointing in different directions. Utilizing this is sightly tricky, because all my towers have a single “head” (turret or otherwise) and all the variables are specific to that one. So basically I made it possible for towers to have more than one head, so to speak. This just means that every tower except vulcano have one head, and vulcano has four. Now I can deal with each one separately — find target, fire, Consuelo resources, set cooldowns, etc.

I made each head/turret only fire in it’s pointing direction (blue cones). So if enemies are in that region, they can fire. This means the tower can be firing up to four projectiles at the same time.

This makes it an excellent tower for tight turns, but not as useful for straight paths. And it is now definitely unique and a worthwhile upgrade from the basic earth tower.

Collectors

My thoughts on collectors can be summarized as “unnnghhrrrr”. Not sure when else to post this, but I’m having fun posting them in every third blog posts with a commentary of “well, we changed collectors”.

The important bit is that they are technically implemented… mostly. I just need to finish them up, polish them up, and then do all the fluffy user interface bits.

I also added some sounds, but you’ll have to take my word for that one  ^_^ .

 

Entry 70 with UI-ness

Jul 6, 2012

Costy tooltipness

It’s now time to describe some of the fluffy UI stuff that I’ve been fiddling with. In this case — tower upgrade and transform costs. Towers can be upgraded to level 2 and then level 3. Towers can also be transformed to their possible “transform-buddies”.

It sounds nice and straight-forward to just print the numbers and forget about it. But I do have to not only draw them in tooltip, but also check if the player has enough before actually upgrading and deduct everything correctly. A little lack  of forethought last year and it’s essentially a tiny mess of arrays and numbers to deal with.

But I digress, here’s a tooltip for upgrading a tower (ignore missing button icon):

Same way, here’s a tooltip for upgrading:

Now the semi-tricky bit is that it’s also possible to first upgrade, then transform and first transform then upgrade. So if I have a level 1 inferno tower and level 2 earth tower, they need to upgrade/tranform with according costs. So here’s transforming level 1 inferno:

And here’s transforming level 2 earth tower:

I have purposefully kept the costs at 10 per essence and 50 wood for a “single” upgrade/transform (except 100 wood to build initially). This way, it doesn’t matter how you build them — upgrade first of transform first — the end costs are the same and no exploits are available.

Such a simple thing but you’d be amazed just how much tedious crap one has to go through from button controls and correct essence type indexes to tooltip rendering and positioning all the text and sprites…

Another UI nicety is that it shows insufficient resources in red. This way the player doesn’t have to guess what exactly was wrong with their attempt to build.

Progressive progress bar

Then there’s the upgrade bar:

“But shouldn’t there be a cancel button?” you ask. Oh yeah… so more fiddling with adding the spent resources back. It’s easy to cancel upgrading and new tower building; it’s a bit trickier reverting tower transform — after all you can be building the same tower in multiple ways.

Progression limitation

Finally, what about towers that are not yet available to the player (due to level progression)? Now that’s a little tricky, but thankfully (for now) this only needs a change in tower transform button choices:

Here, only ice tower transform is available to the water tower and not the other 2.

So there you go. Essentially, I added a couple buttons and a couple labels making stuff that is expected there anyway. Yet it takes a scorching day to do. It’s probably my fault for making everything object-orienty and dynamic. I can have 1000 or 10 towers equally fine with all these systems. Yet I’m not 100% sure it was worth it for 14 towers. I guess I expected more towers/sprites to eventually be there. But gamedev is a fickle bi… umm.. cruel mistress.

Uproot DevDiary entries 61-70

Leave a Reply

Your email address will not be published. Required fields are marked *