Friday, May 27, 2016

Unity Issues

I've been using Unity for over 6 years.  While it has many aspects that I love, no engine is without issues.  Over the years, I've encountered many of these issues, some of which I've found workarounds for.  Several times now, someone will ask me, "Didn't you encounter this issue?  How did you solve it?"  And I'll usually answer, "Yeah, I've encountered that, but I don't remember the details".  What follows is my list of Unity issues.  I'll try to keep it up to date as best I can for issues I encounter, as well as provide any workarounds I come up with.

Issue #1: No adjacency information in geometry shaders
You cannot construct a mesh filled with adjacency information, which is incredibly useful for many things.
Workaround: None

Issue #2: Frustum culling cannot be disabled
Let's say you have an object that has it's vertices displaced in a shader.  If the object is outside the view frustum and the displacement places the vertices inside the frustum, Unity won't render it.

Another example: If you have created a mesh consisting of screenspace/viewspace vertices, Unity won't render that mesh unless the containing object is inside the view frustum.

It would be great to be able to disabled frustum culling on specific objects, or even disable it entirely, but there is no such ability.

Workaround: Change camera view angle.  Change object bounds. Change object position temporarily.

Issue #3: Generic ReflectionTypeLoadException error
This error is incredibly frustrating, especially when you are dealing with a lot of DLLs.  This error can occur for many reasons, and Unity never gives you any details inside the Editor.

- It could mean that you're missing a DLL.  Dig through the editor log file to try to figure out what.
- It could mean a DLL targets the wrong .NET version (> 3.5).  Which DLL?  Who knows.

Workaround: Scour through the editor log to find any info to help.  Good luck trying to support a giant team of developers.  You basically have to have them email you the log file.

Friday, August 7, 2015

Isometric Platformer

Now that video games have been around for several decades, we've seen many different genres as well as countless hybrids between multiple genres.

Normally, I would say that a good game could be made regardless of the genre, but I am now of the opinion that there is no such thing as a good isometric platformer, nor will there ever be I suppose.

Let me recount a tale for you.  I was searching the Interwebs for a top-down Metroid type game.  I saw some folks mention a game called Scurve: Hive.  It was a game that strangely launched on both the GBA and Nintendo DS.  The game sounded oddly familiar to me, so I opened my box of NDS games and found that I already had a copy that I had apparently found in a bargain bin for $10.

Scurge: Hive

I popped it into my Majora's Mask New 3DS (gotta flash my nerd-cred!) and gave it a go.  While I generally like the coloring, enemy design, weapons, and environment, there was one thing that really bothered me that made the game near-unplayable for me.

Nerd-Cred!
Platforming.  In an isometric game.

What does a platforming game consist of?  Jumping from platform to platform using precise timing and coordination.

Using precise timing and coordination!

What does the isometric view entail?  A camera projection that makes everything the same size regardless of distance or height.

Regardless of distance or height!

What happens when you mix precision jumping with a camera projection that prevents you from judging platform position?  You get a terrible game, that's what!

Flash forward a couple months to the current day and I recently got Rare Replay on my Xbox One. Included in the collection are several old isometric platformers from Rare.  While I will admit that the use of lighting and shadows in Snake Rattle 'n Roll made it not as frustratingly difficult, others, such as Knight Lore are abysmal.

Rare Replay

Snake Rattle 'n Roll
Knight Lore used a monochromatic artstyle that made the isometric plaforming incredibly difficult.  It took great effort for me to be able to figure out which platforms were where.

Knight Lore
While I can't seem to find any screenshots from Scurge: Hive of the specific spot that was annoying enough to make me want to throw my 3DS on the floor, here are a couple that kinda give you an idea:



In summary: Never make an isometric platformer!


Friday, May 16, 2014

Dart vs TypeScript

Coming primarily from a C# background (as well as C, C++, & Java), working with JavaScript was quite a paradigm shift.  As a result, I was very slow developing in JavaScript because I had to learn all of the ins and outs of the language while I was trying to implement functionality.

As you may know from reading previous posts, this led me to switch to Dart.  Having a syntax very similar to C#/Java, I was more than happy to dive in.  I quickly developed a simplistic game engine/framework and even developed four games in one month (one game a week).

