Monday, November 30, 2015

Day 99: Tired, Yet the AI Advances

Today was an especially tiring day. Managed to get the finishing touches on Robotron's score, using the modulo operator to get each digit and constructing a score with resets for a playable game:

 I also learned that hulks change direction when you shot them. Who knew?

As for the capstone work, AI was so especially fiendish that I forgot the blur-based health system I put in earlier today:


Turns out the AI doesn't respond to traditional MoveTo nodes excepting a special MoveTo function that DOES NOT STOP moving toward the player, even if the original target object is no longer on the blackboard. The only way to stop this was to set a StopMovement function to halt the target in its place. If the AI MoveTo node doesn't work for location, I'll have to setup a series of empty actor waypoints for patrol navigation in the meantime.

Sunday, November 29, 2015

Day 98: Death From Above

Today was the day that AI finally gets built in. The ant itself is a bit of a workaround; the AI controller requires a character class, which means a skeletal mesh with specific animations. For now, I put in a human character and made him invisible, rendering the ant a menacing foe:


As for the movement, vertical traversal is a tricky thing with Unreal. Technically, the engine offers nav link proxies, or points where one can exit the navigation mesh for a short time. This constrains the jump points to certain points but allows a specific to/from movement that allows ledge jumping:


As for the to-do? The ant is affected by gravity wells and time dilation, but I have to figure out a way to disable the character movement so it can float like a good (pink?) object.


Saturday, November 28, 2015

Day 96-97: Spending Some Time With Friends and the LAST HUMAN FAMILY

These past few days have been busy catching up with good times and good friends (blurgh, it's a holiday, why not?) but I've managed a bit of work here and there.

First off, the last human family. Sounds dramatic, but they're the score items in Robotron, and they have an oddly complex movement system compared to the rest of the enemies and player. So complex that I had to write a new collision system that not only returned a bool if it was colliding, but passed a variable by reference to store the direction to determine where the family member would be going next. The family member can move in 8 directions (cardinal, diagonal), so the direction of their collision directly affects their diagonal movement change.


As for the capstone work, I've been inching myself toward the AI elephant in the room. I'm not too familiar with any kind of AI (nor interested, sadly) but figured that at least a simple AI for enemy interaction in the game would be used. In that case, I've been going through Unreal's creation of blackboards, behavior trees, and decorating pawns with AI control tasks. We'll see how it pans out tomorrow!

Thursday, November 26, 2015

Day 95: Happy Thanksgiving With Some Extra Work

Today contained a little bit of work for me today, despite the holidays. First off was a charge shot; by setting the projectile's construction script with an input parameter for initial speed, I could grow the initial velocity over time. As for the gravity well and time dilation, timing differed for each one. For the gravity well, the class could be timed and destroyed (called by way of the blueprint), but for some odd reason, the test object that the gravity well was attached to still had the component despite the destroyed actor. Thankfully enough, the blueprint could still detect a destroyed actor within a child actor component, but this illuminates the tricky issue with blueprint and C++ communication. Heck, the blueprint interface is even quite limited, as for the dilation slow down and deactivation, the function has to be reimplemented for EVERY subclass object. Blarghle.


Wednesday, November 25, 2015

Day 94: Hitting A Wall, Metaphorically and Literally

Today was the perfect day to work on walls! Got myself to work field collision for the Robotron project so the boundary field could have four different collision checks to test each boundary as necessary. So far, with the addition of a slight top/bottom offset, it works well.

Today was also not the perfect day to run into a wall. Turns out time dilation in Unreal Engine 4 is SEVERELY limited by the PhysX it relies on. The Custom Time Dilation, supposedly for actor-based movement, does not keep into account physics-based motion. Strangely enough, Global Time Dilation is not affected by this issue.

How to fix this? ...There really isn't a way. Linear and angular damping can be increased 10-100 fold to limit individual movement, but still moves rather quickly when interacting with the player and adding forces. I'll have to run it by my producers to see if they want to continue further down that route.

To turn things around, I also looked into tessellation passes on meshes and distorting them with the extra vertices, allowing a neat crystalline effect that can grow as the gravity well crystals grow. By taking the vertices and displacing them by a combination of a tessellation height and a provided texture (normal, other texture, etc) one can achieve a really neat effect:



Oh yeah, and things also deactivate based on the tracking crystal instead of a tricky timed effect; it fits plenty better with our existing mechanics and provides some interesting limitations on the various effects of each line.

Tuesday, November 24, 2015

Day 93: Plans for the Future and Extra Cronies

Today wasn't too much of a day for RPP progress. My producer had me work projectiles as a means of switching (along with the ley line), which had me battling some blueprint code that replaced my ObjectToActivate (the mystic moving objects) with something else. Careful surgery (ripping it out) fixed it right up.

As for the critique on this round...eh. I think they missed the point. We do have some ideas on iterating upon our progress so far, especially the personal time dilation (along with global) and attaching attunement based on the tracking crystal's current color.

Robotron, though, went splendidly. I worked the Grunts' behavior (normalizing the distance toward the target and move toward it) along with the Hulks (randomly move in a direction). When destroying the mines (first time, since the player can't move yet), I had to move the object up and right by half the width when scaling down to make it look like the object is shrinking toward the middle.

