Capstone Blog #7 – From 2D to 3D

Standard

So these past two weeks have been some of the most intensive weeks of this production process so far. Long story short: Don’t believe you can make a 2D game 3D over night.

The Situation:

So I’ve mentioned before that our game will be a 2.5D fighter – like the recent street fighters have been. These past two weeks have been a trial in porting code, making adjustments, and proving the art pipeline. It’s been hardwork, but the entire team has been giving it 200% and I’m happy to say that we’ve made it to the other side! While the environment is still a work in progress, this is what our game is looking like now:

closeup.PNG

It feels so good to see Johnny Fuego fully realized!

As you can see – the camera is a lot closer now, and we have a more fully realized ring to run around it. I had also implemented some dynamic camera work so that the action is always visible – no matter how far away the luchadors are.

faraway

He’s probably not going to make that jump…

This makes the both the artists and the designers happy – artists can have their characters and screen proportions well represented, while we can still have a lot of freedom of movement and rope mechanics being displayed at will (Most fighting games block movement off at the camera boundaries).

Perspective vs Orthographic:

Since the game was purely 2D before, I was using an orthographic camera. In the big change, our artists requested to change to a perspective camera, so we could use 3D background and get more rich and easier to make environments. The main challenge this presented however, is how the characters are represented. Since it’s a perspective camera and the 3D characters now have depth, their width on the screen would change depending on their distance to the perspective camera. The issue is that this skewing wouldn’t accurately represent where the hitboxes of moves are – and even if it’s a minor thing, precision in a fighting game is vital.

This is the part where I talked to people and did a lot of research in order to find a good solution. My characters needed to be rendered orthographically while the environment was rendered in perspective. One option, was to write my own camera projection matrix, as explored here: https://gamedev.stackexchange.com/questions/86960/mixing-perspective-and-orthographic-projections. The other option, was to render out the 3d animations into sprite sheets, so that we could have our 3d looking characters without any depth. Both seemed like fairly costly endeavors, until my graphics professor gave me the simplest solution – scale the model’s z value.

flag fuego.PNG

For all intents and purposes, these are now Fuego sprites.

So yeah, we just flattened the models – angled the camera correctly and voila! Problem solved.

Conclusion:

Our team found the game feel we really enjoyed and wanted to have with our 2D prototype. Despite it being relatively simple, people had fun – and that’s an amazing sign! During our shift to 3D, certain things felt clunky, and not as crisp and fun as it did in our 2D build. These past two weeks have been spent making the transition, and making sure our game feels just as fun as it did before. I’m happy to say that we’re pretty much there – and then some! We have a bigger environment to fight in, more moves, and I’ve also been implementing some new mechanics on the side. Right now you can currently quick rise, so you can adjust your timing when getting up in order to throw off your opponent. In the next weeks, I’m going to be focusing on the last core features like the parrying system and combo system.

After all that said is done, I’ll be polishing off mechanics and cleaning up whatever I can in order to prepare for the big presentation. I’m feeling extremely confident with our game right now. In my last post I talked about how proud I am of my team, and that definitely hasn’t changed. I feel like we’ve overcome a huge hurdle together, and I’m very excited for the future.

Gin and Rummy AI – Code Report

Standard

It’s been a while since I spoke about this, but the due date for this assignment is finally up! My AI performed better than I expected it to, so I’ll take some time to explain my AI’s general strategy. If you’re interested in this, please refer to my previous post for a solid introduction on Gin Rummy:  https://gabepereyrablog.wordpress.com/2017/09/26/gin-and-rummy-ai-planning/

Approach:

I ended up using the value based system I discussed in my introduction post. The bulk of my AI took place in valuing each card I had in my hand. I first started by keeping a reference of the each card I currently have in my hand, while also assigning a parallel list of integers – with the purpose of storing a card’s value. The first step was to determine my current hand’s score. When determining a hand’s score, you could either prioritize matches or runs. My AI prioritizes whatever method gives my hand a lower score.

I then run through all the runs and matches. Any card that is part of set or match, gets a value of one (A card I won’t be getting rid of).  A card that forms part of a match receives a value of two. Any card that is standalone receives a value of three, plus whatever the value of the card is. Long story short, a garbage card with a high value will be the first to be discarded.