Having changed jobs (again!), I took time off of my hobby development to focus on getting up to speed at my new job.  I'm now at the point of where I'm investigating the feasibility of a new idea.  I want to turn my framework into a library that can be used by any web developer to make games.  I was envisioning compiling the Dart code into JavaScript, allowing other developers to interface with it and even create new scripts on the fly.

My entire Dart world shattered apart when I discovered that this would be incredibly difficult, if not impossible to do.  You see, even though Dart compiles to JavaScript, it was not meant to be consumed by any one else in that form.  The focus is squarely on the Dart VM which isn't even implemented in any real browser.  In order to interface with JavaScript, you have to use the interop layer.  Yikes!

I sat for several days trying to plan out the best way of exposing practically everything from my Dart code to JavaScript as well as allow random JavaScript code to be serialized along with Dart so that everything was saved together as one game.  I eventually decided to look elsewhere for other options.

The major alternatives to Dart are:
JavaScript - I've obviously already tried that and need to get away from it until JavaScript 2.0.
CoffeeScript - This has one of the worst syntaxes I've ever seen.  In my opinion, it makes JavaScript worse.
TypeScript - Everything I've seen thus far for this is amazing, but I'm hesitant after Dart.

Dart and TypeScript both have:
  • Types
  • Generics
  • Classes
  • Properties (getters and setters)
  • Static Fields & Methods
  • Aliasing
  • Optional & Default Parameters
  • Lambda Expressions (Anonymous Methods)
What TypeScript has that Dart doesn't:
  • Enumerations
  • Interfaces (explicit)
    • Dart only has implicit interfaces via classes
  • Modules
    • Dart uses libraries instead
  • public/private keywords
    • Dart uses underscores to mark fields/methods as private.  BLEH!!!
  • Rest Parameters
  • Overloaded Methods
    • I can't believe Dart doesn't support this.  This is huge to me.
  • Generic Constraints
  • Superset of JavaScript
    • All existing JavaScript is valid TypeScript
    •  This allows direct interfacing with JavaScript code
    • This also means that its implementations of classes, modules, etc are JavaScript 2.0 compatible!
What Dart has that TypeScript doesn't:
  • Pub
    • A great way to get other people's packages automatically
  • Basic Framework Classes
    • Lists, WebAudio, WebGL, TypedData, etc
    • TypeScript has lib.d.ts, but it doesn't provide as much
  • Abstract Classes
  • Operator Overloading
    • Very handy feature that I hope TypeScript gets at some point
  • Indexers (overloading [])
    • Very useful for creating custom collections or math types (Vector, Matrix, etc)
One of the biggest advantages of TypeScript over Dart is this:

Cloud 9 supports TypeScript

I haven't written a single line of TypeScript (yet!), so I can't truly comment how if it is better than Dart, but on paper it looks fantastic.  I'll try it out soon!

Sunday, March 30, 2014

Game A Week - #4 - Long Jump

Play the game here!

Monday
I wanted to have an even more physics heavy game, one that used joints and compound shapes, so I decided to make a vehicle building long jump game.  I created the base project along with a very long ground object and a wall to prevent travel to the left.  I added in a simple box that would move based upon forces given to it via keypresses.  I created a FollowObject component that lets the Camera follow the box around.  I built a simple ramp, added in distance indicators (current and max) and had the input disable after the box went off the ramp.  I was surprised by how fun it already was to play; just flinging a box off of a ramp.

Tuesday
I started working on adding joints, but it immediately became clear that I needed to separate out my RigidBody components from their Collider components, which I did.  I then realized that I needed to implement some sort of parent/child hierarchy in order to get compound shapes working correctly.  This was quite a bit of refactoring work.

I added in a quick and simple set of marker bars that indicate every 10 meters in order to help give a sense of motion and distance.


Wednesday
I got really sick and didn't work on anything.

Thursday
I was still recovering from my sickness.

Friday
I did no work on the game.

Saturday
I did no work on the game.

Sunday
I added in a RevoluteJoint component and hooked up two CircleColliders as simple wheels.  I pushed the left wall out more to give the player more room to gain speed before hitting the ramp.

