Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Tuesday, July 12, 2016

A programming vignette

This doesn't rise to the level of a "war story", but it does illustrate the importance of testing, checking your assumptions, and not taking anything for granted.

The cave environment in Krag Vargenstone is implemented using a tiling system, where individual graphics are duplicated over and over to draw the floor, the walls, and most of the scenery the player will encounter.  (We are using the excellent SpriteTile framework to make our job easier, which I highly recommend if you are planning to make a similar game.)  Most of the level is drawn in a level editor, but the player, the enemies, and the objects are placed as Unity GameObjects.  Sometimes a tile will be used as a placeholder to represent an object's location, but then replaced with a standard floor tile before the level loads.

I was investigating a graphical glitch where blank lines would occasionally appear in the gaps between tiles.  Having made a number of changes, I hit Play to test things, only for Unity to go completely unresponsive.  Not a single control would work, and I had to force-quit Unity from Windows.

A search of my code revealed no endless loops that could have caused the problem.  I narrowed down the changes I had made during that session -- often having to go through the force-quit and restart routine -- and eventually found that changing the size of the tiles in the level editor would reliably reproduce the hang.  This didn't smell right, but I had pursued that particular thread as far as it would go, so I fired off an email to the SpriteTile guy and turned in for the night.

One of the inconvenient realities of programming is that just because you can trace a bug down to a certain part of code does not mean that you've found the source of the problem.

The following day, I was able to look at the problem with fresh eyes.  Not surprisingly, the SpriteTile guy was unable to reproduce the error.  This called for a more intensive diagnostic strategy: if isolating a specific code change -- or point in the code history -- is unfruitful, the next step is to isolate a specific code statement -- or point in the code flow.  In practice, this involves ripping out or disabling all the features, and then adding them back in one by one.  Rather messy.

This strategy traced the cause to an unlikely place: not the tiling or display code, which I had first suspected, but the object placement code.  And that's where I saw it: an endless loop that I had overlooked in my search the previous day.  It belonged to a hackish section of code that was only present to test a particular new feature.  It was something that I had planned to rewrite and replace with a more permanent solution at some point.

The root cause of the problem was that this temporary code was set up to search for a suitable tile on which to place a treasure chest.  One of the suitability requirements was that the tile had to be off-screen.  It just so happened that changing the size of the tiles shrank the test area just enough so that every candidate tile was within the screen viewport.  The tile picker degenerated into running an endless shell game with no possibility of guessing a valid tile.

Another of the inconvenient realities of programming is that sometimes in the course of tracking down and fixing one bug, you discover another bug that has to be found and fixed first.  After all this, I'm back to the point where I still need to fix the blank line glitch.

Wednesday, June 22, 2016

Getting Up and Running with Spriter

Spriter is a 2D character animation tool that was recommended during the last Devgame class.

When I was an apprentice clown, my master taught me that one of the first rules of clowning is "Stay green."  It means always work something new into your performance.  Let it grow and evolve.  Far be it from me to disregard the teachings of my master.  I got Spriter and gave it a whirl.

I've talked my code-monkeys into trying the Unity plugin it because it simplifies my work for me. To give them a leg up, I animated a treasure chest opening, added the plugin, and put the chest in Unity.

This gif is unable to do the animation justice, alas. In Spriter and Unity it's quick and fluid.

For code monkeys who wish to play with it, here's what I learned:


Monday, April 4, 2016

Duplicating and ordering sprites in Unity

The ART OF SWORD lead programmer contributes some Unity code that solves an animation problem to the DEVGAME community and explains its utility.

I was working on Art of Sword with the animation frames the artist had sent when I ran into a familiar problem; Unity's sprite Animations and AnimatorControllers do not allow you to use duplicate sprites, and neither do they allow you to specify the order of sprites displayed in the animations. That is, if you want to use a sprite multiple times in an animation, you have to include it multiple times in your spritesheet. And you essentially have to have each animation lined up in the spritesheet in order - duplicate frames and all - to let Unity's Animation system use them.