I also worked a function to draw two quads on the hulk, one for the flashing portions (white texture part) and the rest of the hulk to get that flashing piece effect:



Next? Well, as you can see, hulks and grunts can't go through walls. Gotta fix that.

Monday, November 23, 2015

Day 92: Growing Wells and Flashy Triangles

Today was a day to help focus functionality of the various little effects that I was tasked with over the weekend, namely the gravity well. Unfortunately, the gravity well had to reflect its function from C++ to blueprints. This got especially tricky when dealing with the interface. The interface controlling states was a blueprints-only one, meaning I had to focus state functionality based on whatever implemented the interface.

After that, I had to find a way to put an interface function in to get the color state, so the gravity well that would appear from projectile impact wouldn't effect the object that made the well. Also, thanks to the wonders of overlap events not working if nothing overlaps it yet, I had to make a fancy growing well that varied the new refractive textured mesh along with the sphere radius. It's undergrad all over again.



After hence, I made some more progress in the OpenGL project. It's looking a little more like Robotron, with a second texture (no more hardcoded GLTexture enabling, framework!) and gave it a static manager that flashes obstacles with the exact same color over time, along with a randomizer that used time for better seeding. Soon, I shall have input functions. Someday.


Sunday, November 22, 2015

Day 91: Sometimes The Gravity Wells Come Back... Again

I'd never thought that a mechanic I implemented in a previous project would make a reappearance, but here it is. After working with the tracking crystal (which, by way of storing all nodes in the scene and detecting which one is closest to shine it with a specific color (double-parentheses note: will be optimized by not checking every single frame)), I also had to make a quick fix on the nodes. Seeing as nodes will not always be boxes, I had to update the entire parent object of the node to a more generic sphere, instead of a box one can jump on. This may also lead to work in the future that concerns where the node rotates once detached.

As for the gravity well, I had actually implemented a similar concept where an object would disable gravity on an object and instead apply force toward a specific point. It's thankfully quite simple, but will vary based on the object. A character movement component is quite straightforward, but anything else will either have a pawn movement component or a specific primitive component that has physics enabled. We'll keep it to the mesh for now.




As for one last thing, I also applied a custom time dilation effect for later, so that the entire world slows down (projectiles included) until sped up, allowing such things as a circle of projectiles to be drawn around a target. The way that time dilation works for objects in Unreal Engine 4 is that a global time dilation is multiplied by an actor-specific time dilation. That said, if the whole world were to slow down except for the character, the character would have to vary dilation to be higher than 1.0.

Next up? Not sure. Design needs a bit more work before I can continue further.

Saturday, November 21, 2015

Day 90: Attachment and Mystic Moving Object Thingies

Today was another day of good capstone progress! I worked with the objects whose behavior was activated by the beacon from yesterday, namely mystically moving objects. These objects block like platforms but ignore physics, so I could control their movement and rotation via interpoloation. Unfortunately, due to the Euler-angle focused rotation, I had to constrain the rotation of at least the pitch to below 90 degrees.

The good part about these objects, though, is that they can be referenced by a grouping object that can activate them all at will. I applied the same to the nodes so the producers can easily see them.

