10th July Progress

Hi chaps

A busy day at Chucklefish.

We’ve been doing a bunch of design work today.

Consolidating our final todo list (it’s getting shorter!), working on boss designs, fixing a ton of bugs, tweaking a bunch of UI elements, slotting items and features into the progression system.

We’re also working on the leveling system and the quest log.

Omnis grappling hook is now in the game but requires some bug fixing before he can show it off. I know he’s super eager to do so. The grapple hook code is actually going to be used in a whole bunch of different items.

Through play testing we felt that the inventory was just too small, so we reorganized it and increased its size a bit. What do you think?

 

inventory

 

Leave us feedback on the new layout :)

9th July Update

Can you believe we’ve been doing these for two months? Crazy. To celebrate I’m going to be doing a rather technical update, which several people have told me that they wanted. So you’ll get everything, including badly drawn diagrams using my trackball, and my oddly disjoint ramblings.

Today, I finally got the grappling hook in the game, as in you spawn it and equip it and doesn’t crash or break or anything. But there’s many different glitches I need to fix before I can show you off. So for today’s update I thought I’d talk you guys through the logic of how it’s (already should, but doesn’t quite yet) operate.

As I mentioned before in various places, but many of you may not have yet seen. I’m basing the behavior against an old SNES game that very few people have heard of called “Umihara Kawase,” a game which I was introduced to back in 2004 by a TASVideos run.

So let’s talk about grappling hooks and the properties thereof. First off, let’s talk about how the stretch mechanics works. If you remember back to your physics class, we’re going to be using pretty much just the spring equation to calculate this. This is simply F = kx, where k is a constant that we’re going to define in a config file, and x is how far the rope is stretched from “rest.” Of course, you can make the rope’s rest length longer and shorter while you swing around. So all we need to do is calculate how long the rope is. Well… how do we do that? Especially considering that the rope might wind up going around blocks.

Well, we need to keep track of where the rope has bent around something, of course. So, let’s talk about what defines a corner point. Well, first it needs to be anchored to the block it’s curving around somehow, so it needs an anchor point, which is typically one of the corners of a specific block. But blocks share corners in a tile based world, so we need to know which block it’s curving around. Which means we need to keep track of a list of these pairs of values, one tile coordinate, and one spacial coordinate.

But the real source of complexity in this problem is the ability to add and remove blocks. Most other games that I’m aware of with an interesting and complicated grappling hook (Umihara Kawase, Worms, Hedgewars, I’m sure there are more than a few others), don’t have to worry about mutable terrain. We do. This means that at any time one of the blocks that an anchor point is sitting against can simply disappear. What happens then? Or what happens if a block is placed over the line?

Well, in the case of a block disappearing, we want to detect that and then move the anchor point toward the midpoint of the line formed by the previous and next anchor points. Unless the anchor point that disappeared was the hook. In that case we just want to break the connection and watch the poor sap plummet to his doom. Actually, I’m probably going to change that up a bit and just make gravity nom the hook, rather than making the line disappear, but right now I just want it good enough to get on the screen and start testing so I didn’t implement it.

derp1

After we flag the anchor point as moving (over the course of several frames) towards the midpoint, we also need to check the lines before and after to make sure that we didn’t accidentally drag the line into the wall as a result of the move. We also need to check to see if we’re close enough to the middle to remove the anchor point entirely and treat it as a straight shot through.

How about for the case where a block appears in our path? Well! That’s actually similar to (but not the same as) the case where you’re moving around and the line runs into the wall. So I can just write one set of rules to handle that.

If the path between point A and point B is blocked, we first must determine all of the tiles that it’s colliding with. Then figure out which one is the closest. This will be our working block. Now there’s two cases here. The first case is when you’re looking at the block face on, in which case you’re going to need to consider the two corners that you can see. The second case is looking at the tile edge on, which means you need to consider the two opposite corners.

derp2

We consider one side, then the other, which means that I eventually need to introduce a randomness element so it doesn’t consistently favor one path over the other. Anyway in the first case we try the left corner, and check to see if we can actually go around this way (by checking the tiles adjacent to the corner), then if that works, we repeat the algorithm until it returns that we made it (so we try to draw another line between the corner and the far point, discover that we’re travelling through the block again, and then aim at the other corner.) Additionally, there are some checks that prevent doubling back or doing otherwise impossible things. This is a rather crude depth first search through sort of an impromptu graph. I don’t even keep a visited list, those I might need to in future iterations of the code for reasons of not having infinite loops.

There also are other cases, for instance you’re swinging around a wall and your grapple pulls away from the wall, we need to detect that (by detecting that the angle formed is greater than 180 degrees.)

