Author Archives: sandalfootgames

Dungeon Ho!: Unity – Dev Blog #6

Hello again, Blogstalkers!  Sorry for the lengthy delay between updates, but between the holidays and the numerous false starts on this particular topic, it took longer than I expected to actually settle on a simple, Unity-esque solution to the topic.  And once I found one, I just kept focusing on the fun stuff; coding!

Anyhoo, as promised, today we’re going to look at defining Mob characteristics in a data file.  Data-driven development, and all of the perks therein, should be obvious to anyone with half a clue – but if not, the primary reason I did it was to cut down on a lot of duplicate code in the various monster types.  For example, let’s say you have a Kobold.  When you spawn one, the object’s name needs to be set to “Kobold”, his height and weight need to be set, and his starting gear needs to be generated.  Now, you can do this via inheritance in the monster’s constructor – and the original Java Android version of Dungeon Ho! did this – but it involved a lot of copying and pasting, and flipping between files to make sure I didn’t leave anything out.  Wasn’t a big deal when I only had a few monster types.  Much more of a deal when I had twenty.  Much better to just pass a data file into the base Monster constructor and have it pull all the data from there.  And, what better format to use for this than JSON?  It’s human-readable, extensible, and most importantly, natively supported by Unity!  Can’t beat that with a stick.

So first, let’s take a quick look at the current monsters.json file.  This is, as you may have guessed, the JSON file that stores each monster’s default data.  The beauty of it is that we can simply add new key-value pairs as we think of them, and it won’t break the existing loader; everything the C# code doesn’t recognize is simply ignored.

dhu 19

As you can see, each monster definition is labeled with an object name (in this example, “human”) and assigned a bunch of data.  Since Unity handles text files directly, I simply dropped the .json file into a Data directory under my Assets folder in Unity, then dragged the file onto my Game object to create a reference to it.  If you recall from our previous entry, the Game object is, well, a GameObject that manages the state of the entire game via the attached Game.cs script.  So, by adding this line to the variable definition in that file…

public TextAsset monsterDefinitionsJSON;

We now have the ability to drag and drop a text file on there.  So, we do.

dhu 20

Once that reference has been assigned, we need to parse the JSON.  Merely assigning the asset causes Unity to automagically load the text file as a TextAsset, and we can then grab the text therein as a string.  This’ll be necessary to let the JsonUtility class do its thing, since it needs a JSON-formatted string to pull the data from.

So, let’s talk about the object we’re using to store all of these monster definitions.  It’s called, oddly enough, MonsterDefinitions.

dhu 21

Classes that can be parsed from JSON need to be tagged with [System.Serializable] – and note that we have a nested inner class to handle both the monster definition itself and the male/female pairings.  The actual definition itself is mapped to the “human” local variable, which must match the monster’s object name from the JSON data.

Why didn’t we simply make an array of MonsterDefinitions, and then define it as an array of objects within the JSON?  Because then the order of the definitions would matter, and I wanted to move away from hard-coding stuff like that.  This way if I later decide to copy-paste a bunch of definitions and make a mistake somehow, I only screw up the ones I copy-pasted rather than all of them.  Plus, and although this is a one-man project, let’s say a second person was tasked with inputting that data.  You told them/wrote it down somewhere that the monster order matters, and it gets misplaced.  Now you have an out of order data file.  Yippee.  Another drawback is having to possibly keep track of the number of monsters for the array allocation.  And the fact that I’ve read rumblings that Unity’s JSON deserialization for arrays can be iffy and require a wrapper class anyway.  Not worth the hassle.

Anyway.  Moving on.

In the Game class, we take the passed-in reference to our JSON datafile and call the static method of the MonsterDefinitions class initDefinitionsFromJSON to parse the data and give us a MonsterDefinitions object, like so;

monsterDefinitions = MonsterDefinitions.initDefinitionsFromJSON(monsterDefinitionsJSON.text);

 

