Tuesday, April 22, 2014

Unity In Game Level Editor for VXT

I decided to create a level editor for my Senior Production game VXT.  VXT is a side scrolling 2.5D racer where players compete to finish levels with the fastest time by using a polarity shield to attach or repel to objects a navigate the world.  Example video shown below.

Because this game is based off of very short 1 - 2 minute experiences I figured how else to encourage players to really compete against one another the hand the very tools of world creation to them and let them go to work and see if their friends can beat their creations. As one of the creators of VXT I tried to make interesting and action packed levels but as I can see from other games with player level creator tool, there are some really talented people out there that will put in the time to make some really amazing levels.

So I with all of this in mind I set out to accomplish the follow goals:

1. Create a in game level editor to allow player to use a Gamepad to build a world.
2. Make a dynamic menu system to allow world pieces to be easily categorized for streamlined building
3. Allow the ability to save local and test the levels in game at the touch of a button.
4. Give players the ability to push their levels to our server.
5. Make it so other players can pull down levels from out server and play them locally.
6. Save high scores and "Ghost" characters for all custom levels to enhance competitive play. 

Creating a level editor in itself is the easy part, making it usable is the challenge especially when the player is working on a game pad, even things like navigating menus becomes a challenge without access to a mouse and keyboard.

Since our world is basically created in a 2D space, it made this whole navigation to build thing a little easier.  I put the player on rails setting them on a specific axis a set amount back and limiting the player to only be able to move up down left and right using basic translation.  This way the world and the player is always lined up at least in the Z axis.  The pieces for manipulation are set much further back but since the player can't move in the Z axis the pieces are spawns a set distance away and will always be on the correct Z axis.  About halfway between the player and the pieces spawn location I added a transparent plane  as sort of a aiming sight so the player can more easily line up pieces. More so on the movement set I added in the ability to drastically reduce the speed in which the player moves the builder, upon holding down the left shoulder button the player moves at 1/8th speed.  This allows the player to quickly move from section of his or her creation to another section, but then give precises precision when placing the pieces. 

Next logical step would be to worry about how we actually spawn the objects we want to build with, but in my case this goes hand in hand with our dynamic menu system.  In VXT we have many different types of objects we have ramps, pipes, walls, blocks, and any of our intractable objects such as speed bad and colored walls. As such I wanted to created at nested menu system to allow players to know exactly where each piece is located.  Unity has a resources folder inside that folder I created a bunch of prefabs that the player will use to build the world.  These prefabs are named and prefixed with a tag of what they actually are So for example Pipe_Half Pipe.  The pipe prefix causes the pipe object to be placed in a sub grid. To create these grids I used Unity's GUI_SelectionGrid.  The grid takes in the parameters height and width of the buttons, the number of rows and columns for the grid, the current selected item and an array of the names of the items in grid.  These work out so well for my implementation, the selected variable allows me to use the grid with the xbox controller, I increment the variable based on the direction of the left joy stick, I also add in a delay timer so that it I only move up or down 1 ever so often.  Even better when the player selects an object I can use the display name to directly look up the object they want from the resource folder and instantiate it.

    Once it is instantiated I place it on the spawn point and it is now attached to the builders movement.  Upon hitting A the builder will let go of the object and set it in place.  This is where a lot of design and quality of life decision come into play.  In order to make this world truly customizable I granted the player the ability to scale and rotate the objects they are holding.  If they hold the left trigger they can change the scale of the object with the right joystick, the X scale left and right, and the Y scale with up and down.  We simply change the Euler angles directly in the object.  The rotation is similar, If the player hold the right trigger the right stick changes the rotation in the same way as scale.  More importantly I needed to add a slow effect to it much like the movement. If they player holds the left bumper it slows down the rate of change that way the player can scale and rotate things perfectly.  These are the basic building blocks of the level editor with everything I mentioned above they are able to fully create a world to play in, next comes the real challenges, testing these world, and sharing them.

    Testing the world quickly is actually quite an easy task, when the player selects save from the start menu (being implemented the same way as the menu system) I save out all relative data to the world, so item names, their position, rotation, scale, and any special properties if they have them to a xml file. I also prompt the user for a name of the level which I then name the xml file accordingly.  I then remove the builder object add in the player.  At this point the level is fully playable.  Once the player reaches the end of the level or quits, I remove the player object add in the builder and then they are ready to continue creation. It's quick easy and allows for fast iteration and testing of sections.

    With the level file already saved out in an XML format sharing the level is easy as pie.  When the player saves and uploads the object. I make a call out to our php server, in there I have a script to add files onto our server, I call the script and hand it the xml file.  The server takes the file and prefixes it with the players username from the game, this allows people to name their levels whatever they want and not worry about them being overwritten as the account name keeps them unique.

    Once they are up there having a someone else pull them down and play them is super easy.  I have another php script that will pull down all levels on our server. I make an empty scene that the player can view the list of player made levels in.  I pull down the names of all the levels and display them in a selection grid. When the player selects one, I use another php script to get the xml file from our server based on the name. I download the file and then build out the level line by line add in a player and just like that they get the ability to play the level.  Furthermore a ghost file is brought down as well which shows the exact movements of whatever person has the best time on a given level, so you can directly compete with your friends play.   

