Level Pacing Pirates

Summary

In this blog I will be talking about what our group has done to pace the game and make it flow for players. I will start off by define which each segment there  is and what it does. This will be followed by where it is in the game and what we where trying to guide the player to do.

Game

The game for this prototype assignment is also our GDW game. This allowed us to kill two birds with one stone and add some interesting features to the game. In order to get the readers up to speed if they haven’t had a chance to check out are blog and personal profile pages. The game is a 3rd/1st person role-playing game. The game is based around the pirate era and old school myths of the titans. For example the Kraken. Travel from place to place with you ship, and complete quest/objectives for rewards.

In order to start the game, in the menu screen click on the green bottle and it will load the correct level. Then pressing 2 to go into third person view. The basic controls of the game is WASD for movement, R is for picking up objects, X is dodge, B is block, and F for attack. 1 and 2 on the keyboard is switching cameras views, 1 cinematic and 2 third person. The camera movements is done through moving the mouse and if right mouse button is held or clicked it will make the camera center behind the player.

Objective

The player must explore the island and complete both quest to win. Since our game is still rough and will be finalized in the coming week for all the game play, we make the player learn what they have to do based of video game past knowledge.

Customization

The game right now allows the user to pick up different types of weapons. The player can choose what weapon they want to use by pressing C to cycle through them.

Bounce

Bounce sends players back into your level in order to get something to remove an obstacle that is halting progression. Resident Evil for PlayStation 1 is a major fan of this tactic. They make many locked doors forcing you to go back into the level and find a key/code/switch in order to unlock it. The bounce in our game is when you have to get a quest item which is behind a locked door. The key lies on a mountain side which you must get to open the door to get the quest item.

Bottleneck

A bottleneck forces a player into a tight area with tons of conflict and combat which forces them to go through this area. It should bring a sense of sensation to the player after completing this and while completing this. In our game the bottleneck is almost right off at the start. The player must go up a cliff side following a path. In order to get them started we force them into combat right at the bottom of the hill and no way else to get past. After this battle you feel empowered and ready for the next fight.

Sticky Areas

Finally sticky areas doesn’t force the player to them, they just tend to come here more often than anywhere else. There is usually a couple different types of sticky areas: one being a safe area, and a competitive area that has unique rewards which again draws you there. A good example is World of Warcraft the first one is the home cities because they have all the trainers, shops, and is a safer area. The second one for World of Warcraft would be the daily areas that draw you to do them in order to get gold and special tokens. The sticky areas in the game are the enemy camps and the beach at the beginning. The things drawing players there is on the beach safe sticky area, this is where you get a quest and also an item from the quest giver. The camps have items that you can pick up, but one is only mandatory for a quest making you want to go to the other camps to see what you can get.

Game Design Overview – PIRATES

Hello!

The changes in Game Development Workshop have resulted in more strict guidelines as to the type of game you can do as well as the requirements needed to fulfill making the game. Fortunately it hasn’t affected our plans too much and we’ve been able to keep a lot of the features we wanted to implement in the game. To start off, here is a Game Design overview of our game.

Please note that a lot of features here may change such as gameplay elements and stories due to time or scope limitations. This post will be updated in the future or a new post will be added when details are finalized.

Introduction

The sea is yours to sail and discover as Captain of a pirate ship.  Battle other pirates and mythical creatures on land or sea, in action packed combat or ship to ship combat. Unravel a plot to raise ancient powers from the depths that threaten control of the seas around the globe.

Key Features

  • Swashbuckling combat with swords and guns
  • Fast paced, strategic ship to ship combat
  • Board other pirate ships and take their crew
  • Explore the seven seas on a your mighty pirate ship and visit exotic locales
  • Manage your crew to make them stronger to help you command  the ship and fight in battles
  • Upgrade your ship and weapons to fit your playstyle

Genre : Third person action adventure (PIRATES)

Platform: PC (with Xbox 360 controller)

In depth with the system

Exploration

You play as Ashara, Captain of a pirate ship (name of ship to be determined) and sail the seas with a crew of other pirates. The game takes place in an overworld where you get to decide where to sail your ship. There will be numerous ports and key locations where story will progress but there will also be a variety of other islands that contain loot and enemies to fight.

Ship as a Hub

In the sea, the ship is your hub where you can interact with crewmates onboard and find out more about their personalities and stories.  You can also partake in minigames with crewmates. At any time you can take the helm of the ship to sail towards land or further in sea. There is a chance you can run into other pirate ships that may try to board you vessel and attack you.

Ship to Ship Combat

This begins our ship to ship combat system. It will be a balance between positioning your ship with the wind and firing the cannons on the sides of your ships. (However this combat system has not been fully decided yet. It will most likely use the cannons on ship which can be upgrade). During ship to ship combat, you can also be boarded by the other pirates or you can board their ship. This will transfer over to our close combat system

Close Combat

Close combat will be our most refined combat system and will draw inspiration from games such as Devil May Cry and Kingdom Hearts. You will be able to use a light attack and heavy attack, which in combination can be used to perform combos. A ranged attack using your gun (pistol) can be used for long range attacks as well as timed into combos.  You will also be able to dodge attacks as well as use blocking to deflect and parry an opponent’s moves. Further details about the combat system are still being worked out.

Town, Resource System and Upgrades

In the pirate game you will be able to obtain a variety of resources that will important to juggle to get the most benefit in the game. These can all be used in town which will be your main hub besides your ship. You can get the following resources, food, wood, metal and RUM.

Food is used to feed your crew so having an ample supply of food will keep their moral and strength up. This will affect their ability to help you in both ship to ship and close combat. Different foods will also provide different benefits, such as high protein giving more attack but less health, high carbohydrate foods giving more health but less attack, sugary foods giving more speed, etc.

Wood will be used primarily for upgrading your ship and weapons in port towns. Wood is needed more so for ship upgrades but are sometimes needed for weapons as well. Ship upgrades include increasing sailing speed, upgrading the hull to withstand cannon fire, and upgrading your cannons for more damage.

Metal is used primarily for upgrading weapons and your ship in port towns. Weapons upgrades can increase the damage of the weapons and speed.

Rum is not used for upgrading but for aiding in combat instead. Rum can be consumed before or even during battle (This takes a several seconds though) and will provide temporary bonuses to your character. This includes healing, increasing health, increasing damage, and increasing speed.

