GrandMaster is a mix between a merchant management game, and a boss fight action game. The player takes on the role of the Grandmaster, a semi-retired monster hunter who has decided to settle down and open a shop. However, there are beasts in the world that still need to be slain, and some of them are so dangerous, that only the GrandMaster can deal with them. So there are times where he must leave the shop in order to fight these bosses in a top down arena. Winning the fight gets valuable treasure that can be sold in the shop. Losing just wastes time.Time otherwise that could’ve been spent getting more coin before the tax collector shows up.
Gameplay Programmer, Lead Programmer
Twelve (3 programmers, 5 designers, 3 artists, 1 producer)
August 2016- November 2017
Unreal Engine 4, HG repository.
Brief on the Project
On the project, I worked from its concept phase working as a programmer, creating multiple prototypes in order to test different mechanics. During the project there were cuts to other teams, ours was not one of them. Because of this I was able to add two more programmer’s to help work on the project. From that point on, I worked not only as a programmer, but spent extra time working as the programming lead. From there tasks were split between the three of us, and that allowed us to focus more in specific aspects of the game. With myself taking the heading on the main shop screen the adventurer system, player character, and any work that it would take to make sure that everyone’s work combined and worked together correctly.
Tasks and Responsibilities:
I built the groundwork that would be used for the rest of the project, especially when it came to the shop and the basic idea of one of the feature we have the “Adventurer Management” system.
The shop works on the fact that Unreal treats the player character like a singleton, it can be referenced anywhere and then casted into the player management class that I made for it. So I broke different parts of the shop into management systems. For example, having a customer manager, a calendar manager, item manager, map manager etc. Each of these work independently of each other, while having the player character being the meeting point between them, and progressing or changing the game based on the information from each of these managers.
Worked on Main shop experience
Worked on the Adventurer manager sub system
Player controls and system for top-down experience.
Worked on the first boss implimentation
Animation implementation for bosses, player character, and customers.
Managed and directed a team of programmers as team lead.
An example of this would be how customers are handled. All the player is doing when they want to call a customer to their table, is call the customer manager to give them a customer to work with. All of the other information about it is managed through the customer manager itself, that being customer wants, personality, appearance, amount of money, etc.. But there are cases where it needs information about the date and time in order to spawn something specific. So the customer manager then uses the player character to get access to the calendar manager that can return these values. This information is then given to the customer manager, it changes what it needs to based on this information. Laster in development some of this information is given instead directly to the customer that is being spawned itself, here the “brain” (a large C++ class created by another programmer, that dealt with giving the customer the correct dialogue, as well as personality) would deal with setting and giving the customer the correct stats.
Another manager that is being worked with here is the Adventurer manager, which is just the core of the Adverenturer system that we have in place. This is just a fancy name for a subset of the game where the player can send out adventurers-in-training on quests in order to bring back useful items that can be sold in the shop. The adventurer manager mostly handles taking in input from the player from the menus, and performing specific actions to the adventurers that it holds. For equipping items it’s pretty straight forward, give the adventurer that is represented in the ui increases to success change based on what items the player gives them. However for quests, that goes through a quest manager that deals with quests, their loaded in name, description, and possible item rewards. The quest manager gives three random quests every time the calendar moves forward a day (through the player singleton of course), and when the player selects it as the quest they want to send the adventurer on, the manager determines success and rewards.
First Boss Implementation:
I also worked on making the first boss for the game, the giant lava worm. It was a super basic first boss that was more pattern based then it was AI based. There are points that are on the map (placed by designers) and the worm moves to these points by burrowing. In order for the burrowing to not be annoying to the player, along the path it breaches the surface allowing the player to hit it. This is done by placing actors another the path that have damage tied to the main boss. These actors also shoot out a ring that damages the player, which is where the main challenge comes into play. It continues this pattern until it is slain, or the player loses.
Speaking of the worm, I also working on the animation implementation for all the characters within the game as well, except for the second boss, the troll. Working with Unreal’s animation state machine, I was able to create states, and state transitions that were based off of getting information from the character that the animation was tied to. For example, using the booleans I had set up for the worm in order to know when to go underground. I used these to create the states of idle, burrowing, and burrowed, as well as the emerge state for the actor spawned along the path. Once the main worm actor reached the end of it’s path, it played an final emerge animation, and once that state was finished, it switches back to idle.
The customers were a bit harder however. We didn’t have enough time to make a ton of unique customers, so I did some research and came up with an idea. If we were able to break apart each customer that we had into separate meshes, we would be able to use each part in creating a more diverse pool of customers. So I had the animator break up the skeletal meshes for each of the customer, while keeping the entire skeleton intact. That way, even though I just have a torso(for example), it would align with the rest of the bones. I did this for each of the parts, and had them follow the same animation state machine, that way they were in sync with each other. Which animations played were then determined by the character itself (through the manager), that way every single part would know which animation set to be playing at a given time. If it was random each time (like the “no” the customer gives on deal rejection) then it was dealt with by the customer itself.
Player Character and Animations:
The player character and it’s animation set was another task that I had. The basic top down character used the mouse to determine rotation, used WASD to move around the map, and was able to press space to dash in the direction they were moving. The camera was a fixed height above the player, and did not rotated, which allowed for WASD to be intuitive(W was always up, A was always left etc, etc.) The player uses LMB to quick attack, which spawns a very brief hitbox in front of the player in order to deal damage to the bosses they fight (intersection of the hitbox means damage for the enemy). RMB was the heavy attack, which the player could not move or perform any action while they were in the heavy attack. This spawned a large hitbox that deals more damage, and locked the rotation into where they were looking when they pressed the attack button. When the player loses, they black out and the level transitions back to the shop, if they win, they have items added to their inventory, and after 10 seconds are transported back to the shop screen.
Setting up the animations were not as straightforward as the worm, given that the player can dash in any direction, and their rotation was determined by mouse. So I was given 4 animations to work with, a dash in each of the cardinal directions. The difficulty came in the fact that any of the four input keys, WASD, pressed with space can dash in any direction based on character rotation because of the locked rotation camera. I tried using the mouse’s X,Y position to create a giant check of where it was, and which animation to play determined by it. However, it became apparent that I could just use the player rotation (being affected already by mouse position) to create a list of what animation to used based on number. So for example, if the rotation around the Z axis was within X and X amount, modify the list held within to reflect what animations needs to play. The list was an array of 4 ints, each one corresponding to WASD, and the int was the animation to play of the 4 dash animations I had.
The attack animation implementation was pretty straightforward comparatively. The heavy was simple enough because of fact that input is disabled during. The light attack had two animations(for swing right, and for swing left), and some extra code was needed within the player character in order to determine with light attack animation to play. If played within a certain about of time after the first, play the second, if not, run first again. This time was attacked to the animation itself in an event, so it was easy to create a looping quick attack of a back and forth.
Programming Team Lead:
Worked also as the programmer team lead, which meant that I spent extra time creating sprint plans every two weeks, and running the check-ins every week to see if we were still on target for our deadline. Constant communication allowed for rapid reevaluating of sprint goals, which helped give the programming team a good idea of how much would be able to get done by when. I also communicated to the rest of the team the current state of the project from a programmatic angle, as well as giving estimates in time for features, and being direct if something was out of scope. Also enforced scrum meetings with my programmers, if not everyday, then every other day in order to keep each of us informed.
Small other bits of Programming:
Since I was the one who set up some of the code base for the project, when the team was expended, I worked on the integrations of the other programmers’ code into the main project. Like changes to the second boss fight, and making sure it behaved correctly, and making sure that the customer system utilised the new customer “brain” code effectively. Also I deal with managing how and what data is saved for level transitions, what needs to be saved and loaded from each part, like time, items, adventurer status, etc.