Discard:

On the discard, I run my little algorithm to determine the card with the least purpose in my hand (the card with the highest value). I simply discard that card.

Draw:

For drawing cards, I “fake” drawing the discard card into my hand and see if that card can be used in my hand to bring my overall score lower. If it can be used,  then I draw that card. If all other possibilities only make my score higher, then I take a chance and draw from the deck.

Conclusion:

My AI completely obliterates the “dummy” AI we were supplied with to test against, and it seems to have been doing so-so in class. My AI has had a lot of close games with other students’ test AIs. I’ll probably go deeper into this into my post mortem, but there are two things off the top of my head that I could add to my valuing system.

The first, being that sometimes my algorithm causes my AI to hold on to two high valued cards, in an attempt to wait for that third card to come by. This is risky however, because if the opponent catches me in the state, I’ll be giving them a lot more points than I’d be wanting to. To remedy this, I’d take into account the amount of cards left in the deck, and change the value system so that higher valued cards that aren’t in a complete set are more likely to be discarded if the game has a higher chance of coming to an end soon.

The other change I’d want to make is card counting, and taking into account the possibility of drawing one last card to complete a set or run into my value system.

Capstone Blog #6 – Hype and Team Dynamics

Standard

This week was a bit varied with the tasks I had at hand – the main feature being the hype meter.

Hype

The last key wrestling mechanic to our game is the hype meter. Hype is different from your typical fighting game super meter, in that it is affected by specific, crowd pleasing in game events. Break out of a pin at the third count? You’ll get hype. Hit an opponent with a risky top rope move? You’ll get A LOT of hype. After reaching maximum hype, your character will enter Max Mode, and gain access to new attacks and abilities. I’ll go into Max Mode another day.

hype meter.png

The yellow bar on the side is hype. Yes, UI is a work in progress.

The hype events themselves are working, with designer orientated tools to customize how much hype certain events bring. Max Mode will come another day, since it’s character specific and our first full fledged character is currently under development.

Sound Effects 

I also worked on implementing a sound manager. Sounds are key to game feel, and it’s gonna be one of the things we’re going to be doubling down on in the coming weeks.

forpaul

A lot of things go into an attack in a fighting game

I took some time to expand the designers tool set to also let him customize what sound effects play during specific attack events. Sounds that happen on miss, attack, and block are all easily customizable in editor. This will help each move feel unique and have personality, while letting our designer quickly iterate on game feel. I plan to have a similar system for particle effects.

Team Dynamics

The other things I worked on this week involved a bunch of small tweaks, bug fixes, and loose ends I had tie up mechanically from weeks ago. Since none are particularly interesting, I thought I’d be a good week to jot down some thoughts about the current team dynamic.

So far I have been working extremely close with the designer. We’re always bouncing off ideas as to how to implement mechanics and we always have a ton of fun play testing the game together. I don’t think the game would be anywhere near as cohesive and put together as it is right now without me and the designer communicating constantly. It’s a good thing we get along great!

Art wise I haven’t been as close with them but I imagine that’ll change soon as the game makes its big transition to 3D models. As a programmer, I want to make sure everyone’s hard work gets represented the way it’s meant to. This applies to both design and art. On that end, I look forward to trying out shaders and such with the artists to make sure we can make the team’s artistic vision a reality. I also applaud our art team for their communication early on about the feasibility between a 2D sprite pipeline and a 3D pipeline. Without going too much into the thick of it, their input in our vital pipeline planning phase probably saved our game.

Production wise – I absolutely adore having a dedicated producer. While other teams have to juggle some roles, our team has the fortune of having someone completely dedicated to running meetings, documenting deadlines, planning ahead, and most importantly – facilitating communication. It allows me to just focus on my own tasks, and that is a huge time saver.

Conclusion

Overall, while we had our initial difficulties, I’m a huge fan of our team, and I don’t think this incredibly challenging game would be possible without everyone giving it their all. I’m proud of everyone so far and I’m sure that feeling will only grow as the weeks go on.