Play the game here!

Final Thoughts
Due to my sickness and other things in life, I lost several days to be able to work on the game.  I had planned for a lot more features since I had the entire week off of work, but alas it was not to be.

My major planned feature was to allow the player to construct their own vehicle with various parts available such as wheels, rockets, etc.

I was impressed by how fun the game was even in the early stages.  I believe this is a really fun concept that needs to be expanded upon in the future.

Considering I'm starting a new job this next week, I may skip on doing a Game A Week challenge.

Sunday, March 23, 2014

Game A Week - #3 - Orbital Golf

Here is how the past week went: (Play the game here!)

Monday
I really wanted to integrate a physics engine in order to get all of the benefits one provides.  So, I decided to implement Orbital Golf, a physics heavy golfing game that I had developed a rough prototype of several years ago in Unity.  You can play the old Unity prototype here. I pulled the dart-box2d package into my Dart project, which is a Dart port of Box2D. I then implemented a basic Collider component as well as a rough BoxCollider component.  I managed to get a small box to fall and land on a large static box acting as the ground.

Tuesday
I fixed a major scaling issue with rendering.  I added in a second moving box that bounces off the first box.  I implemented a CircleCollider component and the ability to programmatically create a circle mesh.  I created a simple wrapper around mouse input to allow that as an input option. I then spent hours trying unsuccessfully to detect then the mouse clicks an object.

Wednesday
After continuing to struggle with detecting clicked objects by trying to "unproject" the mouse position as a raycast into the scene, I decided to try going the other direction.  (I was able to successfully unproject the mouse position and create a ray vector pointing into the scene, but detecting the ray hitting objects posed the problem.)  I implemented a temporary Clicker component that projects its own world position into screen space whenever the mouse button is pressed and then sees if it matches (within a range)  the mouse position.  It worked great, and since I only needed to be able to detect clicks on the ball, this works fine for the game.

Thursday
I implemented a Planet component that calculates gravity based upon distance to the planet.  I also implemented a Ball component that uses gravity of surrounding planets to apply forces and move the ball around.

Friday
I made it so that if ball is clicked on, dragged, and then released, it applies a force relative to how much the mouse was dragged in order to fling the ball around.  I added in a simple counter to count how many hits were made. I ran into odd issues with trying to make a "factory" method to generate planets.  It seems like a bug in Dart, but I need to investigate it further before I report it.

I set up a goal circle that is a static Box2D sensor.  I implemented a callback system for when two Box2D objects collider and made it so when the ball and goal touch, it displays a winning message. I also implemented a line renderer to show the force vector to be applied to the ball.  It's very crude, but does the job.

Saturday
I set up a simple level system that can switch between various levels. I also tried working on displaying a trajectory prediction line, but it turns out to be fairly complicated.  I had tried doing a similar thing back with the old Unity version.  You can see there is a prediction line in the Unity version, but it doesn't take into account any collisions or friction with surfaces.  I was hoping to have a superior prediction line with this prototype, but that doesn't appear to be possible for a one week challenge.

Sunday
I decided to change things up a bit and instead of working on gameplay I would try and make it look a little better.  I implemented a Texture2D object and the ability to set textures on a Material.  I wrote a simple new shader that took a single texture.  I found a checkerboard pattern image online and I now have a goal with a checkerboard texture applied to it in order to help it stand out more.

I changed focus once more and I added the ability to make the game go fullscreen using the Fullscreen API. I also added in a wrapper around touch events to be able to get touches on a touchscreen.  These two features together make it work much better on a mobile device, and I tested the game on my Android phone (Galaxy Note 3).

I also made a quick update so that the force line moves along with the ball instead of sitting out in space where you first clicked the ball.

Play the game here!

Final Thoughts
I was quite happy with what I accomplished this week.  I actually had almost the entire week off of work which helped me be more productive.

As usual, there were several features I wish I could have added:

Better scoring - scoring based upon the flight time of the ball divided by the number of hits
Better camera - a camera that uses mouse wheel and pinching to zoom
Prediction line - as you probably read above, I really wanted a line to predict ball trajectory
Non-spherical planets - ovals, simple terrain
Orbiting planets - planets orbiting around other planets as moons
More debris and obstacles - things cluttering the way