Next up was a tricky part; the pushing was not a desirable moving strategy, so the next effort was to attach them directly to the player. If the player just snap-attached them from wherever they were standing, there was a danger of the force propelling the player at a ridiculous speed, so I put an attachment point slightly ahead of the character, a placement distance, and disabled physics for the node when attaching. Even so, I had to change up some things (no locking movement anymore, just extreme linear damping) because the node would remember its previous z position and snap back into place.





Next up? They really like the idea of a black hole; thankfully, this is where undergrad experience comes in.

Friday, November 20, 2015

Day 89: The Ley Lines Bleed Red and...A Single Sprite

Today marked some fairly good progress in getting used to Unreal Engine 4 C++ programming! (moreso than "Don't put includes inbetween generated headers and UCLASS!") but hey, I discovered that too.

The plan today was to create a collider for the ley lines themselves; calculating the collision from beam particle systems is (impossible?) risky business, so I used a simple collider. Problem was, I had to change the collider on the fly in accordance to changes in the beam itself, so I placed the collider in between two connecting nodes, rotated it in the direction of the cubes, and set the extents to the distance between them. Problem? For some reason, box extent length is not world space length, so I had to apply a little extent reduction offset before the colliders would show:



After hence, I also put in the switch for the ley beacon. The ley beacon would react based on the line that had touched it, so I considered changing the material instance parameters. From what I remember from previous UE4 work, the program needs to create a dynamic material instance and change those parameters before applying it to the actual mesh's material. After applying another exposed color parameter from the particle beam (why Color Scale Over Life instead of Initial Color, I will never know), the beacon lights with whatever ley line touches it.




And also! Back to the programming project side of things, today also marks the start of working in the Xbox XDK, or (with less fanfare) a horribly deprecated version of OpenGL. If only they could tell me earlier that it was just an obsolete OpenGL instead of some fancy framework, I could have studied beforehand, but I persisted nonetheless to bring a single sprite to the screen:



To-do: decrease the default resolution, but I can barely see through all these MAGIC NUMBERS IN THE FRAMEWORK

Thursday, November 19, 2015

Day 88: Laser Ley Lines

And thus begins the first prototype with Unreal Engine 4 and C++. Phew! I'm getting a little more of the hang of it compared to last time (note: Do not place any header past the generated headers for includes).

The first step was to place nodes on the screen that the character could push around. By switching the linear damping of the nodes while enabling physics, one could resist the character when it is not pressing a pushing button.

Working with the collision delegates is a little trickier with UE4 than with Unity. There's no OnCollisionExit; there's only an OnHit and OnOverlapEnter/Exit. Knowing this, I had to mix the overlap event to enable checking that would allow the character to enable pushing when it hit the node.


I'm also in the midst of working on the ley line as a beam particle, rather than a spline mesh. The spline is lovely, but definitely looks strange when stretching the mesh. We'll see if I can switch the settings of the particle system on the fly.


Wednesday, November 18, 2015

Day 87: A Bunch of Cubes Shaking Around

Today started our official capstone prototype groups! That said, I actually kept working on the Boggle assignment.

Setting up the board with proper allocation of memory was a simple task in comparison to the strange myriad of rules that would come up in getting Boggle to work. I had a recursive function that would search through every letter of a string until it found an answer, something like that of a depth-first search.

However! I had to check for all special cases that would stop the search early. What if the next word had a greater letter (Z > A, in character terms) than where I was checking? What if the word was smaller for the next check? What if, by strange circumstances, I could go to the word that contained the same third letter but not the second letter? What if the word already was found? All these and more required special checks, even moreso tracking what was already traversed.

The solution? Lots of memory allocation. The traversal charts would differ for each and every single branch of traversal, so I had to be careful to only allocate when necessary. For example, when testing every adjacent cube from the target, I could use memcpy and reset the traversal for each and every single recursive traversal, saving up on allocation of memory by reusing it as necessary.

What next? There are some edge cases involving words in the dictionary that contain punctuation, but I'll get em' settled out.

Tuesday, November 17, 2015

Day 86: Boggled

Phew! That marks the end of the mobile prototype. Now onto other things!

That other thing in particular is another programming assignment, the simulation of the game Boggle.
Luckily enough, I'm quite familiar with allocation of memory from the heap and how it'll be required for our assignment.