Although we don’t have 3D models in game to show this week, the work is well underway – and I expect next week to be the first stage of our games transformation. It’s going to be sick.

Capstone Blog #5 – Refactoring and Fighting Game Essentials

Standard

Since last week I spent a lot of time prototyping the more experimental mechanics, I spent this week getting down some of the fighting game essentials.

Pushback

Last week I had implemented push forward, where a move like a sweep will slight reposition you forward. Another key aspect is push back, which is the amount that a player gets knocked back when either blocking or hit by a move. Not only is this vital to game balance, but this also helps give a move a sense of impact. Both a move’s push back and push forward all fully customizable by the designer in the editor.

Throws

A lot of my time this week went into getting throw logic in. For those who are unfamiliar with fighting games, a throw is an attack that cannot be blocked – it’s how you put pressure on an overly defensive opponent. The catch however, is that your opponent can react to a throw by also inputting a throw – therefore “teching” it and putting both players back at a neutral position.

lucha throw.png

Got ’em.

Next to rope shenanigans, throw logic is probably the most complex mechanic I’ve had to code so far, what with all the conditions and animation states that come with it. I put in some extra time making sure it played nice with the systems I already had in place.

Meter

What’s a fighting game without supers? Well, while supers are definitely on the list, you can’t have supers in fighting game without meters!

luchameter.png

I swear the UI will look a lot cooler soon.

I spent some time this week setting up a multilayered meter system where the player can stack up to 5 supers worth of meter. I also set up the design pipeline so that our designer can tweak and fine tune just how much meter is gained when a move is hit, blocked, etc.

Refactoring

One big focus this week was refactoring a bit of code. While prototyping a lot of these mechanics so rapidly, I started realizing that I wasn’t really using inheritance to its fullest. The main issue is that the animation states were unique to the fighter sub class, so the base class had no access to it. I set this up, thinking that each character would be unique and that it wouldn’t be that big of a deal in the future. However, I found myself having to write a function specific to a subclass just to make room for that one line of code involving the animation state.

I took some hours and opted for a more universal animation state system. Where the all the states that every fighter will share are all in the same order, and any unique states will be handled at the end of the list, there by not interfering with the states that everyone is gonna use. This lets me port a lot of sub class specific code over to my base class. Just to show some numbers, my subclass line count went from around 500 to 100 after I made my changes. Though my base class line count went up quite a bit (its in the 1000 range now), it’ll definitely be a worthy investment as we add new fighters to the game. Anything that reduces my workload and the chance for character specific bugs is a plus for me.

Conclusion

When I first sat down to write this, I felt like this was a slow week. Looking back however, a lot got done! Our team is already eyeing up the next challenge, so there’s a lot more to work on, but I’m honestly extremely satisfied with the rate our team is going at. Also, we finally got our art pipeline worked out! Expect to see some cool 3D models in the game next week.

Gin and Rummy AI: Planning

Standard

My next task in my Artificial Opponents class is to construct an AI for Gin and Rummy. If you haven’t played Gin and Rummy, it’s a card game that can be a bit much to grasp at first – but gets really easy once you pick it up. For the unacquainted, you can familiarize yourself with the game’s terms and rules here: https://cardgames.io/ginrummy/

The General Plan

I plan to use a value based AI, where I construct an algorithm that sees the possible options available to it, assigns a value to them, and then proceeds to pick the option that has the highest value. Gin and Rummy has two different actions the player has to worry about – choosing whether to draw from the deck or discard pile, and choosing which card to discard.

Step 1 – Drawing

There are two main things I want to look out for in this phase. First of all, I want to check if the card in the discard pile contributes to any of my potential matches. If it does, I will most likely want to add it to my hand.

gin and rummy

That Jack might help.

However, if a lot of turns have passed, I may not want to add a card to my hand if it’s value is too high unless it fully completes a match in my hand. I’d hate to be waiting on a third jack, get knocked, and have to give up a lot of points that I could’ve discarded earlier. Keeping track of what cards have already been discarded will definitely play a part in this as well.

Step 2 – Discarding