All six of my goals were completed and it was quite an interesting experiences that I feel good about taking the time to complete. 

Tuesday, April 8, 2014

Physics : Attempted Mass Aggregate Physics


Above is my attempt at creating a Mass Aggregate Physics system.  A Mass Aggregate Physics system is one in which objects are made up of many little masses which based on forces applied to them cause the whole structure to move and rotate.  For example instead of a box being one single entity it is made up of 8 nodes all interconnected via rods. When we want the box to rotate since there is no central mass to grab and do so we apply force to a few of the 8 nodes causing it to move and rotate in a corresponding direction.

In my take on this physics system I have the follow physics types.  Basic balls which can be used on their own as a single object or points in larger objects.

Springs which much be at least two connected nodes or a node and a fixed point in space.  Springs have a have a certain amount of elasticity to them causing them to apply force outwards if they are compressed too close together or apply force inwards if stretched too far apart.

Bungees are another type which while much similar to springs have a minimum length before the elasticity kicks in, anything below the minimum allows the bungee to stay at rest.  This can also be anchored or  interconnected like the springs.

Cables which have a maximum length of which then can stretch too but apply no force inwards upon reaching that.  As well no no minimum length so they can compress as much as they would like.  Consider cables like a piece of rope.

And finally Rods which connect two points and keep them a set distance apart from each other.

Making the basic building blocks of the physics system wasn't too challenging, on their own I got springs bungees and cables working, however the eventual combination of the three and rods in of itself caused me many problems.

Rods being one of the building blocks and my main problem seems like the perfect place to start with what went wrong. Rods seem like a fairly simple task, keep to points no matter how they move equal distance away from each other, simple right? Not so much, my first few iterations of the Rod objects caused some quite hilarious outcomes.  Upon instantiation my rods would try to resolve the collision they were having between each other because due to gravity and basic settling they either got to close to far or both.  Upon resolving the collision they would fly off into the distance (staying the correct distance from each out might i mind you).  While funny and a good attempt at creating perpetual energy it did not create the desired results. I then got rods to actually work when standing straight up or laying down , but upon interaction with any force being applied to them they would practically rip a whole in space and time trying to get away from each other.  It seems that the algorithm that I was using to attempt to resolve the contacts had a double negative and applied forces in the same direction, however a little late in figuring this out and not knowing exactly where to change this means it stayed as a bug.

Attempting to connect multiple rods was even a worse idea. making even a simple square as stated above was way out of my reach,  the structure while only needing 4 nodes needed about 24 rods to hold it together each outer wall of the cube and cross braces to make sure the cube didn't collapse in on itself. However once the rods were in place the nodes would move ever so slightly, they would all have to compensate and the cube would literally rip itself apart, and I was never sure why,  which is exactly why this iteration of my physics system contains no rods.

Beyond creating the basic system with the above building blocks, the task at hand was to create a player made of these objects who could navigate through a world obstacle course created via a level editor all while collecting something and interacting with some sort of artificial intelligence.