This is extremely inconvenient, particularly with the large frames the artist made and the grid-style spritesheet I had assembled them into. Without any duplicate frames the texture is 2048x1024 and contains 42 frames, each of which is 283x170. Obviously, I needed to write my own animator script. I already had a horribly kludged one from when I was first working on Art of Sword that required each individual sprite to be in a different texture AND I had to manually drag and drop each texture into the Unity Inspector. I still don't know exactly what was going through my head when I made that.

So with the new frames from the artist, I set out to write a proper animator that could take a single texture and give me an easy-to-use list of frames without my having to do anything more than copy the texture into the Unity Hierarchy. I came up with this:

Monday, March 21, 2016

The Title

Spriter won't actually make the animation easier in Vargenstone's case, due to the perspective, but it may make the interaction between animation and game easier, especially now that my painting program of choice now has an experimental Spriter Exporter. Tomorrow's my day off, and I intend to spend a couple of hours tinkering with said tools to see if a) they make things more efficient and b) if the efficiency gain is sufficient to justify altering my workflow.

Meanwhile, since our Flash expert explained how he did the title for Elvetika, here's a bit on how I made the title Screen for Vargenstone:

Monday, March 7, 2016

Pushing through to the starting line

Unity is an excellent engine for game development.  It is powerful, flexible, intuitive, well-documented, and widely-used.  Just as importantly, it is free to use and free to publish with if you're an independent or small-time game developer.

It also has a very steep learning curve.  This is not because Unity is particularly difficult to wrap your head around, but rather because of the sheer amount of knowledge that must be absorbed.  I started DevGame with extensive experience in both programming and game modding, so I wasn't entirely a fish out of water, but I was unfamiliar with both the environment and the association of particular tools with particular tasks.

The way I initially got started with game modding is by taking an existing level from a game and seeing how I could modify it.  I highly recommend this approach if you know what you're trying to figure out and you can find something approximately similar.  Start by tweaking minor details: flags, properties, attributes, and even scripting if the level uses it.  From there, identify the various building blocks that the level is composed of, and see if you can use those building blocks to make something new.  Eventually, you'll be writing your own levels from scratch.

Krag Vargenstone didn't lend itself well to this approach, however.  I therefore used a strategy of blasting through the Unity video tutorials and searching for any text-based tutorials I could find online.  This can be just as effective as the above method, but it can take much longer, as video tutorials are not a very time-efficient way to learn new information.  I found myself watching a lot of the videos on 1.25x or 1.5x speed.

As mentioned earlier on this blog, the Roll-A-Ball tutorial is the recommended starting point for new Unity users and is an excellent introduction, though it does not cover the 2D techniques used in Krag Vargenstone.  The UFO Game tutorial is the 2D equivalent, as it's basically building Roll-A-Ball all over again in 2D, but it can still be useful to do them both.  First, because UFO Game describes several topics implicitly while Roll-A-Ball describes them explicitly; second, because UFO Game condenses certain details while Roll-A-Ball enumerates them step-by-step; and third, because going through an unfamiliar exercise twice is better than doing it once.  On the other hand, if you have no intention of using the 3D features and don't want to spend the extra time doing Roll-A-Ball, feel free to skip it and save yourself the detour.

One very important thing for new users to keep in mind is that Unity does not play well with source control out of the box.  This page does a good job of covering the various peculiarities and describes how to fix them for Git.  (Be advised that it was written for Unity 4; the only difference for Unity 5 is that the Version Control -> Mode option should be set to "Visible Meta Files".)  For Subversion, the process is similar but shorter.  This page on the Unity site has a quick nine-step procedure, but you should still read the first article to gain a full appreciation of the problem.  In any case, all of the DevGame projects are using Git.

Since I develop on Windows, I also had to edit the template text file line endings from LF to CRLF as described in the aforementioned Git article.  Since these template files reside under Program Files (x86), it was necessary to launch the text editor - in my case Notepad++ -  as an administrator.  In Notepad++, I then had to run Edit -> EOL Conversion -> Windows Format on every file in the ScriptTemplates folder.

As an aside, I enjoyed figuring out that the name Krag Vargenstone was not chosen arbitrarily.  See if you too can figure out why.