For this step, the higher the value is, the more I want to discard the card. Any cards that are part of a match will most likely have the lowest value. Any cards that are forming part of a match will probably be somewhere in the middle, depending on how many points that card is worth (the more points a card is worth, the more dangerous it is to have in your hand).  Lastly, any cards that aren’t really contributing at all will probably have a very high value and be the first ones to be discarded. It’s worth noting that keeping track of the discard pile will probably have an effect on calculating the values of the card.

Conclusion

Gin and Rummy is a very luck based game, so writing the perfect AI for it isn’t really possible. However, I think my general plan of prioritizing matches, while keeping track of the discard pile in order to calculate the likelihood of forming a match with a particular card will hopefully get my AI a pretty decent win rate.

 

 

Capstone Blog #4 – Top Ropes and Bouncing

Standard

The Situation

At the beginning of the week out team challenged in order to get our Lucha game proposal through, and we mostly passed. We got permission to solely work on our fighting game, with the caveat that we present again next week. Our teacher requested that in our next prototype we show more mechanics that make our game unique – so my challenge this week was trying to balance implementing core fighting game mechanics, while also prototyping our wrestling themes mechanics like top rope attacks and rope bouncing.

Rope Mechanics

The Lucha Mechanics we prototyped all involved the rope. On top of all the normal fighting game character states I have to worry about, an additional state is the rope bounce state.

lucha bounce

Look at how smug he is.

From here there are two different possibilities. The player can either run the opposite direction of the rope, causing the player to bounce off and run even faster than he was before. The more consecutive ropes you bounce off of, the faster the player runs. These values are all modifiable by the designer in the editor.

If the player instead continues to hold back into the rope, they will proceed to mount the rope after a certain amount of time – putting them in a threatening top rope state!

lucha top rope.pngPlayer 2 better be careful!

From this state, the player can jump off the rope and attack – executing a special top rope maneuver. For now, it’s just an attack with extra damage – but the logic is there to later add special properties to the move as the design evolves.

Animation State Machine Hell

As you can imagine, fighting games have A LOT of different gameplay states an animations. The Unity animation state machine I was making was quickly spiraling out of control. I spent some extra time cleaning up the machine and adding sub states to better organize things.

animation tree.png

It’s a lot, but manageable.

As you can see, the different sub states consist of game states like “crouching”, “top rope”, and others. These all have their own spider webs which consist of the animation states in Lucha Megadrive. This also helps organize transitions so that characters don’t freak out into states they shouldn’t be.

Conclusion

Besides the things I mentioned, I added in a lot of core fighting game functionality this week too. Things like counter hit logic, normal jumping attacks, crouching attacks, and running. It’s been a lot of hard work but I think the current prototype’s state will better demonstrate how our game will differ from other fighting games in the market right now.

Minesweeper AI – Postmortem

Standard

Well the testing day for our Minesweeper AIs came and went, and my AI pretty much performed as expected.

Results:

While I lacked the time to make AI compete with the class’s top contenders, its solid win rate of 60-70% on small games and its occasional triumph of medium sized games allowed it to pass class specifications.

Last Minute Optimizations:

I made two last minute optimizations, one that really sped up AI thinking time on larger boards, and one that bumped my win rate a bit.

If you remember from my planning post, I had two phases in which I scan the grid for revealed cells for mine counts, and attempt to use surrounding data in order to mark mines and reveal cells that are guaranteed to be safe. Originally, I just looped through each cell ever update. As you can imagine, this would start to take quite a while on larger boards. The optimization was to have a different lists to loop for for both steps. On start up, this list of cells consists of the whole grid, but if a cell has already been used for data, is empty, or contains mine, we prune it from the list. This really helped increase the speed of the algorithm on medium and large boards.

The second optimization was pretty straightforward. As I mentioned before, if there are no safe cells found after the algorithm runs, my AI just picks a random cell. The change I made was when I pick a random cell, instead of just using the whole grid, it forms  a list of what random cells are safe to pick. In short I only pick cells that haven’t been picked yet (to save time) and cells that are definitely not mines.

In an Ideal World

I feel like the main thing my algorithm was missing was some sort of pattern recognition or “tank” solving algorithm, as I mentioned in my last post. Having a second, more intensive algorithm to fall back on would’ve really helped my AI in harder difficulties. I detailed the tank algorithm I would’ve used in my last post.

