Dream Build Play – More Levels and XBox Live Integration

Over the Christmas holiday, I’ve been working on wrapping up the Turn Back the Clocks 4 game for my Dream Build Play 2017 entry. The three things that I planned to accomplish were creating more levels, XBox Live integration, and updating the leaderboards.

Creating additional levels was my first priority. Fortunately, with my level parser code, making new levels is a trivial task. I use a text editor (Notepad++) to lay out all of the clocks, mines, and slot in each level.  For the first level, I wanted to just introduce the player to the main objective of the game, which is activating the clocks.  So the first level is just filled with clock objects.  The other two mechanics in the game are the bonus wheels and mines.  I wanted to introduce these to the player each in a separate level.  I decided to introduce the bonus wheel in the second level, because I consider it to be a positive stimulus.  If you hit the slot target with a ball, then you get the bonus well.  Therefore, I introduced the mines in the third level, since it has a negative result.  Hit the mine with a ball and it explodes.  Using text files to lay out levels has worked really well in my other games.  It eliminates the need for a bloated level editor and the levels can be quickly and easily changed.  The downside is that there is only so much information that you can store in a single character.  However, it works well for games like this where the objects don’t have any additional properties.

The one thing that I really considered when making levels was the amount of interactivity between the objects in the level.  Some levels I had to rework just because it was possible to shoot a ball to the bottom without it hitting anything.  Another problem arose when I would have a bonus slot on the level without anything above it, so that the player just needed to line up the cannon with the slot to get the bonus every time.  With a lot of the levels, I had to do a lot of trial and error by playing each one multiple times.  I didn’t want the bonus wheels activating all of the time, but I didn’t want it to be so hard that that it was rarely activated.  I tried to make it so that the bonus was activated about once each time the level is played.  Due to time constraints, I currently have six levels, which feels about right for this competition.  I had originally planned to make twenty levels, but I think the player would have a good understanding after six levels.  After the competition is over, I would like to go back and add more levels.

I wanted to fix the leaderboards in the game, so that the scores were stored on a per level basis.  Currently, the game calls a PHP file on my server with the player’s name a score as parameters after each level is completed.  To separate the scores by level, I would need to modify the scores table in my MySQL database to add a column to hold the level number.  This wouldn’t be too difficult, but I would also need to rework the PHP code to accept level number as a parameter.  Also, it appears that I may not be able to send an HTTP request to my server when my game is deployed on the XBox One.  I’m guessing the UWP applications may be sandboxes from contacting any external servers.  There is a way to store scores for a leaderboard using the Microsoft infrastructure, but I really haven’t gotten a chance to try it yet.  If I do eventually use the Microsoft leaderboard services, I would definitely have to consider modifying my code so that I could switch between using my server or Microsoft’s leaderboards.  It seems like it should be possible, since I would just need to add an “if” statement in my Leaderboard class to control where the name and score data is sent.

The most important change that I needed to make was adding the XBox Live services.  Actually, I believe I could submit my game as a Windows 10 desktop app and not integrate XBox Live.  However, it is required to publish to the XBox One Creator’s platform.  I’ve been through this process before with my first XBox’s Creator’s game, Kitty’s Adventure.  The first thing that I do is make sure that the game is playable with an XBox controller.  To do this, I had to add additional button mappings in my Unity Input settings.  I added virtual buttons for each of the colored buttons (A, B, X, Y).  I found this diagram a few months ago, which is a good reference for how each button on the XBox controller maps to each joystick index.  I noticed in the past that when a Unity game is deployed on the XBox One, the UI controls don’t seem to work.  So to get around this, I add button icons next to each of the Unity UI buttons, and then write Input handler code, which calls the same method that is executed from the button press action.

