Ice Dragon Combat Behavior

Non-Combat Sequences

Idle Breath With Head Turn Behavior

(optional) Talk every 5-10 seconds.

Wounded Breath With Head Turn Behavior

Dragon is wounded, player can walk up and inflict damage in this state. Player needs to look for weak spots.

Stationary Flight With Head Turn Behavior

Dragon appears flying stationary at start of map. It tells player they should turn back, head rotates with player. It flies off towards the back of the ice cavern and is not seen again.

Combat Sequences

when player enters cave, door closes back up behind.

dragon lures player into cave, says they can approach world portal behind them.

Stationary on foot, head moves around to follow player

When player passes trigger box, dragon turns to player and says you fool, blasts them with ice (turning off player movement until they break chains–maybe entrap player in giant ice cube instead, feels more on theme), and flies out of the cave.

after player passes cave trigger box (to follow dragon)

dragon summons rats to mount crossbows (crossbows don’t exist until this moment), flies stationary for 20 seconds taunting the player. Occasionally flies over the player (low pass) then returns to stationary position taunting. Doesn’t do any damage. Dragon occasionally launches slow moving projectiles, player can avoid them or hit with ballista arrows or hammer. This part does damage.

Dragon flies in an overhead circle then flies down to a lower point and launches projectiles at player

Particle Effects On Projectile & Dragon Breath

Projectiles: looking at using bp_ky_shot_ice as an effect model for the projectile itself.

consider using ky_cutter for another take on projectile

consider ice-spiderling projectile

magic spray ice 02 for dragon breath

moving spin ice 02 is cool for potential big projectile

projectile bomblet ice 02 is interesting

spear blast maybe good for end of ice breath

dragon falls down after player hits with arrow. Dragon looks more wounded. Player has to hit dragon 3 times. Program radius around it for when player enters.

Player enters radius, dragon perks up and says “this is not OVER”. Puts player in ice cube, starts to run in one direction. (this cues a new save/restart position)

Player has to hit dragon during this phase by reflecting its projectiles or somehow hitting with hammer or grippable weapon (will be difficult since it’s far away). Dragon takes 5 hits, announces voice when hit, flashes when hit).

Dragon flies over head, swoops over player and drops icicles from above.

Dragon flies to direction above player, stays in stationary position and spits slow moving projectiles player needs to destroy before they are hit.

When the player hits the dragon during this phase with hammers, it flies or runs directly back to the recharge area.

When player destroys portal object, enter last phase. Large dragon ghost appears in middle of map on pedestal.

Dragon runs in one of 8 octagonal points. It turns and fires projectiles at the player (player must duck/weave past projectiles as they fly in or hit with hammers). Dragon then moves to next octagonal point.

If player hits dragon with weapon, it sits stunned for 15 seconds. Player can hit during this time and damage inflicted shows on body. Large dragon ghost in center of map decreases in size and flashes when dragon is hit (this is life bar).

If dragon is not killed while stunned, it goes ghost, a ghoulish laugh plays from center, then it respawns at one of 8 octagonal points.

When player finally kills dragon, the center pedestal where ghost was shows a new sword. Player can use this sword to break portal and teleport back to main world.

Made a behavior tree called baseDragonPlayer Swoop

Tested keeping dragon within a specified radius and adding to its turn radius to keep it within the edges of the circle

Still ran into issues with collision with large objects on map when dragon was at low elevation after swooping towards player.

Also ran into some issues with this approach of adding to turn radius where it either looked choppy or momentum would still take it to uncalculable position.

Also found that experience of dragon swooping on you in first person isn’t as fun–the first person aspect of it blocks all view of the dragon’s destruction because of the particle effect coming down on you.

Decided to re-orient design more towards a siege fight with allies so you can appreciate the dragon’s destruction from a third person.

Player can open 4 portals for turtles who will assist firing projectiles at the dragon.

Dragon will attack those turtle positions and take a center stationary flight position and shoot homing projectiles at player. Player will be forced to go between turtle positions to reactivate them or find area shielded from dragon.

This approach also gives a better lead up feeling to the fight with the dragon–you are rallying increasing numbers of turtle allies as you fight your way through the bottom canyon.

TODO:

draw distances inside cave need looking at, new max values are not updating.

add some more roll to the dragon turning on its end, will make it feel a bit more real.

add a bit more pitch variation, potentially tied to wing flaps.

Development Blog #1: Designing Trigger Box Logic

This style of dev blog will be meant to be kind of half tutorial, half you the reader following along with my thoughts along the way of developing this VR game.

Right now I am about a month and a half into designing this new ice map.

The ice map is meant to be the first in a series of dungeons, which offer something a bit different than the open world ‘overworld’ part of the map. These dungeons are meant to be linear experiences that offer the player a high challenge in terms of density of monsters, offer some puzzles, and ideally introduce a new item/mechanic as a reward for the player progressing.