The dictionary of words in question will be read from a list and put into a linked list structure. Since no words will be added or removed from the list, there thankfully won't be any functionality other than allocation of the list and freeing the memory as necessary. Same for the board as well; the professor has provided us with a series of constants that are represented as dice. Unfortunately, there's no way that one can just iterate through constants excepting the creation of a dice array (more allocation!), so I'll make that my next step. If I can get a board of dice printed today, I can tackle the more pressing search work for tomorrow.

I'm quite excited that I actually know what I'm doing for once with memory allocation!

Monday, November 16, 2015

Day 85: Nearly There

And the demo is upon us! After adding some art assets last night, the team had me work a little less color interpolation and a little more art into the scene. Switching from a black color to an actual ink overlay required a bit of re-work, but by actually attaching the ink overlay to the player at all times and varying its alpha, I got a nice sludge effect going on:



After that, it was the damage states. Instead of a red color interpolation, I have three different images for low, medium, and high damage states. Multiply this by the number of hats (6!) and.. that's a lot to program in. The parameters now take three sprites on the side and required a bit of rework in the store for each option to reflect those changes. Thankfully we have a full and workable game going in time for interim tomorrow.

What next? Yeeeeagh. Unless I know which capstone team I'm on, I'm not completely sure.

Sunday, November 15, 2015

Day 84: Playtesting Extravaganza

Today marks the day our game is nearly and fully complete! With extensive playtesting, we've found numerous bugs (and fixed them), involving invincibility that doesn't go away, players that creep off screen, and disappearing bears. We also added new art assets and the same explosion in the beehive mortar was later used in enemy death effects, along with buttons that showed what shoot mode was selected. In the case of those buttons, the alpha would be a more opaque value if the mode that the player was shooting matched the mode of the button. For non-shooting buttons, the use of an invalid enumeration sure came in handy.