Image from CMU.edu Wiki ( http://wiki.etc.cmu.edu/unity3d/index.php/File:X360Controller.png )

The rest of the XBox Live integration involves little actual programming.  The general steps for XBox Live enabling a Unity game can be found in the Windows Dev Center documentation.  Of course, the build target must be set to UWP, which generates a Visual Studio project.  Here are some pitfalls and gotchas that I’ve experienced from this game and my previous game.

  • If you get a message like “failed to process xbox live directorynotfoundexception”, then change the Scripting Backend from IL2CPP to .NET.  This should also fix the problem with Unity C# Projects not being selectable on the build window.
  • Before deploying the game in Visual Studio, make sure that Master x64 is selected in the configuration box dropdown.  If I remember correctly, if those two settings aren’t selected, your build will fail with the local certification tool.
  • When deploying to XBox One in developer mode, make sure that your XBox is connected by a wired networking cable.  It won’t work if your XBox is just connected by WiFi.  If it doesn’t display an IP like 192.168.x.y (it’s something like 0.0.0.0), then plug in your XBox One to the same router as your development PC with Visual Studio.  You may also have to restart the XBox One as well after the wired networking has been connected.
  • To build an appxupload package to upload to the Windows Developer site, you have to choose Project > Store > Create App Package.  It’s really important to note that in the Solution Explorer you must have the line with the name of your project plus (Universal Windows) or below selected.  If you have any line above selected (such as Assembly-CSharp) selected, then the Create App Package will be disabled in the menu.  I spent quite a bit of time figuring that out.
  • If you want to change the default splash screen (I think it’s a white screen with a gray box and “X” by default), the select the Package.appxmanifest in the Solution Explorer, select the Visual Assets tab, select Splash Screen and set select an image for the 1240×600 px image.  You can also set the background color as well under Display Settings.  I used Gimp to select the green color from the bottom of my splash screen image, and then selected the color editor to get the hexadecimal value, which I copy and pasted into the Splash screen background field in Visual Studio.  You can also set the other images as well, but it is possible to set those on the Windows Developer site before submitting your game for certification.
  • On the Windows Developer site, make sure to go under Services > XBox Live and press the Enable button for the Creator’s program.  I actually had a problem with this page going into an infinite load when I used the name “Turn Back the Clocks 4”, however it would work for my other games.  Trough trial and error, I narrrowed the problem down to the words “Turn Back”.  Therefore, I just named my game “Turn the Clocks 4”, and then set the name on the XBox enable screen to the correct name.
  • Before submitting the game’s package, it is important to run the Test on the XBox Live screen.  Otherwise, you will get an error about a missing XBox Configuration when you try to submit the appxupload package.
  • When deploying to the XBox for the first time, I always seem to get a NullReferenceException on the userID assignment line in LoadProfileInfo.  I can press the Continue button in Visual Studio, and it will proceed with no problems.  However, it just displays the Add User button on the title screen when the game starts on XBox One.  I think this is the same thing that happened with my Kitty’s Adventure game (it was called veto error), and gamertag display works correctly after it is deployed to the marketplace, but it doesn’t work when deployed through on XBox One in Dev mode.
  • Whenever building using the Master configuration or making a Windows Store package, it’s time to go make a sandwich.  It takes a really long time.  I haven’t timed it yet, but it feels like it takes about ten minutes or longer each time.

After going through all of the steps, I was able to build the package to upload on the Windows Developer site.  It passed the Certification tool as well.  However, it must also pass a second certification after it has been loaded to the site, which I think may actually be reviewed by a real person.  As I’ve learned with my previous game, it is possible to pass the local certification tool, and then fail the certification after it has been submitted to the Windows Store.

 

Dream Build Play – Mines and Slot Machine

I’m now wrapping up the implementation of the gameplay elements in the Turn Back the Clocks 4 game for Dream Build Play.  The two features that I had envisioned adding were mines and a slot machine.

The mines just act as a hazard, which destroy your ball on contact.  Programmatically, this was relatively simple to implement.  The mine is just a GameObject with a sphere collider.  When a ball collides with it, the ball is destroyed.  I do a check in the ball’s on collision method to verify that the object that it has collided with has a Mine component (in other words, has been assigned the Mine script).  I have found that this is a better way to determine an object’s type than using the Unity tagging system.  I don’t know if there are any performance differences, but tagging seems really redundant when the object already has a type from the script that has been assigned to it.  Plus, a GameObject can have multiple scripts assigned, but it can only have one tag.

From doing game jams over the five years, I have really learned a lot tricks.  Others may call this “tools in my toolbox”.  I’ve tried to use an array of the tricks that I’ve learned in this game.  One of those is the Blender Cell Fracture add-on.  This Blender feature will take an object, and break it into multiple pieces based on the parameters that you set.  Then you can apply Blender physics to the broken pieces, which will make the object explode over a period of time, which is saved as an animation.  So I took my ball model (another good reason to use a modeled ball in Blender instead of the default Unity 3D sphere) and applied the cell fracture.  I saved this now model and animation as a ball explosion.  This way, when the ball hits the mine, I can destroy the original ball, and instantiate the ball explosion.  This makes things a lot simpler, keeping the ball and it’s logic separate from the explosion.  The only catch is that you’ve got to pass the ball’s material to the ball explosion, otherwise the explosion will just look like a gray ball breaking apart.  I created a method in the ball explosion, which takes the material of the ball as a parameter.  The other issue is that the ball explosion actually has two materials that are generated by the Cell Fracture plugin.  I know I’ve tried setting the array of materials on an object before, but it never seemed to work.  After some research, I found that GetComponent<Renderer>().materials actually returns a copy of the materials on the object.  So to assign new materials, you have to set the Material array back to the materials property and it will work.  Now when a ball explodes, it is the same color (blue, red, or yellow) of the ball that hit the mine.

The other feature that I wanted to have in the game was a slot machine.  I got this idea from watching Pachinko videos online.  In Pachinko, if a ball goes into the target slot, a slot machine will appear on the video screen.  If all three numbers match, then you get more balls.  I liked the concept of getting more balls from the slot machine.  However, I didn’t like the concept of just matching three numbers.  It just felt too random, and the numbers really didn’t have any significance.  Therefore, I decided to have the prizes on the slot reel, which were the balls which could be won.  Then I had the idea of having a multiplier reel, which increased the number of balls that you would win.  The only thing was, I wasn’t sure how this would work with three reels.  Finally, I just decided to have only two reels, which made things simpler and much easier to under stand.  The first reel is the ball type (blue, red, or yellow) and the second reel is the multipler (x1, x2, or x5).  I wanted the better prizes to be more difficult to win, so each reel has five of the low prizes (blue and x1), two of the middle prizes (red and x2), and only one of the best prizes (yellow and x5).  That makes eight total items on each reel.  The chance of getting the best prize on both reels (yellow ball x5) is 1/8 times 1/8, or a one in sixty-four chance.  That seemed about right to me.  I wanted the best prize to be rare, but not so rare that it will never occur.

I created a SlotMachine script, which controls both of the reels.  I decided against have scripts for each specific reel, although that would be helpful if I had a unknown number of reels.  The SlotMachine script has float variables which store the rotation of each reel.  Each reel is set to a random position, and rotates for a random period of time.  It took me a little while to determine which prize was selected when the reel stopped.  I converted the rotation to an index by dividing by 45 (360 degrees divided by 8 prizes) and rounding to the nearest integer (modulo 8 to take care of the case when the rotation is greater than 315 and it rounds up).  I also have to a 90 to the rotation to get the correct index.  This took me a while to track down, and I can only explain it as being an issue when moving from the Z up coordinate system (in Blender) to the Y up coordinate system (in Unity).  Frequently, when a Blender model is imported into Unity, -90 degrees on the X rotation is automatically applied in the transformation.  However, when you’re handling the rotation yourself, you have to add that 90 degree back to get the correct index.  Texture mapping the reels was not too difficult, but I had to make sure that each of the panels in the UV map lined up exactly over the appropriate square in the texture that I created in Gimp.  I made the reel texture 2048×2048, and each of the panels are 512×512.  I wrote down the sequence of prizes in a text editor, and placed them appropriately on the reel.

I also created a slot entry object, which is just a simple little container mesh with three sides.  The container has a mesh collider on the outside, and a trigger box collider on the inside.  If a ball touches the trigger, then a new SlotMachine object is instantiated.  After both reels on the slot machine stop, then the appropriate number of balls are added to the player’s ball queue.  Another problem arose when a new ball touches the slot trigger, when a SlotMachine is already active, which causes multiple SlotMachines to appear on the screen at the same time.  To fix this, I just simply check to see if a SlotMachine already exists using GameObject.FindComponentOfType<SlotMachine>() before creating a new one.  This is a little unfair, because the player will lose a ball when they should get another turn at the slot machine, so that is something that could be improved by adding something like a lid on the slot entry that closes when a SlotMachine is active.

I think I’ve finished with all of the gameplay elements on this game for now, and I will focus on adding more levels, touching some things up, and make leaderboards work for each level.  Also, I’ve got to submit the game to the Windows Store before the end of the calendar year for the Dream Build Play 2017 competition.

Dream Build Play – Multiple Levels, Stuck Balls

Earlier today, I did some game development off stream.  I was working on the colors for the background.  In previous games like Note Chomper, I have synchronized the hue with the music volume by calculating the RMS value of the AudioSource on the game object playing the music.  It is a nice effect, but sometime appears flickery.  I tried it for this game, and it just didn’t look great.  I tried modifying my code so that it uses frequency instead using the AudioSource GetSpectrumData method, but it still didn’t look right to me.  I also tried setting the hue to the sound of the cannon being shot, but I didn’t like it because it would be one hue (red) at the beginning while the balls were being shot, but then another value (blue) for the rest of the time.  I ended up settling on tying the hue to the current combo value.  I clamped the range from 0 to 50 combo value, which I converted to a 0f to 1f value.  I passed that value to my script which handles setting the background material color, which then sets a target hue.  The hue can be converted to a color using Color.HSVtoRGB, passing the hue as the first parameter and 1f for the second and third parameters.  I then converted my 0f to 1f value to a value in the range of 0.5f (180 degree hue which is cyan) to 0f (0 degree hue which is red).  So as the combo increases, the target hue value moves backwards from cyan to red on the ROYGBIV scale.  I also have value specified for speed of transitioning, so that it is a smooth change in color and it doesn’t jump directly from one hue to another.

I also updated the cannon model.  It didn’t look right before, because it was too small for the balls that it was shooting.  I added a cylinder at the bottom, for where the balls should come out.  I used the boolean modifier to “drill” another smaller cylinder hole in the middle.  I had to ensure that the hole was big enough to give the appearance that the balls were coming out of it.  I also had to significantly increase the size of the model, so much that the top is no longer visible on the screen, but I think that’s not really a problem.

It still really didn’t look like the balls were coming out of the cannon, so I created a particle effect that looks like a puff of smoke.  when the ball is shot, the smoke particle effect is instantiated.  I made it a separate GameObject prefab, which has  a custom script attached that destroys it after a few seconds.  One neat effect that I added is setting the color of the particle effect to that color of the ball that is being shot.  I just pass in the ball score to the SetScoreColor of the particle effect, and it uses the Ball color constants that I defined last time to set the smoke color.  I was really happy with how the effect turned out.

Finally, I added multiple levels to the game.  To do this, I created text files which contain the layout of the clocks on the levels.  I just used an ‘O’ to represent each clock.  I may end up using other letters for future objects to be added to the game.  I put these text files in the Resources folder under Assets in my project, which allows me to assign them to a TextAsset List that I defined in my LevelManager.  I added new parsing code which loops over each line in the text file (rows) and each character in every line (columns).  Based on the row and column position, the clock is Instantiated in the appropriate location.  It’s always important to subtract the row from total rows in the files, otherwise the level layout will be upside down.

Adding a Next Level button was a trivial change.  I added a new function in my Level Manager to handle incrementing the level number, which loops back to zero if it is equal to or greater than the level List size.  I also added a function which deletes all of the objects that are children of the Room object, which is the parent of all of the objects that are Instantiated for a specific instance of a level (the clocks, the cannon, etc).

Another problem that arose from the new level layouts is that sometimes the balls would get stuck between two clocks.  I added code which compared the velocity of the RigidBody of the ball to Vector3.zero (not moving), and destroyed the ball if those are equal.  That worked at first, but I found that when the level restarted, all of the balls were being destroyed.  Apparently on the first Update, the ball’s velocity was getting returned as zero.  To solve this, I added a countdown, which added Time.deltaTime for every frame that the velocity is zero.  Otherwise, it would set the coutdown back to zero (the ball is moving).  Once the countdown reaches a defined value (I used 1f, which is one second) then the ball is destroyed.  I need to go back and add a puff of smoke (probably the same one that I used for the cannon) when the ball is destroyed, so that it doesn’t look like the ball magically disappears.