Outro

All of these systems are subject to change but these are some of the core ideas we plan to use. The ideas will be iterative and be subject to testing and change to gauge their usefulness and overall contribution to the game. The goal is to make this a fun piratey game and any aspects that detract from that will be changed or removed by the end.

This is Scorching South Studios, signing out.

Beginning of Third Year

Ultimate Gladiator Coliseum was a success last semester and a daunting feat to accomplish. This year however there have been changes to the structure of GDW as well as changes to the core team itself. Our team has been split up, with Tyler, Aaron and Mike moving to other groups while Naeem, Fernando (Branden) and Kevin remain in Scorching South Studios. To fill the gap, two new teammates have been brought on board. Branan Sarveswaran, David Yue and temporary contractor Agatha Lee.

Our group has already begun the planning process and we’ve come up with a number of ideas which will be posted soon enough detailing our game concept and such. Stay tuned!

UGC – In-Depth Technical Documentation

In this section, we will highlight most of our game design mechanics and how we managed to code them to work in game. This is fairly in depth breakdown, so get ready to see a lot of code.

Player & Object basics

Entities (Players and Enemies)

Entities represent all objects, including player, enemies, environment objects, etc. All entities have the following variables, so not all of them use these.

//Variables for character entities

float health, maxHealth, stamina, maxStamina;

float damage1, damage2;

Some entities such as backgrounds won’t need these, while Enemies and players all use these all the time. Things to note here are health, stamina and damage our player’s main attributes.

bool hasSpear; //has a spear!

This variable is used only by the player, but it represents whether he has a spear or not and if he can throw it.

Main Character picking up his spear.

CurrentAnimState

This is a part of any Entity, it essentially holds all physics, including force, acceleration, velocity and position. This also contains the radius of the object which is used to handle hit boxes and collisions.

//Variables

Vector3f position, velocity, accel, linearForce, torque, angularVelocity;

float mass;

Vector3f initialPosition;

float maxVel, maxVelNeg;

float maxAccel, maxAccelNeg;

bool isMoving;

bool hasCollided;

int animType;

float radius;

If I set radius to 0, then the object cannot be collided with. This is used for any background objects we don’t want anything colliding with.

Collision Detection

We need collision detection in order to see whether our objects (players and enemies)will hit each other.

//COLLISIONS

bool Level::collisionDetection(Entity e1, Entity e2)

{

Vector3f d;

d = e1.currentAnimState->position – e2.currentAnimState->position;

float dist = d.magnitude();

if(e1.currentAnimState->radius > 0 && e2.currentAnimState->radius > 0) //Do not do any detection if one of the entities has no radius

{

if((e1.entityStatus == STATUS_PLAYER && e2.entityStatus == STATUS_PLAYER_WEAPON) || (e1.entityStatus == STATUS_PLAYER_WEAPON && e2.entityStatus == STATUS_PLAYER)) //Make sure that a player’s weapon does not collide with himself

{

return false;

}

//Returns true if within radius of target

float sumRadius = e1.currentAnimState->radius + e2.currentAnimState->radius;

if(dist < sumRadius)

{

return true;

}

else

{

return false;

}

}

else

{

return false;

}

}

Collisions are detected using spheres and radius. Every entity has a radius and so they check if they radius overlap. If they do it will register that they collided, which leads to…

Collision Response

This is where we do the calculations that follow a collision detection. We will do calculations such as, if the player hits the enemy, what happens? Well it would be something like, take the Enemy Entity’s health and subtract it by the player entity’s damage.

void Level::collisionCharacters(Entity &e1, Entity &e2, float totalTime)

{

//Player attacking Enemy

if((e1.entityStatus == STATUS_PLAYER_WEAPON || e1.entityStatus == STATUS_PLAYER_WEAPON_SPEAR) && e2.entityStatus == STATUS_ENEMY)

{

if (e2.health == e2.maxHealth) //Update HUD

{

levelUpdHealth = 1*((e2.health)/100);

}

e2.health -= e1.damage1; //Take away health based on damage of player

if(e1.entityStatus == STATUS_PLAYER_WEAPON_SPEAR && e1.currentAnimState->velocity.magnitude() <= 0.1) //Make sure spears can’t hurt people if not moving

{

e2.health += e1.damage1;

}

}

}

In this code, we essentially compare two entities. Depending on the types of entities, if it’s a player weapon hitting an enemy, then it will calculate the enemy losing health based on the damage stored in the player entity. Every other calculation in this function does the same thing, compares two entities and does calculation based on inherit values in Entities.

Player Actions

Control menu in from Main Menu

All players need actions and in our game we defined several types of actions. Movement, attacking, power attack, spear throw, running, etc. To handle these, we use openGL’s ability to handle key input and mouse input.

Mouse Movement

In UGC, we use a mouse based camera, just like a FPS or Third person Shooter like Skyrim. To do this, we used our mouse, keeping it forced into the middle of the screen. Whenever we would move it in any direction, we would calculate where exactly we moved it. This then calculated a vector that would be translated to the character, who would then turn as well.

This code example is just one direction of moving the mouse, being the movement to the right.

if (input.lastX < input.currentX)

{

currentLevel->entityList[0]->rotate(input.azmith, 0, 0); //Rotate the player character

for(int i = 0; i < currentLevel->cameraList.size(); i++)

{

currentLevel->cameraList.at(i)->xRot = input.azmith  -90; //Update all cameras

}

input.azmith = input.azmith – ((input.currentX-input.lastX)/MOUSE_SENSITIVITY_X); //Allows camera to move based on how fast you move the mouse

glutWarpPointer(input.lastX, input.lastY);

}

Movement

This corresponds to our WASD movement. It’s pretty simple, we just calculate our direction then move forward, backwards or sideways.

if(keyStates[‘w’] == true) //Movement forwards

{

currentLevel->entityList[0]->currentAnimState->isMoving = 1;

controlCalculationsFB();

//Moves player forwards depending on current angle of rotation

currentLevel->entityList[0]->currentAnimState->velocity += Vector3f(-unitX*PLAYER_ACCEL, 0, -unitZ*PLAYER_ACCEL); //Increase acceleration along calculated axis

}

}

This is for movement, our other movement keys are essentially the same except for a change in direction.

