Monday, September 21, 2015

Lag Spikes! How I hate Thee!

So, throughout the last week of testing Eruptoid on my mobile device, I noticed a rather consistent lag spike every second or so.  Being somewhat noobish when it comes to troubleshooting such things, I took a few wild shots in the dark to try and fix it.

Game's lagging?  Must be my visual effects from my particle generators.  Let me turn those down... no change?  Too many polygons?  I only have about 2000 triangles, so that can't be it.  Let me pull up the profiler.  The unity profiler basically provides a frame by frame glimpse at every function call your game is executing, and just how long, in milliseconds, it takes for that function call to execute.  Through some trial and error in figuring out how to get the profiler to talk to my phone while the phone was playing the game, I finally got a picture of what was going on.  Sure enough, every second you could see a spike in the profile graph.  We'll just pause the profile and examine one of the spikes.

Remember that blog post I had a couple of weeks ago about how awesome Unity's new GUI system was?  How I no longer had to manually calculate the size of fonts to get them to be legible on screen?  I take a good chunk of my enthusiasm for that back, because it is the dynamic font scaling that is causing my game to lag.

Here's how it works (according to my understanding).  You have a font which needs to be scaled by whatever factor it needs scaling by to match your target screen resolution.  Unity does this at runtime.  But it doesn't just do a one time calculation for what font size it needs.  Instead, it scales the font one letter/number at a time, and then writes that font at its correct size out to a texure.  Then, when unity needs to display that same character at that same size, it just references the texture instead of calculating the font all over again.  But textures are of fixed sizes, and chances are that the texture will eventually get filled up with all the different font data.  When that happens, unity creates another texture, twice the size of the first, copies everything from the first texture into this new texture, deletes the old texture, and then continues on filling up the new texture with new scaled font characters.  This can repeat numerous times, every time the texture gets full.

I imagine this isn't usually a problem, except that I have a real time countdown clock which is updating every frame, creating a different scaled texture every frame, and thus filling the font texture very quickly.  The function "Font.CacheFontForText" ends up getting called once or twice a second, and every time it does my framerate dips, momentarily, very low.  Why you end up with is a stuttering experience, where things are smooth as butter, and then hitch, and then smooth again.  Its very distracting and very annoying.

Even more annoying was the suggestions for fixing it.  "Don't use dynamic fonts".  Seriously.  The whole point of the new unity GUI was to make a user interface easily scale-able to any resolution without a lot of manual calculations.  On fonts, this is done by making them dynamic.  So the solution to the problem is to not use the new unity gui.


But I had an idea for a work around.  It might not be perfect, and probably won't work on low end devices (sorry guys, optimizations come later).  I still use the dynamic font, but I limit the framerate to 1/2 the refresh rate of the devices screen.  On most mobile's, that means 30 fps.  When I limit it this low, the amount of font changes that need caching drops, and the lag spikes all but disappear.

Its not ideal.  Its a workaround, not a fix.  And until Unity fixes the lag spikes on Android caused by Font.CacheFontForText, its the best I'll be able to do.

Friday, September 18, 2015

Safe Places to Respawn

Though Eruptoid is MonkeyBall-Like, it isn't a full clone.  My game design is being informed by a number of other games such as the NES classic Marble Madness.  What I liked about Marble Madness is how it handled death.

  • In Super Monkey Ball 1, you had a number of lives and every time you fell off the level, you'd lose one.  When you ran out, it was game over.
  • In Super Monkey Ball 2, you had unlimited lives, but every time you fell off the level, you'd start the level over completely.  Timer reset and you would spawn at the start place.
  • In Marble Madness, there were no lives.  The only opponent was the stage and the clock.  So when you fell off the level, you would respawn at the most recent safe place and the clock kept running.  These places were hard coded per level, and you'd spawn at the nearest one.