Conclusion:

I wish I could’ve put some more love and care into it, but at the end of the day I’m pretty satisfied with what my AI was able to do. I’m looking forward to the next assignment – Gin and Rummy.

Capstone Blog #3 – Pipeline Changes and Pinning

Standard

As the third week comes to a close, my team finds itself heavily leaning towards making the Luchador Themed fighting game I’ve been going on about in my previous blog posts. However, all our excitement for the game is accompanied with some headaches as well.

Future Pipeline Changes

Our art team went and got some advice from faculty and came to the conclusion that we weren’t going to go with 2D sprites for our fighters, but with 3D models instead. This significant change put a bit of a wrench in the pipelines I had set up – but hey, that’s game development!

What was mainly affected by the change was the design pipeline for editing collision boxes. With sprites, the designer could simply switch the active sprite to the desired keyframe and tweak boxes from there. However, with complex 3D character animations in Unity – you can’t just bring the character to a desired frame in the editor. I did some research and everything should be fine as long as I develop a tool that allows the playing of said animations in editor mode to a specific frame. It shouldn’t be too big of a hurdle but that’s the only foreseeable change I can see for now.

Pinning

Since our prototype hit QA for the first time this week, our team decided to put less time towards progressing traditional fighting game mechanics (counter hits, grabs, jump attack logic, etc) in order to prototype a mechanic unique to our game – pinning. Unlike a normal fighting game, you don’t win by reducing your opponent’s health to zero, you win by pinning them. Every time you knock down your enemy (by specific moves or by depleting their health) you gain an opportunity to pin them – in which a pin mini game starts to see if they can break out or not.

pinning

In typical wrestling fashion – get a 3 count and you win!

The red bar moves back and forth as the player being pinned attempts to break out by stopping the bar in the safezone. The size of the safezone correlates with the amount of health you have when you’re pinned (in this case, it’s a pin off a KO so it’s very small in the picture), and the speed of the bar is determined by how many knockdowns you’ve accumulated.

This is the first of our unique Lucha themed mechanics that we wanna implement – and we feel like this is one of the most vital mechanics to represent how our game will put a fun twist on the typical fighting game formula.

Conclusion

It’s been a fun but stressful week – but the feedback to the pinning twist on our fighter was pretty positive, and people look forward to seeing how it would play out when more in depth fighting game mechanics are added. Besides the pinning minigame, I added knockdown properties this week, crouching, and blocking. I hope to spend this next week fleshing out more fundamental fighting game building blocks, like jump attacks, crouch attacks, counter hits, and hopefully throws!

Minesweeper AI – Code Report

Standard

Just a bit of a warning, my other capstone project hit me pretty hard this week, so I didn’t get to do all that I really wanted to for my minesweeper AI – but here goes.

The Approach

The approach I ended up implementing was pretty much exactly what I detailed in my previous blog post.

My implementation consisted of one new class, Mr Robato. Mr Robato’s main purpose is to run an update loop at every PICK_CELL event and returns an index for the game to reaveal. This update loop goes through three main steps at the moment.

  1. Pick a random cell. Gotta start the game somehow.
  2. Go through the grid, find a revealed cell with mines nearby. See if we can 100% mark off a mine using this info.
  3. Go through the grid and find a revealed cell with mines nearby (again). At this point, we used the info we gained in step 2 to see if we can ensure that other cells around our chosen cell are safe for sure. If they are, stick them in the clickQueue.

Mr. Robato’s update loop structure starts by checking if the “toClick” queue is empty. If it’s not, then we pop the queue and return the index to be revealed (thanks step 3!) If it is empty however, we go through the steps listed above.

The Flaw

What really hurts with development is when you know there’s something wrong but you simply don’t have the time to fix it (at least right now). The main flaw is that if we finish step 3 and the board conditions simply do not let us populate our toClick queue, then we just revert to step 1 – which is go random (I’m sorry).

If I had more time to work on this, I would’ve really liked to implement something along the lines of the “tank” algorithm mentioned in this blog post: https://luckytoilet.wordpress.com/2012/12/23/2125/