Running

Running is one of your abilities that drains your stamina. What this does is it will change what your max speed is and then also be draining stamina every second. We also prevent you from running if you don’t have enough stamina

if (keyStates[32] == true) //Space bar (Running)

{

//Allows player to run, increasing their speed for as long as their stamina is there.

if(currentLevel->entityList[0]->stamina >5.0)

{

//Changes your max velocity

currentLevel->entityList[0]->currentAnimState->maxVel = PLAYER_MAX_SPEED_RUN;

if(keyStates[‘w’] == true || keyStates[‘a’] == true || keyStates[‘s’] == true || keyStates[‘d’] == true)

{

//Take away stamina from player

currentLevel->entityList[0]->stamina -= PLAYER_STAMINA_DRAIN;

}

}

}

 

Running Through Forrest

Attacking, Spear throw and Blocking

if (currentLevel->entityList[0]->hasSpear == true)

{

currentLevel->entityList[0]->myAnimation->animType = ANIM_THROW;

currentLevel->entityList[0]->myAnimation->animFinished = false;

}

Essentially, when we call the attack, spear throw or blocking key, all we do is change the animation. We do this because we don’t want the animation being able to cancel out. We use a variable called animFinished to prevent this, where as in movement you didn’t see this. When it triggers the animation, our game also updates and checks for what animation is being played. Which leads to the following…

 

Attacking

//ATTACKING

if(currentLevel->entityList[0]->myAnimation->sourceModelNum == 8)

{

//Set invisible hitbox position

currentLevel->entityList[1]->currentAnimState->position = currentLevel->entityList[0]->currentAnimState->position + Vector3f(-unitX, 0, -unitZ);

}

else

{

currentLevel->entityList[1]->currentAnimState->position = Vector3f(75,0,0); //Sets invisible player position hitbox far away

}

if(currentLevel->entityList[0]->myAnimation->sourceModelNum == 11)

{

currentLevel->entityList[0]->myAnimation->animFinished = true;

}

If we detect the player is on the right animation, then here, for attacking, we spawn an invisible hitbox that acts as the player’s attack. This hitbox can only hurt enemies and only spawns for a limited time at a specific point in the player’s animation. After that it will teleport elsewhere for future use. Also the animation will end, allowing the player to finally trigger another animation to attack. This prevents spamming your attack button over and over and you are able to play the entire animation. The power attack uses this same idea.

 

Blocking

       //BLOCKING

if(currentLevel->entityList[0]->myAnimation->sourceModelNum == 12)

{

currentLevel->entityList[0]->entityStatus = STATUS_PLAYER_BLOCK;

}

else if( currentLevel->entityList[0]->myAnimation->sourceModelNum == 13)

{

currentLevel->entityList[0]->myAnimation->animFinished = true;

}

else

{

currentLevel->entityList[0]->entityStatus = STATUS_PLAYER;

}

For the blocking animation, the player sets their status to a different type of player. This type of player is one that takes no damage from enemy attacks (when checked in collision response). This keeps triggering for as long as you hold up the block button and you will revert to a normal player after. In the collision response, it will also take away the entity’s stamina every time an enemy hits you.

Spear

       //SPEAR – GAN

if(currentLevel->entityList[0]->myAnimation->sourceModelNum == 14)

{

controlCalculationsFB();

currentLevel->entityList[2]->currentAnimState->position = currentLevel->entityList[0]->currentAnimState->position + Vector3f(-unitX*2, 0, -unitZ*2);

currentLevel->entityList[2]->currentAnimState->linearForce = Vector3f(-unitX*1000, 0, -unitZ*1000);

currentLevel->entityList[0]->hasSpear = false;

currentLevel->entityList[2]->rotate(currentLevel->entityList[0]->currentAnimState->angleX,0,0); //Rotate the spear

}

else if(currentLevel->entityList[0]->myAnimation->sourceModelNum == 15)

{

currentLevel->entityList[0]->myAnimation->animFinished = true;

}

 

Spear Throw

This is similar to the player attack, where you will spawn a spear in front. It is also given a velocity to move. However it will not teleport like the player weapon entity, and will remain in position where it stopped to be picked up. Also the spear is no longer in player possession so you can’t throw another.

In terms of collision response for the spear, using our formula from up above, the only thing that the spear does when it touches a player is teleports off screen and then set’s the player to have a spear once again. Very simple.

e1.hasSpear = true;

e2.currentAnimState->position = Vector3f(90, -15, 0);

e2.collisionTime = totalTime; //Save the time it collided, which will in turn prevent damage until set intervals of time

Power attack / Spin Attack

//Power attack animation

if(currentLevel->entityList[0]->myAnimation->sourceModelNum == 16)

{

if(currentLevel->entityList[0]->stamina >PLAYER_STAMINA_POW_DRAIN)

{

// This is drain per frame

currentLevel->entityList[0]->stamina -= PLAYER_STAMINA_POW_DRAIN;

controlCalculationsFB();

// set the weapon entity position

currentLevel->entityList[1]->currentAnimState->position = currentLevel->entityList[0]->currentAnimState->position + Vector3f(-unitX, 0, -unitZ);

//Update the weapon entity to have the same damage as the player

currentLevel->entityList[1]->damage1 = currentLevel->entityList[0]->damage1 * PLAYER_POW_ATK_MULT;

}

else

{

currentLevel->entityList[0]->myAnimation->animFinished = true;

}

}

For spin attacks, it is similar to attack but calls upon only one frame for animation. When this animation is triggered, it changes your rotation and therefore which direction you’re facing. The “controlCalculationsFB” function tracks where you are facing, and so it will put the weapon entity right in front of you. This is how the character is able to do a proper spin attack.

Super Spin Attack

Enemy Behaviours

Enemy entities are different than normal entities. They are the only ones given proper “behaviours”, whereas the others are given behaviours that essentially don’t do anything. What a “Behaviour” class is, is a class that essentially modifies and updates the “currentAnimState” that entities possess. In normal terms, I mean to say that it will effect their physics, so their position, velocity and acceleration, in essence it will move them. All of the behaviours have different properties, for example here is the seek behaviour

Seek and Flee

seekBehaviour::seekBehaviour(Vector3f target, float radiusT)

{

targetPos = target;

radiusDist = radiusT;

behaviourType = BEH_SEEK;

}