I'm going the Marble Madness route with a difference.  I'm not hard coding in my respawn locations.  Every certain number of seconds, I check the balls velocity in the Y direction (that's up and down) to determine if the ball is falling or not.  If the ball is not falling, then I set the respawn point to that location.  Under the level is an invisible plane that, when hit by the player, will trigger the game to pick the ball up and drop it back at the respawn point.  Simple yet effective.

Except it doesn't work if you have moving platforms, like my most recent level does.  While the ball is on the moving platform, its Y velocity is zero, so respawn points get saved.  That's fine until the player falls off, the game picks them up and drops them back at the respawn point, only to find that the platform has moved on and the player falls again into the respawn plane, infinitely respawing to a place with no ground below it until the platform comes back.  For this particular level, the platform reciprocates slowly, so this isn't the end of the world, but it severely limits my level design opportunities, so I decided to fix it.

My first thought was to check for ground under the last respawn point, and if there was no ground, then we'd respawn at the level start location.  This solved the problem, but still severely limited my level design.  Its fine for short levels, but if I have a long level where the player falls off a moving platform near the end of the level, they'd go all the way back to the beginning, with not nearly enough time to complete the level again.  This would effectively give the player a game over, and would be frustrating if it happened repeatedly.

So instead, I created a list of respawn points.  As above, every few seconds I check for falling, but instead of replacing a variable with safe locations, I add the safe locations to the end of a C# list.  Then, when the player hits the respawn plane after falling off the level, I iterate through that list backwards until I get to a spawn point that is over ground, and then respawn the player there.

And it only really took adding about 5 lines of code to make it happen.

Other things I did today was set a speed limit for the player.  I'm not sure how well that's going to work out, but I feel like it's necessary.  Of course I gave myself the option of whether to enforce the speed limit or not under certain conditions.

I also fixed another issue with the above moving platform.  As far as I can tell, there's no "friction" in Unity.  Friction is simulated with the drag parameter on a rigidbody.  What this means is that when my ball was on my moving platform, the platform wasn't moving the ball with the platform.  The platform would move right out from under the ball, and the player would fall into the afore mentioned respawn plane, and respawn in the same place they were before, sans platform.  Since my platform moves using an animation, instead of the physics system, I had to calculate its velocity myself.  Once I had the platforms velocity in world space, I could apply that velocity as an added force on the ball when the ball contacted the platform.

Best part is, the way I wrote the script means I can put it on ANY moving object and they will effect not just the player, but any other physics body that I want it to effect.

Overall, it was a good weekend for development.

Wednesday, September 16, 2015


Being an arcade monkey ball style game, of course Eruptoid has Points.  It'll have a high score tracker that I'm hoping to be able to upload to a global database that will track scores of players by region and player supplied string (such as name or initials, or maybe facebook name/google+ profile name.  Haven't decided yet).

Anyway, while I was messing around the the UI, converting it from OnGUI to UnityUI, I noticed my points weren't working.  Turns out it was because I forgot to associate the correct score text fields with the right public variables in the game controller script.
Total Score at the Bottom
I had TotalScore in the Level Score TXT field.  Oops

Well, after I fixed it all up, I noticed that my scoring was rather boring.  The ice cubes I currently have set to be worth 100 points.

And then, upon completion of the level, you are awarded points based on the amount of time remaining.  And I had total score calculated only after the level ended, instead of having it increment every time you got new points.

First thing was first, getting total score to keep up with level score.  I had 3 variables, the HiScore variable which was populated from playerprefs, and represented the highest score attained on that level.  Then I had the levelscore variable, which represented the current score on that level.  And then we had TotalScore, which was an accumulation of the scores of the current play session.

Getting the TotalScore to move with the level score wasn't too difficult.  I just had to track the levelscore variable, watch when it changed, and then change the TotalScore variable by the amount of the level score variable.  The code looks something like this:
So, lastScore is an integer that's set to the current levelscore at startup.  Then, every frame, we compare the value of lastScore to levelscore (which changes every time you get a cube), and then if a change is found, we add the amount of change to the TotalScore.  Finally, we set the lastScore and levelscore variables to be equal so that we can continue to monitor changes in levelscore based on its new value.

As I said, once I got to play testing the new arrangement, I noticed that scoring was rather boring and predictable.  Not very arcade-y.  So I thought "why not award points based on how fast the ball is moving".  This was slightly more complicated than the above.  I basically ended up using the velocity of the ball, multiplied by a fudge factor, in order to get a point value, which is added to the score every frame.

Trouble was, my scores are integers (int), and the velocity of the ball is a floating point number.  Since integer math truncates floats to their nearest int, I was getting no points added until I reached a certain speed threshold, and then I was suddenly getting lots of points.  The solution I took was to decrease my fudge factor by a factor of 10 (from 0.1 to 0.01), and then store a floating point variable that, once it reached a value of 1 or higher, would then be added to the level score, and thus the total score through the code above.  I then packaged the whole process into an UpdateScore function, which you can see here:
SpeedScoreRate is my public float fudge factor.  Making it a public variable means I can change its value from the Unity inspector, instead of having to open up the code and edit it directly.

So, now that its all said and done, I call the UpdateScore function once every frame in the Update block, and the player gets awarded extra points for going fast.  Scoring is now a lot less boring.

Monday, September 14, 2015

OnGUI and the new UnityUI system

I'm going to fast forward a bit on this blog to the present day, or at least work I was doing today.  I mentioned before that I started Eruptoid back in the Unity 4.3 days.  Back in those days there wasn't a simple, easy to use, user friendly GUI design system.  Buttons were all created in code with an OnGUI function call.  Button and text positions were all determined in code, and called out sizes in pixels.  This is fine if you're programming for a single target resolution, but as soon as the idea of changing screen sizes enters the equation, all bets are off.  This was especially frustrating when programming for Android, since android devices at the time had screen sizes that ranged from 800x480 to 1920x1080.  So programming a button in the bottom right of a screen 800x480 would require completely different code than one at 1920x1080.  This forced me (and I imagine, everyone else) to do some major workarounds, or purchase 3rd party gui addons such as UGUI.  Here's an example of creating a button in the top middle of the screen that would reload the title screen:

if (GUI.Button (new Rect(Screen.width/2 - Screen.width/10, Screen.height/10,Screen.width / 5, Screen.height / 10), "Back to Title")){

Yep.  For each and every gui element I wanted to show on the screen, I had to do a relative position and size calculation manually.  It was tedious, slow, and obnoxious.  Plus, creating a style synergy between your GUI and the rest of your games aesthetic was a process I still don't understand.  So you end up with a pretty plain looking button.

Fast forward to today.  In Unity 4.6, they released a new feature called Unity UI.  It created a graphical user interface for the developer to implement a graphical user interface in their games.  Ground breaking stuff, I know.  It has a ton of features that were handled previously in an arcane style system known as a GUI skin.  Now each individual gui element can have its own style, and the workflow matches much of the rest of the Unity object oriented workflow.  Just drag and drop elements as needed into the inspector and the design area.

It uses a game object called a "canvas" to paint and position the UI onto.  The canvas can be relative to camera space, world space, or screen space.  And best of all, the Unity UI almost painlessly scales your UI elements flawlessly to any resolution.

I say almost painlessly, because there are still some things that feel like need a bit more work.  Text fields on buttons, for example, have an option to scale to fit, but don't have a very good way to constrain what area to scale inside of.  Obviously, text fits inside the button, but buttons can have different outlines/styles, and sometimes the text would end up overflowing outside the graphic for the button with certain styles.  I'm still trying to figure out all the nuance, but its a vastly improved system over the old.

Which brings me to today.  Today I spent most of the afternoon creating new borders for my panels and buttons, and the recreating my old OnGUI buttons and text fields into the new UnityUI version.  It makes things look way more polished than with the stock buttons.  To finish the example, here's a similar button now that does the same thing.

That border and background?  I made that using Blender.  It was a pretty simple process that I'll go into in a different blog post.  But here's a teaser screen shot.

I created a 3D lighted version of the border, and then rendered a 2D texture from it.  Blender is awesome.  Seriously.  If you have any interest in doing anything with art, from texturing to 3D modeling, to video editing and compositing, Blender is what you want to learn.

Blender blender blender blender.  Blender blender.  Blender Blender Blend.  Time for bed.

Friday, September 11, 2015

Physics and Animation do not work Thusly!

Hello my friends!  Stay awhile and listen!

Last time I mentioned that I moved away from level design within Unity to attempt other things.  My original vision for how Eruptoid would work was an entirely physics based system.  Similar to Monkey ball, you didn't actually control the ball, you controlled the tilt of the world, and gravity would pull the ball.  I ultimately decided against this because for the controls to make sense, you would have to change the pivot point of the level to be directly under the ball at all times, and I just didn't have the familiarity with the engine to figure out how to make that work.

Anyway, there were a few special objects I wanted to have in the game.  I wanted a conveyor belt that would shoot the ball in the direction the belt was facing.  I wanted a magnetic floor that locked the ball into whatever its movement vector was when it entered the floor.  And I wanted a piston that would be used to launch the ball into the air (since the player can't make the ball jump).

The magnetic floor was probably the easiest.  Its just a plane with a collider.  Upon entering the collider, the balls velocity and angular velocity are read and reduced by 2/3rds.  Then as long as ball remains colliding with the magnetic floor, its velocity and angular velocity are held constant.  Piece of cake.  The nice thing about the mag floor is that it only takes a short script and the collider to work, so any portion of the game level can take on this property without having a prefab for it.

The next easiest, though tedious, object was the conveyor.  This object was built entirely with unity primitives.  One cube for the body, 2 cylinders for the ends of the body, and then a bunch of elongated cubes for the treads.  The scripting was pretty simple.  Upon colliding with the object, the ball gets a velocity in the direction the conveyor is facing added to its current movement vector.  What was tedious was animating it.  The treads, you see, have to move, otherwise it just sits there looking like it wants to be a conveyor belt, but is forever frozen in a lifeless state.  So I had to animate each and every tread "cube" from its current place to its next place.  From there the animation can loop, because the animation is just to be pretty.  It looks pretty flawless when its working.

My final object, and the one that gives this post it's title, is the piston.  The goal of the piston is pretty straightforward.  When the ball rolls onto it, extend the piston, and the ball goes flying upward.  Here's how it looks in its 2 states:
Piston Up

Piston Down

I actually did this object 1st out of the 3.  Its why the other two were relatively painless; I was able to use what I'd learned on this one to make life easier on those two.

Remember how I said that I wanted this to be a physics based game?  Originally that meant that the conveyor would work by physically moving the ball, with collisions and motion of the treads doing the work, instead of writing code to do it.  The piston above originally did nothing but move when the ball made contact.  On collision, the piston portion moved upward relative to its base.  Physics would take care of how much this would effect the ball.

Turns out, physics in unity is not nearly precise enough to make this work consistently.

I come from an engineering background.  The modeling software I use for physics based calculations care more about getting the right answer than it does looking good or being quick.  I foolishly expected unity to be able to do the same thing, only in real time.  It doesn't, and it is expecting way to much to think it would.

The problem is that unity does its physics calculations on a frame by frame basis, but the position of the piston is calculated based on time and motion.  So the frame after the ball actuated the piston, the base of the piston would be inside the ball.  The physics system says that this can't be, and applies a positional change to the ball on the next frame to move it outside the piston.  Except now on this frame, the piston has moved even more, and despite the correction, the piston is still inside the ball.  So we wash, rinse, and repeat until the ball is now moving upward fast enough so that the piston isn't colliding with it when the physics go to do the collision calculation.  In theory, we should be able to adjust how fast the piston extends to get the results we want.

However, as you can guess, this resulted in wildly different ball speeds off the piston depending only on frame rate.  If we had a high frame rate, we'd have more accuracy and the physics would apply less force to the ball per frame.  However, with lower frame rates, the amount of ball the physics system found inside the piston increased, resulting in higher forces added per frame.  Using this method I could get 3 or 4 collisions with the piston on a single actuation, and would have my ball sailing skyward at ridiculous speeds.  And sometimes, the exact same piston would barely lift the ball at all.

In the end, I had to abandon my physics based fantasies, and alter it so that there would be no physics involved at all.  The piston now adds a velocity to the ball relative to the piston's orientation.  All in code.  The piston even extends using code to change its position, rather than an animation.  This is probably the hard way, but it works and I'm done messing with it. Not as cool as if physics were doing all the work for me, but this way I get a consistent result every time, regardless of frame rate.

Wednesday, September 9, 2015

Pretty much my worst nightmare

This is pretty much my worst nightmare, and most likely outcome, of my indie game romp.
I've done literally none of the things he did for marketing, at least not yet, and I know Eruptoid won't be nearly as polished as his was at release. I'll probably end up with a failure.

That said, I'm targeting a completely different set of platforms than he was (though the play store has all the same problems as steam does for indies), and I'm going for a more community style marketing.
Anyway, that's why I need everyone's help to support and spread the word about Eruptoid. I plan to start posting links to the beta version of Eruptoid on this blog soon, so that I can get feedback from you, the fans and players. I want to know what works and doesn't work. What you like and don't like, and most of all what I need to do differently to make Eruptoid the best ball rolling game that I can.

Thanks again for following. Talk to you guys next time.

Materials do not work Thusly!

Last time I mentioned that, even after my week long marathon of unity tutorials, there was still much I did not know and much I did not understand.  I had hoped to be able to make about 14 levels for the game that would become Eruptoid using only the basic primitives that you can create inside the Unity Editor itself, and the stretching things using x/y/z scales.

The idea seemed like it would work at first, until I applied my first material.

The first material is actually a texture I still use in the game today, though I've done some work on it.  The simple grass texture for simulating rolling on a grassy plane.  I also had a simple stone texture for my walls.  Here they are right here:


Aren't they glorious?  So, with my stretched out floor and stretched out cubes, I added these textures as materials.

Well, the sides of the wall looks ok, and the top of the floor looks ok as well, but what the heck is going on with the top of the wall and the side of the floor?

Remember how I said I was using basic primitives (cubes) and scaling them to be long or flat?  Yeah, textures and materials don't understand that.  The engine believes that the object is still a 1 x 1 x 1 cube, even though its now a 10 x 5 x 1 block.  So it takes that beautiful texture you see above, and it stretches it out in the direction the primitive is scaled.  The only reason these textures look halfway passable is because I have the texture itself also tiled in that same direction.  That's all well and good for a single individual block.  But here's the thing: these settings work on a per material basis, not a per object basis.  So while the settings on the side here work for the wall we're currently looking at, they don't work for another set of walls.  And since the material is global, that meant I couldn't use only stretched primitives for my level design.  What could fix this?  Instantiated Materials at the engine level.  Unfortunately, that's never going to happen because instantiated materials that work on a per object basis would make about a million other things more problematic.  Lets just say you'd end up redoing your materials for every object you attached them to.  Better instead to do things the right way.

Being discouraged on the prospect of making levels with the unity editor alone, I actually only ended up making one of them.  After that I moved on to different challenges.  Learning experiences, really.  I set out to make game object that would directly affect the player, with physics and animation.

Stay tuned for the next blog post: Physics and Animation do not work Thusly!

Monday, September 7, 2015

The Story So Far... Part 1

Welcome back everybody!

In this post I'm going to give you guys a little bit more backstory on my journey into game development.  The truth is, I've been working on Eruptoid off and on for about 2 years now.  Let me tell you the story.

Just before July of 2013, I decided that I was going to learn how to program in Unity.  I had looked into Unity a long long time ago, back when a free game engine was a big deal.  I didn't have the patience or the skill set at that time to learn a game engine or make a game.  I wanted something fast and easy, and way back then there was no such thing.  But I digress.  Every summer my wife and I go on vacation with her family to a house in Murrels Inlet, SC.  The property has been in the family since the 60's.  Beautiful view.  So naturally, I decided that I'd take that 1 week to learn Unity.

Unity 4.3 I believe had just come out at that time.  We brought my wife's laptop to the beach and when folks were taking their afternoon naps, I sat down with a pair of headphones and went through the basic unity tutorials.  You can still find them here.  Naturally, I started with the very first tutorial - Roll-a-Ball.  If you have clicked on and reviewed that link, you'll find that it's basically the game I'm making.  Yes, Eruptoid is an extension of the very first beginner tutorial.  But it is also so, so, so, so, so very much more.  I also went on to do the space shooter tutorial, and attempted the stealth tutorial, which I was not successful at completing due to its dependency on several Unity Pro features which were not free at the time.  I also played around a bit with various modifications to those tutorial projects (like a first person camera on the space shooter).  At the time, those were the only 3 tutorials up at that link.  None of the other tutorials available today existed back then.

So, believe it or not, in the span of just a few days, a few hours a day, I had acquired the skills to make very basic games in Unity, and had been pointed in the right direction to learn anything else I needed to know about Unity.  However, this was not the end of it.  I was only scratching the beginning, and now found myself with more questions that needed answers.  Where do meshes come from?  Where do textures come from?

I don't really remember specifically what made me decide to pursue working on the roll-a-ball concept more.  I think it was because I mistakenly believed at the time that a game where the main character was a rolling ball, and all the levels were basic primitives would eliminate a lot of the work that I didn't know how to do yet.  I hoped that I could at least fake the rest.

As I said, I was quite mistaken.

Saturday, September 5, 2015

Welcome to the Dev Blog!

Welcome, ladies and gentlemen, to the Specter Industries Development blog!  I'm very excited to start this blog and to share with you all the exciting, technical, and frustrating moments I encounter
while on my journey from being "just a guy" to an indie game developer.

First, some background information.  My real name is Joel Kolodziej, and as a professional I am a manufacturing engineer for an international company.  I'm the son of a computer and systems engineer, so I've always had an affinity for pc software, hardware, and other nerdy things.  I took a few computer programming classes in high school way back in 1998 (c++, and visual basic), but otherwise, I've had no formal training in programming in any of the languages I find myself coding in today.  I went through a rebellious streak after high school and determined that I wouldn't go into computers professionally like my father did.  So I went to the University of South Carolina for a degree in mechanical engineering. I've always kept my eye and interests in building computers, and have always been curious about how games are made.  One day, about 2 years ago, I decided that, in my spare time, I'd find out.

Specter Industries is the soon to be umbrella corporation that will cover a wide range of activities.  The first activity under the Specter Industries banner is Specter Gaming, my Let's Play channel, that is slowly morphing more into a PC hardware channel.  My most recent series is on building my very own SteamBox, and before that a personal home media server.  Check it out if that's your thing, but this blog almost certainly won't be about PC building, or playing video games on youtube.

This blog is about Making Games.

The game I'm currently building is a Super Monkey Ball style game for mobile platforms I'm tentatively calling Eruptoid.  On a remote tropical island there is a super-volcano that is about to explode destroying the entire island.  What the scientists observing don't understand is that the volcano is actually alive, the living mother of the island.  In order to save herself and her creation, she is sending you, the Eruptoid, to gather mythic super-cooled artifacts to become a super-cooled pyroclastic flow who will ultimately fall back into the volcano's mouth, calming the building inferno threatening to destroy everything.

Gameplay is very monkeyball like.  Levels are relatively simple and geometric, with a starting place, 3 super-cooled cubes to collect each level (optional, but required for the "good" ending), and a bubbling crater you must roll into in order to complete each level.

Eruptoid is built using the Unity 5, with level design done using Blender for meshing and UV unwrapping, and Substance Painter for texturing.  This blog will touch on the hurdles and challenges I've encountered and overcome in all of them.  I won't be doing tutorials unless heavily requested.  I may live stream some of my dev work on the afore mentioned youtube channel.  I'll let you guys know about new posts and if I go live through my google+ page.

Please follow this blog and my google+ page.  Help spread the word about Eruptoid and help me make it yet another indie success story!