Creating the level editor was an interesting task, due to the crunch time that this is, I took the easy route and created a text based level editor.  Basically all this does is allow you to feed in objects via a text file and It will create the world around it.  This was very using in setting up multiple levels  like I did. because when you you completed one, all I had to do was clean up and open the next file and load them in.  Another cool feature of this level editor is because when I reset the world and change levels it re reads the file, you are able to create  and change levels while the game is running, which was great for debugging and creations, all you had to do was hit the reset button.  An  example of  what one of the objects in the levels in the video looks like is below. I just read in the values line by line and create them as it goes. The labels of each item makes it quite simple to understand what each of the values do.

Bungee
x
50
y
10
z
0
radius
10
mass
5
Ball2
x
0
y
10
z
0
radius
10
mass
5
Anchored
false
spring constant
0.01
rest
100
spring constant
0.01
rest
100


Adding in collectibles was by far the easiest task,  I already had basic orb collision in my engine so It was really just making a new object of a different color that when the player collided with it would disappear. In my game when the player collects all of the collectibles this is when the level is over and the next one loads in.

The final portion was the AI which I very much enjoyed creating.  If you look in the video on the top of the screen is a ball that seems to be flying back and forth.  What I decided to do for this part of the project is attempt to recreate the little cloud guy from original Mario games. What he does is takes a look at where you were last frame and where you are now.  Calculate your velocity and then move in front of you.  Upon reaching that the AI has a chance to drop a ball causing more objects for you to collide with and thus ruining your day.  As you can see he kind of just picks a side when you start and hovers around there, in order to avoid edge cases when you are not moving at all and him not just dropping bombs on your head constantly. I added a little margin of error to allow the AI to always hover around one side of you.

With the task at hand "completed" I decided to take this last bit to explain where and why I think things went wrong, because as you can see in the video  the world doesn't really act as well as it should, and it's in a 2 and a half D setting. Somewhere a long the line while creating these features I lost the ability for my object to draw in the Z direction. I'm not sure why but it does happen.  If I try to move objects in the Z direction while they do not look like they are moving, the lines drawn between them do move, and collision between objects behave appropriately.  For example, an object at Z 10 and Z 10 will collide but objects at Z 10 and Z 50 will not.  I have no rhyme or reason why the objects cannot drive in the Z direction.

Another problem I ran into was way back when I first created my springs and bungees I had a weird bug where they would always gravitate around the origin of my world (0,0,0) I never really questioned it and moved on because I had bigger fish to fry, but now that I tried to make a world full of these objects I ran into some obvious problems. Upon placing spring objects anywhere in the world too far away from 0,0,0 via my level editor when the game runs they will fly back at max speed toward 0,0,0 destroying and knocking away everything in their wake.  I have narrowed this down to a bug in my spring force code which somewhere some how chose a fixed point of 0,0,0 to be bound to.

These bugs made a full world quite impossible to create which is why I made a few sets of levels which allowed to show off each part working on its own and still giving the player a decent feel of progression and what type of interactions they would expect to encounter in a Mass Aggregate world.


Friday, April 4, 2014

Capstone: Trying to polish

This week we finally came to the realization how much more work our levels need. There are too many, a lot of them are very clunky and break the flow that VXT players crave. And they art order is too much for our artists to fill.  So this week I played not the role I am but the role the team needed. Most of my work was on the design and QA front.

We realized that only Brian actually knew how to make a VXT level that captured that sense of speed, and he did it fairly well 4 times in a row. So as a novice player with many ideas about our game I've been working along side him, to run through our levels find the hard breaking points like the 90 degree angles, or poor choice of phase wall useage, and remove, edit, and remake them.  We've decided to cut down from 16 level to about 8 which means a lot has to go and a lot has to change.

I wrote up a detailed list of all things in all levels that I thought were good and bad, this way we can start grabbing the good parts our designers made and start to string them together to hopefully make 8 refreshing and smooth levels very quickly and with input from all 4 main designers and myself .

 I was able to help debug some object that weren't working correctly due to programming issues but mostly I was there to brainstorm and I feel like this is really helping the game as a whole. We needed this hands on feedback and tweaking from the beginning, there is a rough 10 days ahead of us and we're going to give it all we got to make it right.

It's taco time to the max.