In it’s creation our seek behaviour is given a targetPosition and radius. The target position is it’s destination and the radius is a number that calculates that they should slow down on arriving to a location

void seekBehaviour::Apply(AnimationState *animState, float deltaTime)

{

if(activeB == true)

{

//Compute the force vector to get to the current goal

//Compute the distance between the current position and the current goal

Vector3f steer;

Vector3f desired;

desired = targetPos-animState->position;

//Rotate object appropriately

Vector3f unitDesired = desired; //Vectors to determine angle to rotate seeking object to target

unitDesired.normalize();

float angleXI = acos(-unitDesired.x) * 180/3.14; //Conversion from Radians to degrees

if(unitDesired.z < 0)

{

angleXI *= -1; //Flip degree value to maintain full 360 rotation accurately

}

animState->rotate(angleXI,0,0);

float dist = desired.magnitude();

//As long as you have not reached the destination

if(dist > 0)

{

//desired.normalize(); //Multiply by speed

//Steering arrival behaviour

if(dist<radiusDist)

{

desired*= dist/radiusDist;

}

else

{

}

steer = desired-animState->velocity;

steer.y = 0;

if(dist < 0.05)

steer = Vector3f(0,0,0);

}

else

{

steer = Vector3f(0,0,0);

}

animState->accel = steer;

//float amountOfForce = 2;

float amountOfForce = 100;

this->internalAnimState->linearForce= steer*amountOfForce;

}

else //If not active, do not influence the object

{

this->internalAnimState->linearForce = Vector3f(0,0,0);

this->internalAnimState->accel = Vector3f(0,0,0);

this->internalAnimState->velocity = Vector3f(0,0,0);

}

return;

}

This behaviour is long but essentially what it does is, first makes sure its active. I have enabled the ability to disable or enable behaviours. If it’s active then it will calculate a vector to It’s target (who’s position is constantly updated). It will then use that vector and force itself towards that position. This behaviour also rotates the entity so it properly faces it’s enemy. Also to note that the flee behaviour is the exact same, except the linearForce is in the opposite direction.

This is mainly used by the coliseum enemies as they relentlessly pursue you because you are their target position.

Fighting Bandit and Wolf in forest.

Wandering Behaviour

This behaviour takes in more factors, essentially what it does is takes in degrees, the arc it wants to rotate along as well as the intensity of how much it wants to try and rotate each second. It calculates it’s potential destination and moves towards it based on the angle. At random, it also decides to go change it’s angle, so essentially moving left or right.

       //Calculate the new location to steer towards on the wander circle

Vector3f circleloc = animState->velocity;

circleloc.normalize();

circleloc *= wanderDist;

Vector3f circleOffSet = Vector3f(wanderRadius*cos(wanderTheta), 0.0, wanderRadius*sin(wanderTheta));

Vector3f target = circleloc;

target+=  circleOffSet;

A lot of the rest of this code is similar to seek & flee so I won’t include it. Every enemy has a wandering behaviour, which can be overpowered by the seek behaviour. This allows it to blend with the seek behaviour and be able to move less predictably, in less of a straight line and can allow them to flank you.

Repulse / Attract Behaviour

This is essentially seek & flee, except that is also governed by a radius which determines whether or not it will repulse/attract to you. So if you are out of range of it’s radius, it won’t seek towards you as a target position. If you are out, then it will apply that behaviour.

This is mainly used by the animals in the forest area, as they don’t want to really attack you at first until they notice you’re close. Since they already have the wandering behaviour, it means they will walk around, exploring but then notice you’re close then use the attract behaviour that overrides the wandering and try and chase you.

Attacking Behaviour

This isn’t listed under the Behaviour section, however it acts just like one. This is targeted at changing the animation however.

Vector3f steer;

Vector3f desired, desired2;

desired = targetPos-currentAnimState->position; //Vector between target and current position

desired2 = desired;

float dist = desired.magnitude();

if(dist < radiusDist) //If you are too close, try to attack target

{

myAnimation->animType = ANIM_ATTACK;

desired2.normalize();

currentAnimState->position += Vector3f(desired2.x/30, 0, desired2.z/30);

}

else

{

myAnimation->animType = ANIM_WALK;

}

Basically what this does is uses the same radius idea as our repulse/attract behaviour. If you’re within a set distance, then the enemy will use this behaviour and attack. This means it will change their animation from walking to attacking and also on top of that, it will increase their position towards you, in essence, making them move a lot quicker than they would be if they were just walking to you. Once they get out of range they would just revert to their normal walking animation and no longer charge at you.

This is to make it more dangerous when they get close.

Moving between Coliseum and Forest area

Walk into the Golden Ring to leave or enter the colosseum.

We essentially load two levels right away, our Coliseum and Forest area. In both of them we create all our entities and give them behaviours.

In the Coliseum area we have a variable that keeps track how many enemies are in the coliseum. Once that number hits zero we have an entity called “LEVEL_FINISH” that teleports to the gate of the coliseum. Touching this entity will allow you to move to the next level.

levelFinished = true; //Enable the level to now change

if(curLevel == LVL_COLISSEUM) //Switching from coliseum to forest

{

curLevel =LVL_FOREST;

init(); //Reinitialize the level

curBattle += 1; //Ensure the next time we enter coliseum, we fight the next battle

}

else if(curLevel == LVL_FOREST) //Switch from forest to coliseum

{

curLevel = LVL_COLISSEUM;

init();

}

This then changes the level to Forest, then it loads in all the enemies at random positions. In the forest area

//Place the wolves randomly

std::vector<Entity *>::iterator it;

float increment;

for(it = entityList.begin() + 2; it!= entityList.begin() + 9; it++)

{

Entity *e = (*it);

increment += 0.3345;

e->currentAnimState->position = randomNumGen(increment);

e->health = e->maxHealth; //Heal the wolves

}

The purpose of placing the wolves like this was to make the forest level more dynamic. Also whenever the level is changed, the player’s health is automatically reset to it’s max value so that the player is now fully healed and ready to go.

The level changing system is rather simple. If the level was already fully created, then it won’t reload those assets again. For example, the coliseum only loads a select few models, including the player, skybox, coliseum, etc. Anything beyond that are enemies that spawn based on the current battle.

if(curBattle == BATTLE_1)