The challenge right now for this section of the blog is designing trigger box logic for various encounters on the ice map.

Let’s dive into the sequence of events now:

  1. Enter the map.
  2. See the dragon near the cave entrance, have it shout some menacing things at you.
  3. Fight your way down the ramp until you’ve activated the first respawn point.
  4. Fight your way through three sets of monsters to activate three puzzle platforms which allow you to control giant eye towers and point them towards the ice door.
  5. Unlock the ice door finally and fight boss dragon in a boss battle.

First we want the player to descend the mountain and encounter enemies along the way.

This part is easy-we put some trigger boxes (green squares) and each time the player overlaps with them, we have them spawn enemies. We implement a do once node, and if the player dies we should reset this node as part of the death sequence so enemies can spawn again: we’ll get to this later.

Next step:

When the player reaches the final end of the ramp, we want them to unlock a new respawn point.

Open questions: should they unlock this respawn point only if they’ve defeated all enemies? What if they don’t go towards it and teleport off the edge somehow?

To solve for this, I decided to implement either a magic cylinder that draws to this point in the sky so it signals clearly to the player they need to go there to progress or a line drawn from the player’s hand towards this goal. I’ll add this implementing to my todo’s at the bottom of this post.

Next step.

We want the player to now see an event take place where these eye towers come out of the ground. We also spawn monster portals and/or boss monsters along the way near these towers.

These towers are controlled by this platform with a VRLever the player can spin.

This platform should only be unlocked once the player has beat all the monsters. If they die in the process of fighting the monsters, they should respawn at the last respawn point.

OK–so how is this all achieved in code?

Spawning Monsters–handled by the respawn pad blueprint:

Relevant functions: SpawnNextMonsterEvent–this gets called in one of two scenarios, either the player has survived and finished the previous puzzle, or the player has died, then when the player ends overlap with this wider collision area, it starts the whole sequence again. So only when the player has had a chance to recover mentally and moves themselves again does it start the sequence.

Keeping Track of When to Unlock Lever

This loop is activated after spawning monsters. All monsters spawned or other classes associated with monsters (such as the big spawn portals we create) are added to this array of spawnedActors. Every 0.5 seconds we check if this array is count 0, if not we assume the player has not finished this sequence. If it does tick down to 0, then we destroy the ice cube component of our lever class. TODO: need to draw more attention to this, make sure it’s clear for player they have to go to the lever after they’ve cleared the enemies.

Handling Player Death

If the player dies, we respawn them and destroy all the monsters and return their life back to maximum.

We also have to stop the loop checking for spawned actors before it has a chance to trigger, so they don’t get credit for finishing a sequence just because of monster despawn. This is done by some code in our GameMode class checking to see which map we are on, and then getting a dummy blueprint actor we placed in the level handle all our death logic.

Right now this actor has two responsibilities:

  1. Reactivate the correct respawn pad so that sequence starts again once the player starts moving.
  2. Kill all loops respawn pads are firing checking if their clear conditions are met.

Saving Progress

So if a player has cleared 2 respawn pads, how do we keep track of that?

Also, if a player quits the game, how we do keep track of which map they should open when they restart the game?

For our case for now we are implementing this fairly simply assuming it’s always the same player and they aren’t selecting their own save game file–later on we’ll have to go back and allow multiple save games so different players can have unique progress.

Right now it is implemented with two variables on the save game: iceLevelHighestTP and currentWorldToLoad.

When the player dies, it gets to this section of logic in the function “RespawnPlayerOpenWorld”. It loops through all the possible respawn objects and gets the one that’s equal to the highestTPNum from the save game. When the player completes one of the puzzles on the levers, then it saves this to a higher number.

Next Steps:

Beyond our todo’s, we need to consider the layout for all of these objects in the map. Here you can see the position of the 3 eye towers (all will be under the ground so they have a chance to rise up).

We also have to think about the locations of the towers with the rats operating ballistas and how we want them to respawn. I am leaning towards having them respawn every time regardless of the player location, I want them to feel annoying and not necessarily dangerous but something to keep your mind on. I might add one more rat tower for good measure.

TODOs:

Convert spinner to VRLever Object and test

Implement sound once VRLever object is unlocked

Draw attention to vr lever once it’s unlocked.

Implement sound and animation once final ice door is unlocked

Reset trigger boxes ability to spawn monsters after player death

Implement magic cylinder of great height at first respawn point when that is the player goal or draw an arrow to this point from the player hand.

Sound for eye towers coming out of the ground.

Test travelling to this new level from previous level

Reward waiting: move on to doing ice dragon boss fight behavior logic.