To be honest, I'm glad the week is over.  It's good to be able to switch over to a different game every week.  I really like the concept of Orbital Golf  and I believe it has great potential, but there are other ideas I'd love to try out.  I have this next week off of work as well, so hopefully I can whip up something awesome.

Sunday, March 16, 2014

Game A Week - #2 - Asteroid Spacewar?

Here is how the past week went: (Play the game here!)

Monday
I decided that since the first Game A Week (GAW) game (Pong) only had 2D shapes with translation, then the next game should have 2D shapes with translation and rotation.  In keeping with the theme of remaking old games, I chose to create a clone of Spacewar next.  I was only able to set up the initial project in Dart, nothing else.

Tuesday
I created a triangle shaped GameObject and wrote up a simple Ship component that I assigned it.  This component uses keyboard input to rotate the triangle left and right and move the triangle forward and backward.  I also changed the background color to black (whoa!).

Wednesday
I changed the ship to move via forces applied to it instead of just changing its position.

Thursday
No progress.  I went to a concert dinner and drinks. (We discovered the concert was cancelled after arriving at the venue.)

Friday
No progress. I went to a birthday party.

Saturday
I set it up so that the ship warps to the opposite screen edge when it reaches one screen edge.  I added in the ability to fire bullets that also warp around. I made a tough decision that since I had not worked on the game very much during the week, that I had to trim down features.  I knew I wouldn't have time to put in multiplayer, random ship warping, etc. I decided to make it a more simplistic game similar to Asteroids. I implemented an AsteroidManager component that randomly spawns asteroids that fly around the screen.

Sunday
I added in collision detection between the ship, bullets, and asteroids.  I set up scoring as well as game over conditions.  I added in the ability to render the ship with color (everything previously could only render in white).  I tweaked the random creation of asteroids and limited the maximum number of both bullets and asteroids in order to avoid the game being a big mess of objects.

Play the game here!

Final Thoughts
I had even less time this week to work on the game than last week.  I believe I spent about a total of 12 hours on it this week.

Here were the features I had hoped to get in that I had to scrap:
Sounds - Again, sounds for everything didn't make it in.
Planets - Planets with gravity that affected the acceleration/velocity of all objects
Multiplayer - Two ships battling against one another.

I'm really hoping that I'll have more time in the next two weeks for future GAWs due to certain circumstances in my life that I'll explain later.

NOTE: I realized after publishing the game to my server that my changes to some shared shaders broke last week's Pong game.  Nothing is rendering anymore.  I'll need to figure out what's going on with that and fix it (no other game code will be changed except that). NOW FIXED!

Sunday, March 9, 2014

Game A Week - #1 - Pong

I've read about many different indie developers making a game a week, but it was this recent article on Gamasutra that really sold me on the idea.  I decided that I would try to do it myself, using it to strengthen my game design skills as well beefing up my Dart knowledge.

I was tempted to tackle this challenge using Unity, as I have vast knowledge of the ins and outs of that engine, but in the end I decided it would be more educational for me to use something I was not very familiar with.  I figured it would force me to think outside the box to come up with solutions.

Here is how the past week went: (Play the game here!)

Monday
The first issue was figuring out what game to make.  I assumed that making a clone would be best to start off with, and a very simple one at that.  Pong seemed appropriate for many different reasons.

Once I had chosen the game,  I had to set up the basic Dart project structure.  This was rather difficult just because of the Dart Editor.  (I had decided to use the Dart Editor instead of Cloud 9 while I learn the ins and outs of Dart.)  Dart would constantly take up massive amounts of RAM (2.3 GB) and CPU (87%), which would cause it to come to a crawl and even crash repeatedly on my PC.

I also had quite a bit of difficulty trying to load assets in Dart.  I'm developing the base engine as a Dart lib, so I first tried putting the shader files directly in the lib folder.  I couldn't figure out any way to actually access them at run-time, so I tried putting them in the asset folder, since that is what is described here.  That also didn't work since it requires pub build which apparently doesn't work on Dart libs.  So, I ended up simply putting them in the example folder.  It's not ideal, but it works for the present.