{

curEnemyCount = 3;

battle1Init();

}

else if (curBattle == BATTLE_2)

{

curEnemyCount = 1;

battle2Init();

}

So then it will initialize these enemies, based on the current battle. If I reload the coliseum again, it will keep my coliseum, player, skybox, etc but it will delete these “Battle1” enemies because they are no longer needed. Then it will load the next battle’s enemies, in this case “Battle_2”’s enemies. This is the same case for the forest area, in which it will delete unnecessary enemies. This is to prevent loading too many enemies and overall just controlling all our entities better.

Forest Area – Quests & Upgrades

The forest quests are initiated by talking to the blacksmith. To talk to him, all you need do is attack him. This will trigger a variable that will then be transferred to the gameState. This is checked when the game updates.

Blacksmith

Blacksmith is our go to guy for getting quests and upgrades. He triggers his own menu to pop up once he is activated, which then allows you to access upgrades and quests. We also have to check for things like getting your reward from a quest.

//Blacksmith enable

if(this->currentLevel->blackSmithOn == true)

{

//Checks if all quest enemies are killed and if you haven’t gotten your reward yet

if(currentLevel->curEnemyCount == 0 && questRewardReceived == false)

{

//Awards money if quest was completed

goldRewardQuest();

}

//Resets player’s animation to idle

currentLevel->entityList[1]->currentAnimState->position = Vector3f(0, -30, 0);

currentLevel->entityList[0]->myAnimation->animFinished = true;

currentLevel->entityList[0]->myAnimation->animType = ANIM_IDLE;

gameState = GAMESTATE_BLACKSMITH;

}

Quests

First off we make sure to check to see if you completed a quest to gain the gold reward. From there it will stop your attack animation and open up the black smith menu. The menu will be drawn and then a list of quests and upgrades will appear. The goldRewardQuest() function just checks what quest you had active and then rewards that amount of money.

gameState = GAMESTATE_GAMEPLAY;

currentLevel->blackSmithOn = false; //Get out of blacksmith menu

currentLevel->curQuest = QUEST_LIONS; //Select the quest

currentLevel->init(); //Spawn the lions

questRewardReceived = false; //Allow you to receive a reward upon completion

This code here essentially sets the quest to the button you chose, in this case lions, and then spawn them. Also it makes sure you will be able to receive a reward once you complete the quest.

Upgrades

Our upgrade system is associated with the blacksmith menu. When you click an icon it will check how many upgrades you have already gotten (currentUpgradeLvl), which increases any time you get an upgrade. A calculation will be made to see how much the cost is, and will only allow you to buy an upgrade if you have sufficient gold.

//Check if you have enough gold to purchase the upgrade.

if(currentGold >= UPGRADE_HEALTH_COST * currentUpgradeLvl)

{

gameState = GAMESTATE_GAMEPLAY;

currentLevel->blackSmithOn = false;

//Increase the HP stats of the player

levelList[0]->entityList[0]->maxHealth += PLAYER_HP_UPG;

levelList[0]->entityList[0]->health = levelList[0]->entityList[0]->maxHealth;

levelList[1]->entityList[0]->maxHealth += PLAYER_HP_UPG;

levelList[1]->entityList[0]->health = levelList[1]->entityList[0]->maxHealth;

//Decrease current gold

currentGold -= UPGRADE_HEALTH_COST * currentUpgradeLvl;

//Increase increment to next level of upgrades to make any upgrade after this, cost more

currentHealthUpg += 1;

currentUpgradeLvl += 1;

}

This code here will check if there is enough gold to make the upgrade first. If you do, you will gain the benefits of the upgrade, and lose the gold associated with the upgrade. Then it will make sure to increase the upgrade level so that any upgrades after will cost more. All the other upgrades will look exactly like this code with different variables.

Blacksmith Interactions

HUD

Our HUD is relatively simple, the only thing that updates within the HUD is the HP and stamina bar. Here is quickly how we draw it in game.

void Game::drawHPBar()

{

//Front

glBegin(GL_QUADS);

glColor3f(1.0,0.0,0.0);

glTexCoord2f(0.0, 0.0);

glVertex3f(-0.72, 0.85, 0.0); //Bottom Left Corner

glTexCoord2f(0.0, 1.0);

glVertex3f(-0.72, 0.9, 0.0); //Top Left Corner

glTexCoord2f(1.0, 1.0);

glVertex3f((currentLevel->playerHealthNum), 0.9, 0.0); //Top Right Corner   -0.46 is max is can go

glTexCoord2f(1.0, 0.0);

glVertex3f((currentLevel->playerHealthNum), 0.85, 0.0); //Bottom Right Corner

glEnd();

}

