Tuesday, November 17, 2015

Capstone Post 6: Interpolating Given Time

Linear Interpolation is a hugely powerful technique, and can be very easy to implement in your code! If you implement it properly. Simply, it is a function of time which returns a value between an initial value (a) and a final value (b), given a time (t). Time (t) is a normalized value which represents the fraction of how far along in the Lerp we are. Calling it time is a bit misleading, but bear with me.

Knowing this, let's take a look at the whole one line of code that let's us interpolate given an a, b, and t:

Taking a look at the above function, let's plug in some example values. If I am Lerping between 5 (a) and 15 (b), and I am 0% of the way there (t = 0.0), this function will return 5. If I am 100% of the way there (t = 1.0), then it will return 15. If I am 50% of the way there (t = 0.5), this function will return 10.

Now that we understand how Lerping fundamentally functions, let's do something super simple with it: move from point a to point b in Unity C#. A really simple interpolation we often must perform is moving something a distance in a given amount of time. Well here ya go, pretty much exactly as you might have expected:


It's as easy as that! But by no means does Lerp stop here. What Lerp is really good at is interpolating anything. Position, rotation, color, velocity, acceleration, scale, even strings of text! Anything with a start and desired value can be interpolated between.

The real power of linear interpolation heck yeah there's more comes in to play when we do fun things with our t variable. A graph of the distance over the time for the above code would look something like this:



Very simple. However, we can run t through ANY function and it will interpolate properly as long as we normalize it to [0.0, 1.0]. What this means is we can turn ANY graph into a change in position, rotation, color, etc.


smooth: t = t*t*(3-2*t)
smoother: t=t^3*(t*(6*t-15)+10)
If you can graph it, you can run t through a function and Lerp it that way. Have fun out there!












Friday, November 06, 2015

Capstone Post 5: With a Machete

I worked a lot today. I woke up after working on capstone and then went to class and then worked on capstone and then went home quite late to write an indefinite number of blog posts (it's going to be two, counting the one before this).

A period of this particularly stuck out as the happiest. Zac and I got on the same page in terms of the new design direction of our game, discussing exactly how everything should work mechanically so I can program these things without having to make too many as-I-go-decisions. So, with this very specific approach to how everything would work, I began brain scheming and dug into the code. I knew I needed to change how things were set up because of the new design I talked about in my previous post. Having done a bit of work on it already, the architecture was headed in the direction of being a complete mess of useful code mixed in with outdated or useless code.

If you're building a house and you mess it up in the beginning it's fine; just knock down the house and start over. But if you already have the wooden frames of most of the rooms up, and you realize you put the kitchen inside the living room or something, you can't just tear down the house and start over. You tear down the studs and other wooden things and rebuild the kitchen somewhere else.

And so began the most joyous time of this night. So I got to both analyze and make changes to the existing, useful code and all that, but the code we didn't need anymore. Since we cut orbiting for cooler motion and arrows because they were lame, I had the pleasure of spending like an hour hacking through this codebase
with a machete.
As I was making boulders collide with the tail and the biomes, I came across the arrow collision code. Since we did away with the arrows, I got to select that code, and delete it. And every time I pressed that backspace key thereafter, my heart grew warmer. I fell down a beautiful rabbit hole: arrows spawn in Game Manager *SLASH!* arrows have a prefab *DELETE!* arrows have a script *NO PRISONERS*. Then I compiled, and wow look at all those lines of code that reference the arrows I had deleted out of existence. Well time for all that code to die *OVERKILL!!*.


But wait, planets still orbit and we don't want that, also the way the planets move (if at all) needs to be dictated from the BiomeProgressionManager. And so I went on to remove probably about a third of all the code in our game. It was a blast.


 Special thanks to Subversion! Without you that would have been significantly more worrisome.

Capstone Post 4: Progression Zoom???

The amount of work I have to get done on this game between now and Saturday, and subsequently the following Monday when we will be challenging Vertical Slice, is a little terrifying. We've taken yet another screeching left turn with Serpent Shadows, and this is the last turn we get this semester. I'm actually really excited about this! I've scheduled out everything I have to do (half on the task board, half in my brain board), and I know this is possible on my end (with room for polish, of course!). While the mechanics of the game have not changed that much, it turns out the code will need (and as of tonight, has received) heavy iteration.

We are working with leveled system now: at the end of a "round," the player will enter one of the biomes. The game will then pick up inside that biome, with challenges themed based off the theme of the biome. This biome will have another set of biomes in it, and those will have sets of biomes in them, and as you go deeper into the very-hard-to-explain game world, the biome themes stack with each other. So you go into a mountain biome, there are falling rocks, then from there you go into a river biome, there is both a river and falling rocks, and so on. We've dubbed it "biome-ception," for lack of a better explanation.

Concept: I shrink myself and eat pizza forever
This calls for a pretty big paradigm shift in the code I've been working with. I hadn't structured this in a way that is conducive to this new biome-ception, as I had no way of predicting that we would go this way. I don't typically set up code to work this way. So I had my GameManager, ya know, spawning arrows and keeping track of planets and whatnot. But now all of a sudden, I need to have some sort of "GameManager" for each level of biome-ception. I don't want to load a new level to do this. I want the transition between levels to be a seamless zoom, like the above pizza.

So I've been tasked with creating a code paradigm that's pretty significantly different than anything I've attempted before. It's one thing to load the next level, or move from one region to another in a game space. It's another to keep zooming into the next "level." So I have a BiomeProgressionManager class attached to my GameManager GameObject. This class handles all the biome spawning for sub-levels (but not the overworld, because we will revisit the overworld later in the game). GameManager still handles the biomes in the overworld, as well as data saving/ parsing from the overworld.

BiomeProgressionManager holds integers to keep track of how many levels of type mountain, river, etc we have gone into. It also keeps track of the current spawned biomes, as we do not need to save the ones from the previous level (unless that level was the overworld). It also holds the level prefabs to instantiate: let's talk about those.

So I currently only have the MountainLevel prefab, which has the MountainLevel script attached to it. This script will handle all obstacle spawning, and decide the difficulty curve as the number of mountain levels the player has been through increases. On instantiation, it will do it's own thing. The RiverLevel prefab will do much the same thing. So, say the player goes through a Mountain level, another Mountain level, and then a River level. Well, the next level would be Mountain (level2), River (level1). Since I'm using these prefabs, I can simply stack them on top of each other to handle this "branching" progression. The river level can be seamlessly combined with the two mountain levels to create the mountain1-river2 level. Interestingly enough, the code has taken on an inception-style structure, much like the game.

Luckily Zac and I have no problem sitting next to each other in a lab until the sun rises because it's going to take a lot of balancing to execute this well.

Side note: I effing LOVE this idea. We needed a weird progression in the game, and we came up with one. No currency, no stars or coins or powerups. It fits the game so well I just want to hug it. And make it happen. It's going to be a long week.