The big thing that my producers worked on (gotta love em') was a shop that one could access and purchase lovely cosmetic changes in the form of hats (bear, cat, Pikachu, etc) with the use of points earned in the game. It was tricky taking those changes and saving them across resets, but they managed it!




What next? If there needs to be any tweaks, I'll be there to fix em'.

Saturday, November 14, 2015

Day 83: Slow Down There

Today was a good wrap-up and addition of further content. On top of various bug fixes, we introduced the next enemy, an odd inclusion of a squid creature:


Unless hit by contact, the squids' ink bullets do not hurt the player. This required a bit of extra working, as the player is set up to move slowly for five seconds while the black ink effect slowly interpolates from the bear's color. Along with that, the water also can wash off the ink effect. This was a bit tricky, as I had to keep track of the coroutine and prematurely start or stop it based on added ink or entering the water. Reinstantiating the coroutine did the trick.

The squid also has a very particular movement. Instead of moving with a specific velocity, the squid has a coroutine that applies a force every couple of seconds that gives it a more realistic burst movement, akin to that of an actual squid.

With this new enemy in and a couple of fixes here and there (the slider, for example, blocking the player from tilting toward the bottom of the screen), the game is pretty tightly made at this point. Just needs a bit of playtesting (which can be difficult with so much going on in the scene!)

Friday, November 13, 2015

Day 82: Not Enough Boss Phases

Today was spent wrapping up the phases on Boss Sauger. I managed to use the coroutines yet again to establish a flashing color for the charge; that way, the boss can telegraph its charge forward. The tricky part was to make the coroutine a data-driven time scale, so it would stop right before the charge phase actually ended:


As for the other two phases, it was fairly straightforward - the last phase required a new bullet type, as the bullets curved toward the left edge of the screen by way of a left-oriented gravitational acceleration. As for the shots that came out of the top and bottom, I devised a series of locations in a set of children for each side of Sauger.



And that's it for the visual progress; I've been attaching plenty of sounds to the game to give it a bit of flavor, so one can imagine these screens with plenty of fancy sound effects attached to it.

Thursday, November 12, 2015

Day 81: Sauger's the Boss

Boss Sauger was the main target for today's work. After mixing an iteration of coroutines through different wave delays and combining all sorts of rotations, lasers, shotgun shots, enemy birthing, and even a charge shot, I'm glad to see the combination of the serializable classes from the wave spawning class and the coroutines to switch between each phase make the system much quicker than I thought it would for Boss Sauger's phases:





The sheer amount of phases planned in this brute is a programming challenge in itself. Onto the next couple of phases tomorrow!

Wednesday, November 11, 2015

Day 80: Arms and Armor

Today was a difficult day in terms of progress; the Remote Desktop client was not functioning at all today, so I had to swing by school in order to get work done.

With that, I managed the rocket arms, which fire outwards based on a radius set by the user's finger and slowly retract back. At first the team was worried about the contact damage being too powerful and able to ward off any and all bullets and enemies, but the arms are actually quite tricky to aim and are more useful to defend against bullets:


I also setup some initial scripting for the boss, the SAUGER. Mr. Sauger currently has three detachable armor pieces that, instead of completely disappearing upon death, drop to the bottom of the screen. The preparation is slight, but should help make something to work with when I start working on boss attack phases.


Tuesday, November 10, 2015

Day 79: Cooling Down for Interim

Today actually turned out to be a successful interim! I managed to get the honeycomb all settled out and worked as a powerup for the bear to absorb. The only tricky part was having to rework the scripts so that the powerup could be reused upon reset. That meant deactivating game objects instead of destroying them.



I also stuck in cooldowns and invincibility frames for Major Ursa; the invincibility was a tricky coroutine since I needed to reset the coroutine every time the Major got hit. This was fixed by constantly assigning a new coroutine so it would take over after the previous one finished up. As for cooldowns, we decided to assign shrinking properties to the buttons to reflect charging attacks.


Next up? Extendable bear claw shields and one heck of a boss fight.

Monday, November 9, 2015

Day 78: Sliding Along

Today was a day to balance a couple of things out before the interim demo; the angler enemy finally got its shots in, a spike tooth that fires in the general direction that the fish is traveling. With a low shoot rate they look rather innocuous, but their size is definitely terrifying.

I also put in separate cooldowns for the missile and mortars (as not to overuse them) and kickback from the missiles and mortar shots. The missiles were a simple kick in velocity, but the mortar required a reworking of the accelerometer motion. Luckily enough, linear interpolation helped smooth out the accelerometer motion more, so a kickback was as simple as offsetting the position by a small amount and letting the accelerometer slowly catch back up.

On top of that, I replaced the boost buttons with a smooth slider. No more clamped horizontal velocity here! The slider allows more area for touch input and allows a smoother change in velocity.



That said, I'll be working on a honeycomb powerup next. Phew! Just trying to get Unity's Pro water to show something other than blue was definitely a challenge. I had to interpolate it again with a separate horizon color, even in a refractive option.

Sunday, November 8, 2015

Day 77: Productivity Comes in Sine Waves

Today was quite the challenge! The main to-do of the day was setting the shoot style of the mortar; I figured that one could aim and fire with rigidbody velocity based on trajectory, but that unfortunately didn't work for a mortar arc. Nor did trying some double equation magic when trying to find a parabola through two points. What my producer did suggest worked well; one could fire the trajectory upward at a high angle off screen, and then shift the mortar right  above the target point to land properly. Combining that with spawning a random group of explosions within the unit circle (thank you, Random.InsideUnitCircle!), and the mortar is complete to go:



As for the angler, the fish was supposed to follow a sine wave movement. Similarly to the bullet movement in the salmon bullets, I could directly control the curve of the fish and rotate it toward the next point in the curve for smooth pointing toward a drunken sine wave. Combine that with variable offset, amplitude, phase, and angular frequency, and...


Next up: Angler bullet spikes!

Saturday, November 7, 2015

Day 76: Productivity Comes In Waves

Today was a bit (of a lot) of a curveball in terms of productivity and progress. The Perforce server was down for the most part of the day, so I was forced to work locally for awhile.

That said, I managed a spawner for waves of enemies. Unity doesn't allow structs to be shown in the editor, so I used a small serializable class to mark waves. Waves contain simple things such as spawn rate, enemies to spawn, and how long till the next wave, so that within that time random enemies of varying difficulty and spawn time. Alas, not the most artistic way, but that's up to the producers once they prototype level design.


Oh yeah, the bear got a funky new design as well. Looks great!

Afterward was the sturgeon, a new sort of enemy. The enemy needed a tricky bit of work in inheriting classes, mainly due to the different sort of behavior. The sturgeon starts out slow but zooms straight ahead to the left side of the screen; that, and leaves an alternating stream of bullets in its wake that also accelerate. Mike and Ike's, they be not.


Next up? Plenty! The mortar strike comes first though, so I created a quick script to get a double-touch target circle to prepare for the mortar strike.

Friday, November 6, 2015

Day 75: Fire the Bear Claw Missiles

Fantastic news-after a struggle to the thirteenth hour last night, I finally got the compressor and decompressor working just fine and submitted the project.

Onto prototyping! I placed a (currently static enemy) in the game for now and went along with the design idea that color can be used to represent enemy health. The enemies and player all interpolate their color to a much darker hue (currently halfway to black with linear interpolation).



As for the main course, the missiles are finally implemented. I had to work a bit on inheritance in classes (bullets and health, mainly) and the missiles are a bit tricky. The way that they work is that upon a long enough swipe by the player, four missiles are fired (one after the other in a specific coroutine) and as long as that swipe is held down, the missiles will follow the finger.

The branching got a bit tricky, as I had to detect not only specific touch phases, but the moment that a missile was firing and when the finger was let go to make the missiles guidance-free. Combine that with acceleration over time and the same reaction to movement in water, and the missiles are fully usable (and quite fun!)



Before bed, I'll tackle slowing the player's vertical movement in water- thanks to the tricky accelerometer position change, it won't be easy.


Thursday, November 5, 2015

Day 74: A Watery Grave for Prototype Progress

Good news regarding the compression assignment! Turns out that out of all of the ridiculous and fancy ways we could have compressed the data, there was a simple solution that the entire Internet seemed to have no knowledge of.

In this model, one can take the range of values that can be represented with each bit size (2 bits = 4 values, 5 bits = 32 values, 16 bits = 65536 values, etc). Take the minimum and maximum of a given set of data and put each of those bit values as markers in that range, floor clamping the float values to those markers. Next up is decompressing the data - it seems I need to attach a small header containing the minimum, maximum, and bit value since the decompressor can't take command line arguments.

The downside is that the prototype class will have to be moved out of the way for a little while; I did manage circles that incorporate Unity's water texture as sections to slow down the bullets and player in the scene though. I did have to make a slight change to the shader (swizzle to the xy plane, instead of the xz plane) but otherwise it looks pretty neat:


I did have to place some restriction on the water though; if it was set to not ignore raycasting, the buttons would have trouble picking up the touch inputs if the water ran behind them.

Back to decompression work!

Wednesday, November 4, 2015

Day 73: Boosting and Blasting the Salmon Armada

Today marked a great start to our RPP thus far! After consultation regarding calibration of accelerometer input, I set both a low pass filter to take out noise values (fancy term, but a linear interpolation with a set factor to reduce large values) and also took the average of the first 10 frames of acceleration for a relative factor that can be used for movement.

We decided to go with only one axis of movement for moving the ship with the accelerometer; the z axis looked as if it would work but oddly enough, the x axis is most responsive when working in Landscape orientation.

Things did get a bit tricky, however; the acceleration took awhile to catch up, especially with quick jerking movements. The application of a force, even a small one, felt like it dragged on. In response, I actually dropped the Rigidbody2D and set the position based on a clamped min/max accelerometer input. The max (0.5, for example) would be the top of the screen, while the min (-0.5) translated to the bottom of the screen. This ensures a relatively quick input without fighting with a rigidbody's movement dynamics.

As for the bullets, I used Spherical interpolation again (Sluuurp) to naturally aim the ship where the finger was being pressed, and I added a bit of the spin to the bullets to give them a little more appeal. I did run into an (obvious) problem when I had forgotten to set the player's child objects' local positions to the origin, which led to quite the mishap involving the ship rotating around an entirely different point in space.

I also put in some buttons for boosting forward and backward. The ship has a natural deceleration that pushes it back to a starting point, but the boost allows a faster jump forward and backward. This input was especially tricky, as I had to specify if the touch was on or off the button before I could shoot; Input.GetTouch(0) was no longer an option. Luckily enough, the touch list is a short one for iteration, so iterating through them and taking the first one that wasn't on a button worked well, allowing multi-touch input.



Next up? Watery areas; the salmon gotta swim through something.