Here is an example of drawing the HP bar. Where it says glVertex3f((currentLevel->playerHealthNum), it basically draws the HP bar the length of the player’s current health. If it’s low, then the bar will be shorter. If its full then it will fill the length of the bar. It’s relatively simple and the stamina bar uses the same method. The stamina and health are updated at regular intervals.

Updating Health & Stamina

In our game, your character is able to regenerate health and stamina over time. You are able to regenerate stamina constantly while health can only be regenerated when not attacking. You regenerate both based on the maximum amount of the attribute you have, so the more you have, the faster the regeneration.

//Regeneration of stamina

if(stamina < maxStamina)

{

stamina += (maxStamina/PLAYER_STAMINA_REGEN_FACTOR)*dt;

}

else

{

stamina = maxStamina;

}

if(stamina < PLAYER_STAMINA_DRAIN*30)

{

currentAnimState->maxVel = currentAnimState->maxWalkVel;

}

//Updating Health

if(entityStatus == STATUS_PLAYER || entityStatus == STATUS_PLAYER_BLOCK)

{

//If you are not attacking, or throwing a spear, then regenerate health

if(myAnimation->animType != ANIM_ATTACK && myAnimation->animType != ANIM_THROW && myAnimation->animType != ANIM_POWER_ATTACK)

{

if(health < maxHealth && health > 0)

health += (maxHealth / PLAYER_HP_REGEN_FACTOR *dt);

}

if(health > maxHealth)

health = maxHealth;

}

 

Also this function only applies for players. Enemies cannot regenerate health and stamina.

Hit invulnerability

Blocking Animation

This term means that if you get hit, you will briefly have a period of time where you will not be able to be hurt. To do this, whenever we check the collision response between entities, if the entity gets hurt (Such as player getting hit by an enemy) then it will save the collision time.

e2.collisionTime = totalTime; //Save the time it collided, which will in turn prevent damage until set intervals of time

Total time keeps track of the amount of time passed in the game, and whenever we update collisions, it checks the total time versus the time you past collided.

if((totalTime – e2->collisionTime > HIT_INVULNERABILITY) && (e2->entityStatus != STATUS_ENEMY))

{

collisionCharacters(*e, *e2, totalTime);

//This enables BLOCK to have more invulnerability time

if(e2->entityStatus == STATUS_PLAYER_BLOCK)

e2->collisionTime += HIT_INVULNERABILITY*1;

//e2->isHit = true;

}

So it won’t allow the collisionCharacters(our collision response) function to go through unless enough time has passed since being hit. When that threshold is passed, it will do the function which in turn calls the e2.collisionTime = totalTime to occur to save the new time. Then total time, will be increasing all the while and the process will start over.

There is also a special case for blocking because it increases your collision time, which means that it will take even longer to reach past the HIT_INVULNERABILITY threshold.

Story of making our Game

From Start to Finish

Ultimate Gladiator Coliseum : 80 AD has been a year long project, a long one at that. It’s been a very exhausting, long but fun experience at times. We’ve been at it since the first semester, and so the ideas to create this game were first formed then. I will refer to THIS to show what how the game first came to be in the first semester.

Basically in summary, we came up with a gladiator game due to inspiration of Skyrim coming out, who’s prequel Oblivion contained an arena. With that in mind, we had certain requirements in the first semester we had to fulfill, such as third and first person modes. This instantly made it even more inclined with the Oblivion style of game so we took a lot of aspects of that into our design. The first semester was essentially getting a lot of base code in, which in turn made the game more of a tech demo than anything. We had a lot of art assets done, but not all, our basic gameplay and enemies in, but not all of it. Due to time constraints we were more focused on getting all the requirements in then the gameplay or balancing so we got all of that in.

This semester would be where we added more in, from gameplay, to new and improved art assets, some new areas to explore and make the game fully functional. Here is our updated (for second semester) Game Design Overview, which is how we might pitch our game to a potential investor. In terms of how we broke down our game in terms of what we learned in class, refer to our Overall Game Atoms & MDA Break down

Second Semester

First week

We started off the second semester off of our break and we started with a meeting in order to discuss our plans for the game this semester as well as take a look at the requirements we needed. A full detail of our meeting and plans is located here. Basically we discussed many of things we wanted to add in, for one we were planning a forest area in first semester but didn’t have time, so now we planned out how we wanted to implement this area and what enemies would be in it. From now, to when that post was written, a lot of the original vision of the forest remains. Pretty much all the enemies and features of the forest are there, the only change since then is that there are no “fledgings” to be cut down for resources. The only resource we have for players is gold, which we will get into later.

For the coliseum, many aspects were planned such as new NPCs, the blacksmith made the cut (for selling items, giving quests), Caesar (final boss) as well, but the battle master did not. The lobby area was also cut, where you would talk to the blacksmith and battle master. Instead the blacksmith was placed inside the forest area.

Another change that we mentioned was to go full out lego style since not all art assets were fully lego styled before. We also talked about revisions to the combat system, though not all of it made the cut, such as blood effects, and the way characters die will also change.

Week 2

Week 1 was the biggest in terms of overall change, and by the 2nd week we simply stated things that needed to be done and tried to finalize our vision. For one, we decided how many enemies we wanted specifically to be modeled and put in the game (Again Battle master got cut). We stated a few other things that we wanted but so far have not made the cut, such as two coliseums, we are using one right now, and we are still sticking with our keyframe animation system.

Otherwise no other significant design changes were changed, we finalized a few things but not too much change at this point.

Week+2

Over the coming weeks, in terms of overall game design, there was not too much more that changed. From the very first week our vision for the game was quite solid, only minor tweaks from then on where done in terms of the overall design.

We began to post on the possible rewards and the number of battles in the coliseum and number of side quests in the forest area, but even that wasn’t fully finalized because all of this was to be changed based on testing. But with that we had an even more solid idea of the number of battles we wanted our game experience to last. We also had an idea of what upgrades we wanted to offer the player and we haven’t changed what upgrades we are offering since then, again the change is in tweaking the numbers after testing. Here you can find a breakdown of our quests and coliseum battles (The finalized version). Here you can find a post of the rewards offered by the upgrade system. (The finalized version)

Combat was still pretty much set in place, though not all of it fully implemented in the game at the time. We know we wanted to have a normal attack, power attack, running, and blocking. Half of this already implemented and the rest implemented soon after. We always had in mind that we would have these abilities, from then on it was just a matter of getting it into the game and then tweaking damage and use of stamina. Here you can find a break down of our combat system (The finalized version).

By late February we had many assets complete, though not as much progress code wise since we were waiting on some of the assets to integrate into the game. The particular post on March 5th I linked was a solid indicator that we had a good idea of where we would go with initial testing numbers for many of our game systems. From there, we had a good idea what initial values to start with.

Month of March

On March7th, we detailed how we began to implement many changes in our game. This first technical post was the beginning of the major changes in our game from it’s tech demo status at the beginning of the semester. It showcased the changing of the combat system and enemy behaviour. Meanwhile, many of the art assets were continually being created. On March 17th, we showcased how we wanted to use gold and upgrades to provide replay value and player rewards.

By March 19th, we already had pretty much all our sounds created for the game. Our team members had chosen and created a variety of sounds, form lion roars, to sword swings, and finding music that fit our game. Details of some of the sounds they found are here. We were quite ahead in terms of the sounds we needed for the game, and all that was needed was to implement them into the game.

Only 2 days later, our main modeller announced that all models were complete. All that was needed was to animate them now. In the time being, our programmers implemented them into the game as placeholders and to make sure they looked right in the world space.

Of course testing began to occur, which is covered in our testing reports. This of course continued through out the semester as more and more features were included into the game and more bugs were discovered.

By the end of the month, we had our poster for our game complete.

April, the month of crunch time

From then on, our game design ideas were pretty much set. Much testing and debugging was done over the course of the month, including implementing requirements such as Sound & Audio, as well as Computer Graphics shaders. Our blog was updated every day with progress of what we added in, every day being new gameplay that we planned to add. Detailed in our design breakdowns, is pretty much what we set out to have from the beginning. Specifics about actual number values came from testing.

Some specific things we did change through the month is some details about the upgrade system, as well as changing a few specifics about our combat system, such as the spin attack, which replaced just a regular powerful attack. This was when we decided to have the upgrade system tweaked, which is detailed here. The system evolved in such a way so as to encourage players to purchase upgrades that tailor to them, and could stick with upgrading their attack the whole time if they so desire. The old system did not allow this. The quest system was also tweaked a bit, where you could start any quest right from the start, though it could be difficult.

The main change we had, was the upgrade system and was really the main difference between what we planned at the beginning of the semester and the end. Everything else was pretty much planned from the start.

But in the end, we got everything in. The combat system was fully integrated, with some tweaks. The coliseum battles were fully defined and the quest system was in, though modified by the end. The upgrade system got the biggest modification that really helped make the game stand out more than we thought it would. Overall, timing for making the game was more hectic than we planned, but in the end we managed to get everything that we wanted into the game. All our systems were in, and intact and our game turned out very well. It became a real game and greatly overshadows the tech demo that was our first semester game.

Game mechanics and Interface overview

So in a gladiator coliseum game, the rules are simple. Fight to survive.

Game Mechanics

Basic Goal

That is the task you must complete as you fight your way through the various coliseum battles. Before you start the game however, you must choose between axe or sword. Axe is stronger but slower and the sword is vice versa. Between each battle, you are transported to a forest area where you get a breather from the frantic coliseum battles. In this area you have time to purchase upgrades and complete quests from a friendly Blacksmith. Upon completing quests and at the end of every battle you are given gold, which is used to purchase upgrades to make your character stronger.

Basic necessities

Your character has three things they need to account for at all times, which is their health, stamina and gold. You must have more than 0 health at all times, or else it will lead to your death, which will restart the level and cause you to lose half your gold. Health also regenerates at a very slow rate. Stamina is very important, as it governs many special abilities you are able to use. Stamina also constantly regenerates, and regenerates faster when you’re not moving. Gold is needed to purchase any sort of upgrades from the blacksmith. Every time you beat a coliseum battle or complete a quest, you will get gold to purchase upgrades.

Health and Stamina Bar

Battles and Progression

In the coliseum battles, simply defeat all your opponents in order to progress to the next level. In the forest area, it is optional to fight any of the monsters there. You can simply ignore them if you wish and proceed to the next coliseum battle. However if you desire you can defeat them for extra gold you would not otherwise get.

The enemies in the coliseum will pursue you all around the arena, once they get close enough they will try and attack you which will make them dash at you even more quickly when close. Some enemies will also have access to special abilities that will activate after some time. These can be devastating, be careful. The enemies in the forest area are a bit different as they will simply walk around but if you stray to close they will chase you. If you get far enough away though, they will stop chasing and go back to their daily lives.

Upgrading

Upgrading is an important part of the game as it governs how you want to evolve your character. You have 4 basic stats, which are Health, stamina, damage and movement speed. You have the ability to upgrade any of these as long as you have enough gold. The catch is that every time you purchase an upgrade, it will get more and more expensive. However this applies to all upgrades, all of them will get more expensive at the same rate. So even if you buy a health upgrade early on, go to buy a few attack then go back to health, it will be much more expensive than it used to be. This allows players to tailor towards what upgrades suit them best, as the player could have just gone for only health upgrades the whole time if they wanted.

Interface

Controls & Battle system

Control menu in from Main Menu

Basic controls

In battle, you control your character using the “WASD” keys for movement. As it is a third person action game, you control your camera by moving the mouse, and to attack you use the mouse buttons. Left mouse will use your basic attack. This basic attack will also slow down your movement speed as you use it. Pressing Q will launch a spear, that deals a lot more damage than your basic attack. You can get your spear back by picking it up.

Advanced controls

These controls all take a portion of your stamina bar or drain it over time. Holding the “spacebar” will allow you to run for as long as you have stamina, a good way to run away and get around. The “E” button will allow you to block enemy attacks and prevent you from taking damage. The “Right mouse button” will allow you to perform a spin attack that deals significant damage to enemies all around in a circle around you. This ability has an initial start-up stamina cost as well as a cost over time for as long as you continue to spin.

HUD

As was mentioned earlier, you have three important attributes, health, stamina and gold. Your health (red bar) and stamina (green bar) are constantly displayed at the top left portion of your screen. Your gold on the otherhand is not shown unless you pause the game. This allows it to be out of the way and not in the way of gameplay so as not to distract you during an intense fight.

Other HUD elements that are only visible in the pause menu include your upgrade lvl (Which governs how much any upgrade will cost), your health upgrade lvl, stamina upgrade lvl, damage upgrade lvl, and speed upgrade lvl. These levels essentially represent how many times you have purchased an upgrade in that category, just to give you some perspective on your progression. Again these elements of the HUD will only pop up when talking to the blacksmith or pausing the menu as there are a lot of numbers.

Combat specifics

In combat, we’ve added a few signs of when you or you’re opponent are being hit. You will hear an attack sound when an opponent is hit, and you will hear a grunt sound when you are hit. Not only that bit a “Flashing” effect was given to show that the enemy was hit as well. The flashing effect makes it very easy to tell when you or your opponent are being hit.

Technical Update #10 & Testing

It appears we have gotten an extension on our game, or at least it was clarified our game was due later. This means our team now has much more time to polish up our game and have it ready for Gamecon.  Already we are continuing with our bug testing and implementation of feature requirements. The requirements in question are now nearly complete and are running in our game. Our game is very near completion and should be very soon. Bug testing and balance will forever continue though!

Testing Results

Bug fixes

  • Fixed a bug where game would crash after loading too many enemies
    • This was caused by the texture being loaded every time an enemy was created
      • All textures are loaded now at the start
      • This also causes the game to transition from forest to coliseum faster
      • Fixed a bug where forest area would slow down if too many quests were loaded
        • Fixed by creating all enemies at the start and then positioning them correctly when activated

Balance

  • Spin attack range increased by 50%
  • Spin attack can be refunded for a quarter of it’s cost when spin attack button is clicked again
    • At a cost of 20 stamina, you will gain 5 back
    • Stamina will regenerate twice as fast when standing still
    • Health will generate twice as fast when standing still

 

Additions

  • Able to choose between axe and sword at the start
    • Axe
      • Deals high damage but has lower attack rate
        • This means spear and power attacks benefit greatly for axe
        • Upgrades for axe provide more damage per upgrade than swords
    • Lower movement speed
  • Sword deals less damage and has faster attacks
    • Deals moderate damage and has fast attack rate
    • Higher movement speed
    • Decreased loading times
      • Transition from coliseum to forest area much quicker
      • Displays when objects have been loaded

 

Major developments

  • Majority of sounds in the game now
  • Cell shaded look now applied for game

Scorching South Studios present… Ultimate Gladiator Colosseum: 80 AD


Hello World,

Well the trailer for the game is finally finished! After lots of difficulties and probably unnecessary steps we are all finally happy with it!
I started with the trailer by animating 2 cut-scenes  in Maya using the characters and colosseum I modeled. After about 15 hours I was happy with the key-framed animation I had made. The next step was the tricky part. I needed to set up cameras within Maya and rig them to move with the animations and then export the cut-scenes from those camera’s views. After another 2 hours or so, I had 7 cameras set up between the 2 cut-scenes and I was ready to start rendering the scenes.

At first, I attempted to export the entire cut-scene as a .AVI file, however for some reason I was able to view the cut-scene in Windows Media Player, but it wouldn’t show any frames in my movie editor, Magix Movie Edit Pro MX, or in any other movie editor on my machine except Windows Live Movie Editor. Even within the 1 program it did work in, only some of the frames showed up. I had to go back to Maya and export every single frame (from every camera) as a .JPG. Once I rendered both cut-scenes (About 500 frames all together), I had to import all the images into Magix and string together each frame. I then rendered each cut-scene camera angle. After that, I edited together the angles to make an effective cut-scene. I found out from my group that we wouldn’t be able to include the cut-scenes in the game, as we are unsure how to play a video using our game engine.

Trailer Storyboard Page 1

Trailer Storyboard Page 2

I decided instead of just scrapping the cut-scenes I spent so long on all together, that they would just enhance the Game Trailer. Before I could start putting together the game trailer though, I had to capture some in-game footage. Using my past experience in cinematography, I knew the most logical place to start was by drawing storyboards. After that, I went through the game and screen captured all the in-game footage I need using Fraps. I then took all the files into Magix and edited them together in the order that I drew out in my story boards. Once I was happy with how the trailer footage looked, I exported the trailer without any sound to show people in my group and make sure everyone was happy with it. I then took the rendered video file back into Magix and went through the sound files we have throughout our game and found some sounds that went well with the footage. After about an hour I finished placing the audio files on the video and rendered the final pass of our game’s trailer.

Thanks for reading, and I hope you like the trailer.
– TBibes: Signing Off.

Technical Update 9 & Testing (Day -3)

It’s been another long day but in terms of gameplay, our game is now fully complete. Upgrades are now in which gave rise to an interesting dynamic of balancing enemy strength, gold received and what kinds of upgrades you can get. This is still being balanced and will become the major focus of any further testing.

Otherwise there are still some requirements that must be met, as well as including some hud elements to indicate upgrade strength and current gold. But otherwise this game is now where it should be in terms of gameplay.

New additions

Upgrades!

  • You can now purchase upgrades from the blacksmith
    • Stamina can increase, also increases stamina regeneration rate
    • Health can increase, also increases health regeneration rate
    • Attack can increase, increases damage for all attacks
    • Speed can increase, increases movement speed all around
    • Each upgrade cost 50 at the start
    • The costs rise exponentially with each upgrade
      • Old Version of upgrades made it so if you bought an upgrade, only that specific upgrade would cost more on the next upgrade. I.e., buying health, the 2nd health upgrade would cost more, but speed upgrade would remain at base cost
      • Changed to all upgrades costing more as a whole, so buying health, then buying stamina means that stamina will cost more than it’s base cost.
        • This means you have to be more selective with your choices as it will become increasingly more expensive to purchase upgrades the farther you are.
  • Example : lvl 1 cost = 50, lvl 2 cost = 100, lvl 3 cost = 150

Fixed bugs

  • Fixed bug where Blacksmith menu would restart if you exited it
    • This was caused by the attack animation sending the weapon hit box to hit the blacksmith again
    • Fixed by changing animation to idle after hitting the blacksmith
    • Max speed now updates properly, will scale up with upgrades properly
    • Fixed a bug where player would slow down when attacking but would remain slow
      • Fixed by setting max velocity right after attack frame is finished
      • Fixed a bug where when going from coliseum to forest area, would have previous quest monsters in the forest
        • Now only wolves will spawn when this happens

 

Balance

  • -increased rotation rate of spin attack
    • Has a better chance of not being hit while using spin attack
    • Lowered amount of HP, stamina and attack given in upgrades
      • HP lowered to +20 per upgrade
      • Stamina lowered to +15 per upgrade
      • Attack lowered to +2.5 atk per upgrade
      • Adjusted quest monsters to give lower amount of gold and coliseum battles to give higher amount of gold
      • All quest monsters have increased difficulty
        • Harder quest monsters have high stats to make it risky to try and engage them early
        • Coliseum battles have been increased in difficulty with the advent of upgrades

Part 2 Night time

Balance Changes

  • Lowered stamina regeneration rate from 15 seconds to full stamina, to 20 seconds
  • Spin attack start up cost decreased to 20 stamina, drain amount increased to 0.75
  • Upgrades increased again
    • HP from 20 to 25
    • Stamina from 15 to 20
    • Speed from 0.5 to 1.0

Bug Fixes

  • Fixed a bug where the spear would not be picked up if a player was blocking

I’m too tired to write much more about this. Lots of progress, closer to all requirements. Game is fully a game now at this point which is a definitely plus. Only 2 days left now!

To do list for gameplay

This is for all team members, these are things that need to be put in the game for it to function properly.

To do list

  • Loading screen (need to put in)
  • Display current gold
  • Display current Weapon upgrade
  • Display current speed upgrade
  • Display current Health upgrade
  • Display current stamina upgrade
  • Maybe a main menu