We can then use this object to retrieve the data from the ObjectSpawner, as the monster definitions variable is both public and static, alleviating the need for any obnoxious getters or reference passing.  It’s totally okay since we’re only ever going to have one of these objects.  And, although I don’t know if it’ll help, I null out the TextAsset reference afterward so the garbage collector can reclaim it, since we don’t need it anymore after that.

So how does the object spawner, use this data?  Glad you asked.

dhu 24

The ObjectSpawner class uses similar logic for monsters that it did for the Player.  Note that the basic GameObject creation has been abstracted into a separate generateEntity method.  We do some basic housekeeping by setting a (temporary!) sprite to the SpriteRenderer so we can see it in game, as well as set the monster’s solid variable (we’ll cover that another time when we deep-dive further into the Monster and Item classes), but the most interesting thing is the assignMonsterComponent method.  It takes a MonsterType enum, which is defined as an integer, and based on that, passes a particular MonsterDefinition from the Game’s MonsterDefinitions class into the Monster’s init method.  That method is as follows;

dhu 25

Note the one-to-one mapping of variable names in the MonsterDefinition to the JSON data.  Easy!  We can grab the data fields as variable names and assign them to our own variables.  Also note the slick data processing that checks whether or not we should format the Monster’s name with “A” or “An” depending on whether or not it starts with a vowel.  Does this cause issues when localizing to other languages, you ask?  Damn right it does!  But I made the decision early on that such a text-heavy game would be basically impossible for me to localize anyway without a lot of work for very little gain.  So if you were hoping to play Dungeon Ho!: Unity in German or Swahili, you’re out of luck.

Anyway, that’s all for today.  Tune in next time when we lay the groundwork for items, including the Item class itself, extending the ObjectSpawner to handle them, and maybe even the Inventory system complete with picking stuff up that’s just lying around the dungeon.  (Told you I’ve been busy!)

– Steve

Categories: Development, Dungeon Ho!, Unity | Leave a comment

Dungeon Ho!: Unity – Dev Blog #5

Welcome back, Dungeon Masters!  Today, we’re finally going to look at the Dungeon Master object (…natch) and its role in processing the game’s command queue.

As I explained last time, the DungeonMaster object maintains a queue of all the commands collected from the player.

DHU 15

Pretty straightforward.  The DungeonMaster maintains a List object of MobCommands, which we saw the structure of last time.  There’s an addCommand() method, which adds a new command to the end of the queue.  We keep a constant to make sure the queue doesn’t get too large (which normally won’t happen, but if the game’s running slow and the user starts monkeybashing the UI, commands might get backed up in the queue).

Next up is the processCommandQueue() method.  This method simply checks to see if the queue is empty.  If it isn’t, it calls the dungeon’s advanceTime() method – which, as the name suggests, advances the time passed in the dungeon by one turn – and passes it the first command in the queue as the player’s input for that turn.  It then removes the command.  Simple enough, right?

Where the actual magic happens is in the Dungeon class.  It didn’t do much the last time we looked at it, so let’s revisit it now.

DHU 16

We’ve moved the map generation and player-spawning code out of the Start() method and into its own init() method, which will become relevant next time when we start doing some more sophisticated setup code in the Game object.  Stay tuned for that!  Moving on, you’ll notice we now have a DungeonMaster object and a turnQueue, which is a list of all of the commands collected from both the player and the monsters’ AI for the turn.

Since the Dungeon is a Unity Monobehavior, it has an Update() method which gets called repeatedly as the game runs.  This is our update loop.  Every pass through the loop, the dungeon tells the dungeonMaster to collect input from the player (…which we’ll see shortly).  Any input collected that frame is converted into a MobCommand and added to the DungeonMaster’s commandQueue.  And, after the input has been collected, that command queue is processed, as we just saw.

Now, you may be wondering why, if we’re only collecting input once a frame, why we don’t just pass that input directly to the dungeon.  Why the extra queue?  Well, the answer is because eventually we want to be able to collect input from the game’s UI, as the result of button presses and event handlers.  Those happen outside of this loop, so we need a way to collect all of the command input in one place and handle it in the order it was generated.