The general gist is that it’d be a backup plan that isolated a part of the gameboard – the smaller the better. From here, it would generate every possible configuration for mine places. Then it would cross reference the configurations to either isolate a safe zone or choose a cell with the least chance of having a mine.

It’s not all Doom and Gloom

While my AI may not be perfect right now it does in fact have the capability to win minesweeper. To be honest, the win rate isn’t very high for large and medium game boards, but for the small ones I’d say it’s pretty respectable:

mineOutput

Here’s the console output for 10 games

Out of this batch, my AI won 7 out of 10 games on the small game board. Overall, throughout all my testing the win rate has been about 50/50.

Another thing to mention is that while it does struggle to win the higher difficulties – it definitely makes progress with them, and in some cases comes pretty close to winning. From what I can see, implementing that final step I mentioned is probably the last push the AI needs to start competing in higher difficulties and beyond.

Besides that, there are some minor optimizations I can make before the class competition on Friday that will hopefully improve my AI’s speed. Overall I think it’ll be passable – I’ll post an update with my AI’s performance and any last minute modifications I made at a later date.

 

Capstone Blog #2 – Pipelines and Prototyping

Standard

Planning Ahead

So the team decided to move forward with the three concepts I discussed last week. Out of all them, we thought that the Luchador themed fighting game would be the hardest one to conceptualize and prove – so I spent pretty much all my time on that prototype, while our designer handled the other two.

Out of the many challenges that come with developing a fighting game, our team singled out perhaps the most crucial of issues to get out of the way early – solid production pipelines.

Since our game is most likely going to be 2D, for now the art pipeline will be ensuring that our artists get all of their animations nice and packed in a sprite sheet and put in the project. Since fighting games are so frame dependent on their game play logic and balance, a lot of the process I worked on was geared towards our designer.

The Problems

The two main issues are that fighting games are extremely animation intensive, and there are several bits of game play logic that are specific to frames in that animation. The other issue is that a character in a fighting game has many moves to choose from, and each and every one of these moves has different hurtboxes and hitboxes. My goal was to make a smooth and easy pipeline so that my designer could tweak and balance on the fly – without ever having to touch a line of code.

The Design Pipeline

As time is crucial and limited in Capstone, my solution was to work with the engine (Unity) as well as I could to streamline the whole process.

animationtimeline

For getting animations in and having different hitboxes become active depending on the frame of the animation, I decided the most cost effective way was to work with Unity’s built in animation tools. In the picture above, the diamonds represent different keyframes, which our designer will place in from the spritesheets our artists provide. The little white ticks on the timeline represent animation events, our designer simply has to line up these animation events to the keyframes that corresponds with a move’s startup, active, and cooldown frames. From then on, he can just select the functions that I’ve already coded, and work universally for each move. With this method, I don’t have to spend time making our own animation tool, and our designer can easily tweak moves frame by frame if he sees fit.

In terms of collision boxes, the solution is a little less elegant – but it works!

collisionmoves.png

Please excuse the programmer art…

So as you can see to the left in the object hierarchy, the player has several child objects that share the same names as the moves that are defined on the right. These child objects simply hold collision boxes. Upon loading the scene, the fighter object cross references its list of moves along with the names of the child objects it has in order to make a dictionary of collision boxes and moves.

From here on out, whenever a move is executed, the program finds the name of the move that was executed, and uses that name as a key in order to seamlessly change the collision boxes of the player. Once a move is complete, the player goes back to using the default “Idle” hit boxes. With this method, as long the names of the child objects and the moves are the same, the designer can easily dive in and tweak collision boxes on the fly as well.

Conclusion

With these pipelines set up, I feel much more comfortable about proving the feasibility of this game. As long as animations are coming in – I can work on implementing new mechanics and polish while our designer tweaks and balances the game. Despite the huge challenge ahead if we decide to go with this, I truly believe my team is up to the task.

Other things I did this week is do basic prototype-y stuff, like win states, getting collision and damage to register, and so forth. Next week I’ll probably be putting the finishing touches on our initial prototype, and I’ll be diving into how that went then.