I eventually figured out how to make the Dart Editor stable.  I deleted all of the metadata under C:/Users/[user]/DartEditor and then deleted all of the packages folders in my project, since they are generated by Dart anyway.  I rebooted the Dart Editor and pulled in my project.  It ran smoothly after that.

I didn't get as far as I had planned since I was battling against the Dart Editor most of  the time.  I did end up with a square and triangle rendering via WebGL in Dart using my own custom shader loading.

Tuesday
The next major part to implement was an actual game loop instead of having one single Render call.  I set up requestAnimationFrame to achieve this, which was relatively straight-forward.  It currently calls both Update and Render at the same framerate.  I may change this in the future, since most engines/APIs have Update called much more often than Render, but it works fine for me now.

I then created a GameObject base class as well as Renderer and Transform components that can be attached to GameObjects.  I updated the square and triangle test from Monday to use these new structures which greatly simplified the set up code.

A small tweak was made so that the WebGL rendering context (Canvas) will be automatically resized along with the browser window.

It doesn't really look like a productive day, but I actually accomplished a lot by putting in those base components.  It should make all future work much easier.

Wednesday
I didn't get much time to work on the game due to other things in life, but I did get some important pieces in. I created a Camera component to help alleviate the hassle of dealing with projection and view matrices all the time.  I created a Scene manager to manage GameObjects and to automatically call their Update and Render methods.  I also created a very simple Color class that acts as a simple wrapper around Vector4 to provide static properties to commonly used colors.  The square and triangle test is now only a few lines of code to set up.

Thursday
It was another short day for me, yet very productive.  I implemented Keyboard class to handle all keyboard input.  I created a Paddle component that uses the keyboard to move up and down. I created a Ball component that moves across the screen and detects collision with the screen edges and the paddles.

Friday
I didn't even touch Pong on Friday because I went out for pizza and beer with my girlfriend. I don't want to sacrifice my social life for the sake of a game a week.

Saturday
I spent most of the day going for a long bike-ride.  I tried fixing some issues, which was mainly fruitless.  I tried forcing the canvas to have focus as soon as the webpage loads so that it immediately can accept keyboard input.  It works most of the time, however it doesn't work when the browser is first loaded, which is quite common when debugging using the Dart Editor.  I tried fixing some wonky collision behavior between the ball and paddle.  I made it a little better, but it's still nowhere near perfect.  I also added in simple scaling to the Transform component to allow easily re-scaling the paddles.  It works well right now for axis-aligned 2D shapes, but it may have to be re-visited in the future to be more robust.  Also, scaling currently only scales the rendering mesh, not the collider mesh.

Sunday
I spent the afternoon at a friend's house playing various board games.  I set up a scoring system with normal HTML used for displaying the score.  I implemented a crude AI system so that you are playing against the computer.  This brought to light a big bug with the collision system.  I had to put in a hack to alleviate that.  I also added in a random element to the ball velocity after a player scores.  I then adjusted collision between the ball & paddles with the screen edges.  Finally, I deployed the game to my server.

Play the game here!

Final Thoughts
I was surprised by how little time I actually had put into the game over the past week.  It is an incredibly difficult task balancing my time between my full time job, my bike-riding, my girlfriend, my friends, etc.  I had hoped to accomplish much, much more.

I have an entire list of features I had hoped to put in, including:
Networking - Allow multiple players across various web browsers
Different Paddle Shapes - Not just | shapes, but < and > and curved surfaces
Increasing Speeds - Make the ball go faster as the score increased
Varying Angles - Make the angles of the ball not always 90 degree bounces
Sound - Simplistic sounds to indicate when the ball hits a paddle
Circle Ball - Use an actual circle mesh for the ball instead of a square
Scale Properly - Currently the game doesn't scale the collision zones with the visible window

In the end, I did get a working (albeit simplistic) version of Pong up and running via Dart and WebGL.  I suppose that's as good of a first Game A Week as I can get.  I'm already looking forward to the next game! (Whatever it may be.)