So, how do we do that?  Here’s the DungeonMaster’s collectInput() method, which is textbook Unity keyEvents.

DHU 17

See how we’re instantiating new commands of the types that we defined last time?  The MoveCommands take a reference to the player as their source (I added a getter to the dungeon to access its player object), as well as a constant denoting the direction, and the PassCommand merely takes the player (also as the source; remember, the source object is the one that initiated the command) and nothing else.

Okay, once we have commands to process, what do we do with them?  I’m glad you asked.  Remember, the dungeon calls advanceTime() to advance the game one turn.  Here’s that method.

DHU 18

Not exactly rocket science, is it?  Every turn, the dungeon clears its turnQueue, then adds the passed-in player’s command object to it.  (Eventually, it will loop through all the other Mobs and ask them for their commands, but we haven’t gotten that far yet!)  We then sort the queue, using the CompareTo() method we defined to sort on the turnOrder of the Command.  We pass in a lambda function calling that method with two MobCommands (denoted by the parameters mc1 and mc2) as our sort comparator (check the C# documentation for more on that – it’s kinda tricky).

Once the queue has been sorted, all of the commands will now be in turn order – so, we merely loop through each command in the queue and process it by calling the process() method we looked at in the previous blog.  Finally, we loop through all of the entities in the map (mobs, the player, items, and so forth) and call their postCommandUpdate() methods.  This method is currently empty, but will eventually do things that update the Entity’s state, like check if its health dropped below zero as the result of any attacks carried out in the queue so that it can mark it as dead.

…and that’s it!  This simple queue processor runs the entire game, and is stupidly flexible.  We simply define new commands for any new action we want a mob to be able to take, and as long as they inherit from MobCommand and define their own process() method, the turnQueue will handle them.

Tune in next time when I’ll show you how I finally decided to represent Entity spawning, including the use of JSON-based default data to avoid hard-coding values.  Things are starting to get interesting!

-Steve

Categories: Development, Dungeon Ho!, Unity | Leave a comment

Dungeon Ho!: Unity – Dev Blog #4

Welcome back, Roguelikers!  Today we’re going to be looking at the basic structure of the Command classes… which, collectively, are the heart of the entire game.

As many Roguelikes before it, Dungeon Ho! is turn-based.  Whenever the player inputs a command, the game puts that command into a queue, then queries all of the other Mobs to see what they want to do.  Each Mob also selects a Command (…even if it’s just doing nothing), then adds those to the queue as well.  The game then sorts all of the commands into an “initiative order” to represent the fact that some Commands should take priority (IE, “go faster”) than others.  For example, moving is faster than casting a spell (usually!), so if a Mob submitted a MoveCommand and another Mob submitted a CastSpellCommand, the first Mob would act before the second.  Since Mobs attack one another by moving into another Mob’s space, this means the first Mob may very well kill the second Mob before it gets to act!  Once all of the commands have been sorted, the game then runs down the list and processes each command in order, carrying out whatever tasks need to be done in order to fully execute the command.  This may involve updating the mob’s position in the world, running an attack routine, picking up an item and adding it to the mob’s inventory, or a host of other things.

For now, though, let’s look at the basic structure of a command.  It’s represented by the MobCommand class, and each different type of command will get its own class that inherits from MobCommand.  For example, moving is a MoveCommand.  We’ll get to that in a moment.

DHU 10

Don’t worry about the ToString() method being cut off on the bottom.  You’re not missing much.  All it does is replace the standard ToString() method with one that outputs a formatted string including the Command’s turnOrder, name, and data.

Anyway, let’s look at this class.  Note the two member variables of type Entity; we defined our Entity class in a previous blog entry, and it’s the building block of all… well, entities in our game.  A MobCommand needs to know its source (the entity that initiated the command) and its target (the entity the command is invoked upon).  For example, if one Mob was attacking another, we’d create a MobCommand with a source equal to the attacker, and the target equal to the victim.

We provide two constructors for our command class; note that one takes a parameter of type object, which gets assigned to a member variable called data.  Don’t confuse an object (little ‘o’) with an Object (big ‘O’)!  The lower-case object type is the base object class that everything in the C# language inherits from… that includes basic datatypes like integers!  The Object class is the base Unity object class, and the two of them are not equivalent.  We want our data variable to theoretically hold anything we can stuff in there, so it needs to be the most base of objects the language allows.  We could easily just have a single constructor that can take null for the data value, but this is more intuitive when you see it in action, IMO.  The variables are assigned in the init() method, to keep from duplicating code across constructors.

The process() method is the heart of a MobCommand.  This is the method that the game will call in order for the command to do whatever it needs to do.  We give it a reference to our Dungeon, because although most commands will simply act on the source and target, some of them will most likely need to gather additional data from the dungeon… like when a Mob tries to move.  (We’ll look at the MoveCommand shortly, so hang on!).

The compareTo() method allows us to compare two MobCommands and evaluate whether one is “higher” than another based on their turnOrder.  This method, as you will see later on, gets called in the Dungeon’s update loop when there is a turn to process.  It simply calls the built-in C# method CompareTo(), which is implemented in all basic datatypes… including ints, which is what our turnOrder is defined as.

The getTurnOrder() method should require no explanation.  Since turnOrder is private, it’s just a getter that allows other objects to access the variable.  We might not even need it, as turnOrder is basically calculated once and then forgotten about.

…and it’s calculated in determineTurnOrder(), which is a virtual method that can either default to the base initiative as calculated by the source entity (currently, it’s merely the maximum value an ability score can be, which is 100.  We’ll talk more about ability scores and how they determine initiative in a future blog.), or get overridden by a child class that provides its own way to calculate the turnOrder.  For example, we may want MoveCommands to use the mob’s current Agility score plus some kind of action modifier.

***

So, how do we make new commands?  Glad you asked.  Let’s do it.  Here’s the PassCommand, which is the command a mob would invoke when they didn’t want to do anything at all.

DHU 11

Fascinating, right?  The most interesting thing about the PassCommand class is that it inherits from MobCommand and invokes that base class’ constructor, passing it the values it is given by the code (defaulting the data parameter to null, as the PassCommand never provides data.  Hm, could probably invoke the other constructor instead, then… better fix that!).  We have to do this because otherwise Unity would complain that there is no “default” constructor, which is a constructor that takes no parameters… and it’s right!

We also override the process() method, because eventually the PassComand is going to put a message into the game’s log when a Mob passes its turn.  For now, though, we can just fart out a message to the log so that we know our queue has processed the command.

Now, let’s look at one with more beef to it; the MoveCommand.

DHU 12

The MoveCommand currently defines four constants to indicate the compass directions.  Note the TODO tag that implies that we’ll be expanding this in the future to handle diagonal movement.  (It’ll be fascinating, I assure you.)  Anyway, again the command provides its own constructor, and this one uses the data parameter because the game needs to pass one of those compass directions in so the command knows which way the source plans to go.  (Once again, I note that there’s an unused parameter – targ – so I modified the constructor definition after this screenshot was taken to remove it and simply pass null to the parent class.)

When the game processes a MoveCommand, it looks to see which direction is stored in the data, then constructs a Vector3 representing the modification to the source Mob’s position.  It queries said position (making a copy of it in the process, as the getter for that property provides a copy of the value, not the actual property itself), modifies that copy, and then checks if the Mob can move into the new space.  If they can, then the command updates the source Mob’s position with the new value… not using the setLocation() method that I defined for precisely that purpose!  Argh!  Y’know, it’s a good thing I’m doing these blogs.  They’re helping me catch a lot of mistakes that I’m overlooking while coding.

Anyway, we’ll fix that later.  You’re probably wondering what magic the canMoveTo() method is doing to check if the Mob’s path is clear.  Wonder no longer.

DHU 13

Remember how I said a command might need access to the Dungeon?  I’ve added a getter method to access the DungeonMap object, and passed that to the canMoveTo method, which calls the map’s getTile() method to return the Tile object on the WALLS layer at that position.  If there is no tile there, then the space is clear and we can move there.  Easy!  That’s the whole reason we have a WALLS layer in the first place – all collidable/solid tiles that block a Mob’s movement exist on that layer, and that layer alone.  You’re not shrooming if you don’t remember my defining a getTile() method, though; I added it as part of implementing collision.

DHU 14

Well, that’s enough code for today!  Tune in next time and I’ll explain how the game polls the turn queue and processes command input.  We’ll have our adventurer trekking about in no time, I promise.

-Steve

Categories: Development, Dungeon Ho!, Unity | Leave a comment

Dungeon Ho!: Unity – Dev Blog #3

Welcome back, Unity fans!  Today, I’m going to show you how to use the Tilemap objects created last time… as well as the basic object/entity hierarchy that’ll finally get a player into the maze.

The cornerstone of all Unity objects is the GameObject, and we’re going to utilize this beast for all of our mobs (old-school speak for Mobile Objects), items, and of course, the player.  We need a base class script that we can attach to a GameObject so that Unity knows it’s one of our Entities… so, enter the Entity class;

DHU 5

The Entity is a MonoBehavior, because there’s some functionality in that class that we’ll need down the road… primarily the gameObject member variable.  At the very least, we need to be able to modify its position in the game world!  And speaking of that game world, let’s backtrack a bit since I did promise to show you how to generate a very simple test map to run around in.

DHU 6

As you can see, our TestDungeonGenerator inherits from our DungeonGenerator ScriptableObject, and I’ve added a CreateAssetMenu tag at the top of the file so that I can automatically create a new Asset of that type.  We’ll need to create one as a prefab so we can assign it to the DungeonGenerator variable from Dungeon.cs, swapping out the (currently) empty original DungeonGenerator.

This TestDungeonGenerator overrides the generateDungeon method of that class to create a simple 10×10 dungeon full of empty tiles, denoted by the tile constant TILE_EMPTY.  We then set all of the tiles on the border of the map to TILE_WALL, and set two of the empty tiles to our up and down stairs, respectively.  We also throw a single solid wall into the center of the dungeon to test collision and pathfinding, once we’ve got them in.

Now that we have somewhere for our player to go adventuring, let’s continue inspecting the object hierarchy.  We’ve got an Entity, which forms the basic building block of all of our in-game objects.  Item objects will inherit from Entity, once we are ready to equip our Mobs, and (you guessed it) the Mob class will inherit from Entity.  Currently, the only member variables Entities have are weight and flags, but we’ll be adding to that later on.  Note that the Entity class defines a Start() method, which Unity calls when the object is first created/activated (and, for our purposes, is basically the same thing).  The Start() method sets the name of the entity so that we can quickly identify it in the Unity scene tree.  All subclasses will override this method, as you’ll soon see.

Naturally, the Player class inherits from Mob, so here’s our inheritance tree;

Entity > Mob > Player

Next, it’s time to port over the master ObjectSpawner class from the original Dungeon Ho! codebase.  This factory class, as its name suggests, is responsible for spawning every kind of object the game could possibly need.  Right now, we need it to spawn us a player.  Eventually, we’ll need it to spawn a player from a specific set of characteristics, like character class and gender, but for now all of that will be set to temporary defaults.

DHU 7

The spawnPlayer method creates a new, blank GameObject and attaches a Player component to it, representing our Player.cs script (which, currently, merely sets the gameObject’s name to “Player” – similar to how the Entity class does).  It then attaches a SpriteRenderer, and loads one of our existing sprite assets from the Resources folder to serve as its sprite.  Note that the sortingOrder is set to DungeonMap.RENDER_LAYER_ENT; this is a convenience constant I defined to put all of the spawned sprites in front of the TileMaps that make up the dungeon.  Once all of that is done, the method returns the newly-created gameObject.  Let’s see where this is all tied together… in our Dungeon class.

DHU 8

The Dungeon keeps a reference to the player (we’ll need it later), and it grabs a reference to the newly-spawned player’s Player component (we can always access the gameObject directly through it).  Although, I may want to simply return the Player component from the ObjectSpawner, now that I think of it.  It’ll save me from having to manually do that every time I spawn anything.  Let’s put that on the ol’ TODO list.  Anyway, once we’ve got the player we set his position (I added a setPosition() method to the Entity class that changes the gameObject’s world position by passing it a new Vector3.  We’ll take a quick look at that next time when we cover movement), and parented the player’s gameObject to the Dungeon itself, so it appears under the Dungeon in the scene tree.  Hmm, may want to wrap that in a method as well.  To the TODO list it goes!

Eventually, this spawn code is going to be moved out of the Dungeon.start() method, but it’s okay for now.  Let’s see our results!

DHU 9

Not too shabby!  Tune in next time when I take our intrepid adventurer out for walkies, creating the object command queue processor and handling collision with the TileMap.

-Steve

Categories: Development, Dungeon Ho!, Unity | 2 Comments

Dungeon Ho!: Unity – Dev Blog #2

Welcome back, coding fiends!  Today we’re going to look at the core app design for Dungeon Ho!: Unity, from both a project and code perspective.

As I mentioned previously, I decided to go with a single-Scene approach.  Each game menu, screen, and dialog would be organized in a hierarchy of Unity Canvas objects, which will keep me from having to worry about data persistence or nested scene management.  As this will be a single-developer project, encapsulation and decoupling is not going to be my biggest concern.

So, let’s look at the basic scene tree;

DHU 1

As you can see, within the scene I have a GameObject called Game.  This, as the name suggests, is the object that contains the entire game; the map, the monsters, the players, all of that good stuff.  It will also eventually contain things like AudioListeners, high score tables, and so on – but, we’ll burn those bridges when we come to them.  For now, the Game contains our Dungeon, which consists of a Map that has three layers, represented by Unity Tilemap objects; Floor, Walls, and Details.  These layers are separate for both stacking/rendering and collision purposes, which we will set up later.  Floor and Walls are self-explanatory, but what about Details?  The Details layer will represent “props” that decorate the dungeon, like torch brackets, furniture, and cracks in the floor.  By keeping those tiles on their own layer, we can generate a wide variety of scenery without having to make a tile for every possible combination.  The Camera will eventually be attached to our player object, but for now we can let it float free.

Next up is our overall project structure for asset management.  I’ve created some preliminary folders, as shown in the Project view;

DHU 2

As you may already know, the Tile objects are created from sprite sheets sliced from singular images.  Currently, I’m using placeholder art imported from the original Dungeon Ho! assets, but these will eventually be replaced.  The tile assets themselves are kept under the Resources directory so that they can be dynamically loaded at runtime.  I should probably look into making them AssetBundles instead.  We’ll throw that on the ol’ TODO list.

With the initial set of GameObjects created and a basic project folder structure in place, let’s start coding.

There is, of course, a Game.cs script – but as our Game currently does bupkis, it’s simply an empty MonoBehavior.  We’ll fill it in as the game progresses.  The most important thing to do right now is to create our Dungeon/Map classes so that we have something to run around in.  The Dungeon GameObject has a Dungeon.cs script attached to it, which currently (we’ll change this eventually) generates a new dungeon map when the game starts.

DHU 3

Note that we do a GameObject.Find() call to locate the Map GameObject within the class and grab a reference to its DungeonMap component (…which I haven’t discussed yet; it’s the DungeonMap.cs script).  We do this so we can access the script attached to it and manipulate the Tilemap, which we’ll see in a moment.

The DungeonGenerator member variable deserves special mention.  Initially, I had the DungeonGenerator class not inherit from anything (IE, it wasn’t a MonoBehavior or ScriptableObject) that just had a single static method called generateDungeon().  I switched it to a ScriptableObject and made it public so that I could swap out the DungeonGenerator object from within the editor.  This is so that I could dynamically assign different DungeonGenerators to the object, which would generate different kinds of dungeons.  It’s currently using a class called TestDungeonGenerator, which generates a single, simple 10×10 room with a center wall and both entry and exit tiles.  When the actual DungeonGenerator is ready, and I’m done using this small room for testing, I’ll simply swap in the other one.  ScriptableObjects; you gotta love ’em.  I’ll go over that process a bit more next time.

Here’s the DungeonMap.cs;

DHU 4

Pretty straightforward so far.  I’ve defined constants to represent the layers, as well as the different tile types.  There’s an array of Tiles (for our loaded Tile resources) as well as TileMaps (for our Tilemap layers).  We do some Find() calls to locate our in-scene Tilemaps; again, we could easily just have assigned them from the editor, but this is pretty much the same thing (whoops! Took the screenshot before I changed the DETAILS layer to find the “Details” object!  Rest assured this was fixed in the code).  We also define a method to load a particular tileset, which grabs all Tile assets in the provided folder, and a setTile() method that sets a particular tile on a particular layer to a particular index.  We simply pass in the TILE_ constant and the code indexes it into the Tile[] array and finds the proper Tile object to use.  Easy!

Tune in next time, and I’ll show you how I generated the test dungeon… and, if we’re lucky, I’ll also have had time to get a player wandering around in there.

-Steve

Categories: Development, Dungeon Ho!, Unity | Leave a comment

Dungeon Ho!: Unity – Dev Blog #1

Hello, nerds!  Today we’re kicking off the first in a series of Development posts about porting my first Android title, Dungeon Ho!, to Unity.

Dungeon Ho! was a Roguelike written for Android API level 10 and released in the summer of 2013.  It did… respectably for a first solo attempt in a niche with basically zero marketing, but ultimately a bunch of design decisions that I’d made during development came back to bite me in the ass to the point where the planned ongoing addition of new content and features never came to be.

Here’s a screenshot of the game running in either Android Studio, Eclipse, or on my test device.  I forget.

5631_10151355638768124_168043149_n

I’ve had a plan to do a sequel ever since I realized there were a number of ways I could have made the game better, both feature-wise and code-wise.  After all, it was my first Android title and I’d learned so much since (mostly by leveraging the fact that I’d published an app to actually get a string of jobs as a professional Android developer, but I digress.  Even so, Lesson #1: publish something!  It looks great on your resume!)… but one snag came in the form of Unity, which I’d learned during a stint of downtime between jobs.  Unity offered so much stuff in it that I could leverage to make great games, but the tilemap support was still in development and, at the time, didn’t seem that great.  I revisited it recently, though, and that cinched it; rather than re-use my custom Roguelike engine (…which needed refactoring anyway), I would merely port the game to Unity.

Why. though?  After all, refactoring aside, I already had an engine, right?

Well, yes.  But here’s the thing; Roguelikes have a big audience, especially on Steam.  If I could make a stellar sequel, and I did it in Unity, I could leverage the cross-platform building capabilities of Unity to spread it far and wide.  I mean, I did already have one or two people ask me if there was an iOS version, so there you go.

***

Ok, now what?  Well, the first thing I had to do in terms of tech (I already know my feature list) was to analyze the Android build and see where I went wrong, and what exactly needed to be re-done as opposed to just ported to C# from Java.

Here’s my initial list;

  1. UI – When I first moved to Android, I didn’t feel like it would be productive to spend a huge amount of time absorbing all of the new platform’s features.  After all, by this time I had a large amount of J2ME experience and felt that I would be able to leverage my hard-won optimization skills to keep the game small and light.  So, all I learned how to do initially was start a thread that would paint to a canvas, scale it to the size of the device’s display, and that would be enough.  My main concern was that I had no hard data on whether mixing blitted bitmaps with Android’s XML/Layout-based UI would cause performance issues that I wouldn’t start seeing until riiiiight before release, because I was already developing on the Android emulator (I didn’t have a device yet) and figured I’d play it safe.  In the long run?  I wasted a ton of time rolling my own UI components when I could have totally just used Android’s dialogs, buttons, lists, text boxes, and other handy widgets.  For the Unity port, I will definitely be leveraging Unity’s UI canvases.
  2. More robust Command system – To keep the amount of Java classes in the app fairly small, I chose to do a number of things with switch statements rather than polymorphism.  This was fine when the switch statements only had a few branches, but the game essentially takes a different switch branch for every possible command in the game.  This… got ugly.  The Unity version will definitely provide child classes for the TurnCommand class, cutting down on the game loop complexity immensely.
  3. No class-based conditionals – “if (variable instanceof Class)”?  Blargh!  The fact that I kept checking the types of my objects told me that I’d blundered my inheritance chain somewhere.
  4. Better object spawning – For some reason, I chose to do the most basic of object initialization within the SpawnFactory classes, but setting other aspects of the items and mobs was done wherever said item/mob was spawned, leading to me copy-pasting various spawning boilerplate all over the place, so that when a bad spawn initialization occurred I would have to hunt down which spawn chunk-o-code was responsible.  Making the spawn factory more robust, to allow specific kinds of object spawning as well as randomly-generated, is definitely going to be a must.
  5. String formatting, not concatenation – Ugh.  With the amount of text in a Roguelike, you’d think I’d have been smart enough to use formatted strings, but no; I concatenated everything.  The amount of time I spent tweaking my string cleanup routines to remove rogue spaces and such was… a lot more than it needed to be.

That’d do for a start.  My next step was to decide on the overall application architecture within Unity.  After a lot of pondering over things like persistent objects and scene loading, I eventually decided to just keep it simple and use a single Unity scene with a number of switchable canvases for the menus and information screens, both in and out of the game.

And, that’s basically where I am now.  Tune in next time where I’ll go over the initial Unity coding, and how the various game objects (as well as GameObjects) are arranged.

-Steve

 

Categories: Development, Dungeon Ho!, Unity | Leave a comment

A New Beginning

Hey there gamers, how’ve you been?  Has it really been five years since Dungeon Ho! was released on the Android platform?

I’ve been dipping in and out of new projects since then, learning new technologies and dealing with the ups and downs of Real Lifetm – but I’m happy to announce a few happenings that may be of interest.

Firstly, though… how ’bout that Ouya, huh?  Didn’t exactly take off like gangbusters, did it?  I’m kinda disappointed that I wasn’t able to develop anything for that platform after all, but I guess in hindsight it would have been a whole mess o’ wasted effort.  Those of you curious about a followup to Dungeon Ho! are going to be happy, though, as I’ve finalized the design of the pseudo-sequel, Dungeon Ho!: Unity.  DH!U is going to be a spruced-up, refactored port of the Java/Android codebase to the Unity engine in C#.  Big whoop, you say?  Well, the more interesting aspect of this decision is that I’ll be writing a series of Dev Blogs documenting the process which will serve as a pseudo-tutorial of sorts for those of you interested not only in the complete game development process from beginning to end (God willing, anyway) as done by a solo indie developer, but also the ins and outs of developing a 2D roguelike in Unity.  I’d wager there are far more of you in that latter camp than the former, at least for now!

That’s not all I’ll be up to, though; I’ll share development of all of the other projects I’m working on, as I work on them.  Hopefully you’ll find these postings useful in your own game development journey in one way or another.

Steve

Categories: Development, Dungeon Ho!, Unity | Leave a comment

O hai

Hey there. I’m Steve, the lead developer and general Guy in Charge here at Sandalfoot. We (okay, so far just me and occasionally another contributor) are an up-and-coming indie game developer whose work primarily centers around the Android platform.

Our first title, Dungeon Ho!, was released in late March 2013 and garnered some pretty good reviews, including this one from Hardcore Droid. Since then we’ve been busy learning the Ouya and porting it to that console, as well as working on the tech for our next couple of games.

The future is bright for Sandalfoot (we may even have a logo pretty soon!), so hop on and join us for the ride, why don’t you?

Steve

Categories: Uncategorized | Tags: , | Leave a comment

Create a free website or blog at WordPress.com.