There are some more complicated bits, but it’s now 5AM in my part of the world, and I have to get up at 9AM to start work again on this stuff. Hopefully, we’ll be able to show this off in the next few days. Sorry, I jumped the gun a bit and promised Tiy that I was going to make a video on it when I got it done in a day or two (which was like 4 days ago…), I had some code problems that slowed me down dealing with unimplemented areas of C++11 that I expected to be there (specifically the function I wanted was std::deque::insert(DestInterator locationToInsert, SourceIterator begin, SourceIterator end); I expected it to return an iterator, because when you call insert on deques it invalidates all current iterators to the deque, but it didn’t, because it hadn’t been implemented yet.)

As far as what everyone else has been doing, I honestly have no clue. I’ve managed to wall myself off to work on this for a few days, and it’s been a bit stressful, but ultimately rewarding. This was really fun to work on, and thank you so much for your indulgence. And I hope this wasn’t too boring or frankly terrible oh my god I can’t believe you call that drawing what is wrong with you.

8th July Progress

Oh man it’s me again..

So, what’s the scoop.. Well, like Tiy said I’ve moved to Orlando!  Holy cow is moving 420 miles with two people and two cats in a pickup truck not as fun as I imagined it to be!  But Orlando is nice and as of today I now have a desk and a bed finally so I should be good to go :P

Bartwe has spent the day squashing all sorts of bugs all over the place, some with beds, some with status effects, and some others.

Omni is still working out the final touches on the ninja rope.  I know it’s taking a few days, but after hearing the explanation of what he’s doing with it.. it’s gonna pretty cool and well worth the wait.

Legris is currently working on the glitch intro, which is coming along nicely and we’re all very excited about!

Like Tiy said I’ve been working on leveling.. everything.  This is the part of the development cycle where the game really starts to take shape as a real game, and it’s important that it’s done properly and in a flexible way that allows us to adjust and balance everything properly. Sit down while I get technical for a second:

Because so many things in the game are dynamically generated or at the very least flexible, an awful lot of things really can’t just be *set* as a value, because a single value is just too limiting and boring.  For example, take a random monster with a certain leg type that we decide should give the monster a ground speed boost.  Should that ground speed boost be the same for each level that we can generate monsters with that part, or should the speed boost become greater as the level of the monster rises?  Maybe take the same scenario, but with a jumping boost, or an armor boost etc.  Some numeric parameters like this *will* be hardcoded, or perhaps specified as some kind of multiplicative factor, but there are an awful lot of inputs for us to deal with and an awful lot of balancing to do, and not everything will work like that.

Any randomly generated monster has a ton of what *could* be level dependent parameters.  An incomplete list would be health, energy, physical damage amounts, knockback amounts, status resistances, mass, walking speed, running speed, swimming speed, etc etc etc.  Then, after that, it has a list of status effects it gives off, and those have intensity and duration, and then also any projectiles they give off have projectile speed, projectile time to live, projectile physical damage, projectile status effects, etc etc etc.

So how do you take ALL THESE PARAMETERS that are more or less randomly selected and turn it into something that can be balanced?  The trick is, is that really none of these parameters can just be a value, they have to be a function of the level.  We don’t want to hard-code anything in source code because there’s a lot of tweaking / balancing to do with a TON of inputs, besides being really really difficult to manage in code.  The best most flexible solution we found was to allow these fields to be specified, in JSON, as a *function* of the level.

Now, I don’t really want to write a math parser to handle real mathematical functions, which is good because exactly nobody wants to write real mathematical functions either.  Instead, tons and tons and tons and tons of parameters in our configuration files will look like this:

“baseMaxHealth” : [“cubic”, “clamp”, [1, 20.0], [50, 500], [80, 1000], [100, 3000]]

Which is a pretty simple to understand thing, it’s just a table of <level> and <value>.  But through the miracle of *cubic spline interpolation* it turns into a nice smooth curve which I’m too lazy to draw right now.  In this way, we’re able to specify *how parameters change with level* rather than just specify the parameter directly.  This will also allow us to do the huge amount of balancing and tweaking that we will have to do with as little pain as possible, which is probably still quite a bit of pain :D

So, I’ve pretty much gotten this applied at least in some form to most things that use damage and stats, but there’s still a *lot* left to do, and not everything that is leveled is this simple!  There are biome and ore distributions to adjust, the existing gun and sword and shield generator math needs to be looked at again, there will probably be a large number of parameters to monster and npc generators that are not curves but tables of what parameters are acceptable at what level, and on and on.

So, sorry for talking your ear off,

Kyren Out.

Edit: It has been pointed out by Havoc that the curve listed looks weird with cubic interpolation, which is true!  In fact, these are a) values I pulled out of the air, and b) it comes from a code example which is linear interpolation rather than cubic, and I changed it because I thought cubic was more interesting for a post.  Nice catch, though, should have plotted it before posting it as an example!

And he’s right it is weird, and shows that you have to be careful when using different types of interpolation or you might end up with a not monotonic increasing function!

rwMIwiU