A Simple Generic Timer System for Unity ECS

Timers are used in different ways in video games such as to allow the players to fast forward in strategy games, or to be used by systems for computations like damage per minute type of effect, and much more. In my experiment project using Unity’s pure ECS, I needed a timer for setting how long an NPC will be on idle.

In this quick tutorial I’ll show you how I implemented this timer system. As usual, there are references at the end of the blog for further reading. Enjoy!

The Timer Component Tag

Let’s start with the Timer tag that we will add to the entities that we want the timer system to affect. Keep in mind that we will be implementing a generic system later that will take this timer tag as the system’s data type. The tag will look like this:

public struct Timer<T> : IComponentData where T : struct {
    // Note that we don't reset the values here since
    // we will remove this component when we're done anyways

    public float ElapsedTime;
    public float TargetDuration;

    public Timer(float targetDuration) : this() {
        SetDuration(targetDuration);
    }

    public bool IsDone {
        get {
            return this.ElapsedTime >= this.TargetDuration;
        }
    }

    private void SetDuration(float targetDuration) {
        this.ElapsedTime = 0;
        this.TargetDuration = targetDuration;
    }
}

I admit that this code looks weird because we introduce a type T, but never use it anywhere in the struct. But, this will help us differentiate the different timer systems later. This is done this way as a workaround to the fact that we can’t inherit structs and structs can’t derive from classes.

The Generic Timer System

For the system, we’ll implement a generic timer system. This will allow us to extend the timer system and have different timers for different parts of the game (such as animations, idle, game speed, etc.). This is what it looks like in code:

public class TimerBaseSystem<T> : SystemBase where T : struct, IComponentData {
    private EntityQuery timerQuery;
    private EntityCommandBufferSystem entityCommandBufferSystem;

    private const float TIME_SCALE = 1f;

    /// <summary>
    /// We set the TimeScale as virtual so that subclasses can have their own timescales if needed.
    /// A use case for this is for faster speeds or faster enemies in strategy games.
    /// </summary>
    protected virtual float TimeScale {
        get {
            return TIME_SCALE;
        }
    }

    /// <summary>
    /// This is the scaled time - applying the Timescale to the delta time.
    /// </summary>
    private float ScaledTime {
        get {
            return this.Time.DeltaTime * this.TimeScale;
        }
    }

    protected override void OnCreate() {
        base.OnCreate();

        this.entityCommandBufferSystem = this.World.GetOrCreateSystem<EntityCommandBufferSystem>();

        // The main idea here is that everything that has the Timer tag of type T will only be processed
        this.timerQuery = this.EntityManager.CreateEntityQuery(
            ComponentType.ReadWrite<Timer<T>>()
        );
    }

    protected override void OnUpdate() {
        UpdateTimerJob job = new UpdateTimerJob {
            EntityTypeHandle = GetEntityTypeHandle(),
            TimerTypeHandle = GetComponentTypeHandle<Timer<T>>(),
            CurrentTimeInterval = this.ScaledTime,
            CommandBuffer = this.entityCommandBufferSystem.CreateCommandBuffer().AsParallelWriter()
        };

        this.Dependency = job.ScheduleParallel(this.timerQuery, this.Dependency);
        this.entityCommandBufferSystem.AddJobHandleForProducer(this.Dependency);
    }

    // BURST IT!!! YAAS!
    [BurstCompile]
    private struct UpdateTimerJob : IJobChunk {
        [ReadOnly]
        public EntityTypeHandle EntityTypeHandle;

        [ReadOnly]
        public float CurrentTimeInterval;

        public ComponentTypeHandle<Timer<T>> TimerTypeHandle;

        public EntityCommandBuffer.ParallelWriter CommandBuffer;

        public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) {
            NativeArray<Entity> entities = chunk.GetNativeArray(this.EntityTypeHandle);
            NativeArray<Timer<T>> timers = chunk.GetNativeArray(this.TimerTypeHandle);

            for (int i = 0; i < entities.Length; ++i) {
                Timer<T> timer = timers[i];

                timer.ElapsedTime += this.CurrentTimeInterval;

                if (timer.IsDone) {
                    int sortKey = firstEntityIndex + i;
                    this.CommandBuffer.RemoveComponent<Timer<T>>(sortKey, entities[i]);
                }

                timers[i] = timer;
            }
        }
    }
}

Now, if you want to extend the timer system – say, you want another one with a faster timescale, it will look like this:

public struct FastTimeScaleTag : IComponentData {
}

public class FastTimeScaleTimerSystem : TimerBaseSystem<FastTimeScaleTag> {
    protected override float TimeScale {
        get {
            return 2f;
        }
    }
}

We first create a new tag that we will then use as the type for the new timer system. Then inside the timer system, we override the TimeScale and set it higher (faster) than the default 1 inside the base class.

A caveat however, if you run this now, you will get an ArgumentException error. This is because in ECS, all ComponentTypes should be known during compile time. To remedy this you can create a separate file, say AssemblyInfo.cs and add the following:

[assembly: RegisterGenericComponentType(typeof(Timer<NormalTimeScaleTag>))]
[assembly: RegisterGenericComponentType(typeof(Timer<FastTimeScaleTag>))]

You can also add this in the TimerBaseSystem class right after declaring your using directives if that is more convenient for you.

To further make it easier to track all the timer systems, we can make a separate system group for all the timers. Then update our timer systems inside that group.

// Depending on your use case, you can choose when your timers should update
[UpdateBefore(typeof(EndSimulationEntityCommandBufferSystem))]
public class TimerSystemsGroup : ComponentSystemGroup {
}

[UpdateInGroup(typeof(TimerSystemsGroup))]
public class TimerBaseSystem<T> : SystemBase where T : struct, IComponentData {
// Rest of the timer system code
}

Now, we are almost set. We just need to add the timer tags to our entities. My use case for this timer is for how long an NPC should wait (be idle) before moving. That said adding the components for me would look something like:

// This will make the NPC wait for 3 seconds at a normal time scale.
// More or less 3 seconds in real life.
this.CommandBuffer.AddComponent(firstEntityIndex, npcEntity,
    new Timer<NormalTimeScaleTag>(3f)
);

// This will make the NPC move earlier than the one above with a
// faster timescale which is twice of the normal time scale
// which is about 1.5 seconds in real life.
this.CommandBuffer.AddComponent(firstEntityIndex, npcEntity,
    new Timer<FastTimeScaleTag>(3f)
);

To demonstrate this I made the following setup:

  • Two NPCs with different time scales (1f and 2f), but the same idle wait time of 3 seconds; and,
  • A MovementSystem that would move the two NPCs after waiting

And it looks something like this (note that timing might differ since I just captured this with a screen to gif tool):

Unity Pure ECS Generic Timer System Example
Don’t worry, they still met in the end and lived happily ever after. *wink*

And there you have it. For further improvement, I’m thinking of adding a query in the base system that the subclasses can override, so that other parts of the game can get the scaled time from any respective timer systems. I already got it working and if you want to read more about query systems, Marnel from Squeaky Wheel wrote a simple query system. He made a better version of that system that doesn’t involve boxing but I can’t seem to find a reference about it online, maybe soon.

If you have questions you can reach me via Twitter or Instagram – That’s all for now and see you in the next one!

References:

P.S. It took a lot longer for me to release this blog because of something great happening soon – Academia: School Simulator is releasing in just a couple of weeks and boy are we nervous in Squeaky Wheel. Please check it out on Steam and let us know what you think. Thank you again, have a good one, and stay safe!

I Made a Game: Leave My Base! (Part 2)

July 15-16, 2017 – Yeah….I didn’t sleep.

I woke up around 7AM to have my early coffee and read a book I had for a while now, The Finishers by Ezra Ferraz. It’s a book about Filipino entrepreneurs and founders. After preparing my mind for the day, I went on to my station and continued my work on the game.

I started where I left of the day before, the aiming and shooting system for the weapons (the ballista and the cannon). I spent about 3 or 4 hours improving this system because this will what the player will interact with in most of the gameplay.

I also realized that this is what makes making first-person games difficult – you need to make everything look and feel right, because the character BECOMES the player. If something is off, the whole immersion will be broken.

After that, I went back to Blender and design the units. As mentioned in the previous part of this post-mortem, I was planning on making the graphics like Superhot, and I’m also inspired by Final Fantasy 7’s Fort Condor Mission. With those in mind I designed the units along with the enemies.

Units_WP
This was the original scale of the bosses which I had trouble spawning in the game. As a solution, I scaled them down a bit.

After modeling the units and the enemies, I imported them to Unity and started writing the spawning scripts.

I didn’t really have any trouble here, thanks to Unity’s navigation system. I just needed to properly write the behavior of the enemies, make sure that they have the right reactions when needed. As for the player’s units, I just need them to spawn at the right location (where the player clicked), and instantiate with a NavMeshAgent component while properly placing themselves on the NavMesh in the scene. As for the unit’s behavior: when they spawn, they will roam around until they see an enemy in range, if that happens, engage the enemy.

I also didn’t have enough time to animate the units and the enemies, so I settled with make them ‘wiggle’ a little bit when attacking. I also added some particle effects when both the units and the enemies die to simulate blood, and also when the cannon balls hit the ground or a target, to simulate explosion.

For the finishing touches, I added Unity’s water standard asset where the enemies spawn to give the feeling that they are coming from “the void”.

For the tutorial and the quit button, I didn’t have any time to make a main menu to put the tutorial in, so I incorporated them in the game world just like in the Dead Space series.

Then, I worked on the audio. I composed a solemn tune with my guitar for the background music and then I used BFXR (I love this app) for the sound effects.

After that, I added some image (post processing) effects on the camera which yields these results:

I playtested the game a couple of times more then I packed everything up around 11 AM of July 16.

Then I submitted the game around 12 noon.

Which is wrong. My greatest mistake for this jam. I forgot that I started the jam almost around 3PM of July 14; that means, I’ll be hitting my 48-hour mark at 3PM of July 16; which means, I still have about 3 hours more to improve the game when I submitted it. Crap.

Conclusion and realization:

Take note when you start the jam and when you’ll hit your n-hour mark. Plan when you will be sleeping and plan what to eat ahead of time (I thrived on chips, packed rice and beef, and peanuts…lots of peanuts). Like always, the next one will be better.

 

Thank you for reading, here’s the first part of the post-mortem, and you can check the game out here (click on the image, it will open a new tab):

ForWebsiteGamePage

I Made a Game: Leave My Base! (Part 1)

Yey! Another game jam. This time, it’s the first ever game jam by Mark BrownGame Maker’s Toolkit Jam. It was a 48-hour game jam where your game must be made from scratch. That is, everything – art assets, hundreds (if not thousands) of lines of code, and sounds – must be made in or under 48 hours. The theme will be based on one of Mark’s videos which are mainly about innovations in video games and game design.

As for the start and end of the jam, Mark was lenient. He allowed the developers to start at 6PM, Friday, in their own respective timezones which means that you don’t need to stay up late in order to start at the same time with the rest of the world. That also means that your 48 hours will only start when it’s already 6PM in your timezone.

ForPostMorted
GMTK-Jam’s banner in the itch.io gamejam page

July 14, 2017

I woke up early to get the theme early and start right away but, Mark seemed to encountered some problem, he was sick the day before, which I think caused the delay. The jam page on itch.io has a countdown which told us (me and the other participants) that the theme will be announced around 1PM. This made me excited and all. But due to the delay, the theme was announced around 2:30PM which, I think, is just fine.

The theme was: Downwell’s Dual Purpose Design.

 

At first, I found it hard to think of something to do with the theme because I’ve never played Downwell before. I’ve been watching Stefanie Joosten’s playthrough of Final Fantasy 7 and I’ve been a huge fan of Monster Hunter since early high school. And, yes, that’s Stefanie Joosten or better known as Quiet from Metal Gear Solid V: The Phantom Pain. When Stef was playing the Fort Condor Mission in Final Fantasy 7, I thought, “this mini-game has always caught my attention ever since I was a kid, watching my brothers play and I can add that mechanic to my other favorite, Monster Hunter”. Then, I thought of how would that combination of mechanics fit into the theme – use only one button to do everything in the game.

I went with that idea and jumped on to Pinterest to look for inspiration and to further visualize my idea. After gathering enough images for my Pinterest board, I picked up my pencil and my sketchpad to try to “make the game on paper” (I have to take an image because my sketchpad doesn’t fit my scanner).

IMG_20170719_182659
Here’s the first draft of the game with check marks on the things that I implemented in the game with 2 which didn’t make the game due to time constraints

IMG_20170719_182715
Here’s my first draft of the battlefield which is very close to the final product in the game.

You can see that there are a lot of scribbles there and numbers; the scribbles are just me writing down what I’m thinking, it helps especially when I’m in the zone, it helps when you can see what you’re thinking. As for the numbers, majority there are just spawn coordinates, height and radius of the colliders, and some ratio and proportions of some stuff.

Writing down things really does help. For me, it cleared my head somehow, which allowed me to process other things – freeing up mental space, if you will.

Level Design. Usually, I start with a prototype of the core gameplay to see which works and which doesn’t but, this time I started with designing the level. I started with some basic assets like the floor and some blocks just to have a general ‘feel’ and size of the in-game environment. My target for the graphics was the same with Superhot. Simple. Lowpoly. Easy and quick to make. After finishing the floor for the game with the appropriate size, I went on to design the ammo containers which will play a major role in the game. I also designed the weapons to be used in the game – a pair of both ballista and cannon.

I also started with how the battlefield will look like (see sketch above). I made 2 paths to make the game quite difficult, and also a bridge between the paths to make the enemies travel farther and to make the player sort of predict where the enemies will go based on where they spawned.

This is how the game looked like. After designing the scene, I went on to programming the ballista. Well started to program, since I encountered some problems with collisions with the bullet and the ground. I really really want to make the bullets stick to whatever it hits, but I keep on seeing a problem in the future with the navmesh. I solved this by adding a separate trigger just before the ground, specifically, for the bullets (ballista ammo and cannonball).

With this, I went on to bed to have the only sleep I got for this jam, a 6-hour sleep.

Here’s the next one where I tackle how I made the enemies go from their spawn point to the gate of the base and attack the player’s units if they come in range. I also discussed some finishing touches for the game.

 

I Made a Game : Fyrelette (Part 2)

July 1, 2017

I woke up early to start with the first thing on my list – a working, playable prototype in, at most, 8 hours. It took me about 13 hours.

The main problem I had was the optimization of the game, especially during the prototyping stage, my laptop “blue screen”ed three times; because I was trying to randomly generate a tile map with a separate particle system for each tile.

Now to give you an idea on how messed up my system was; this was just during the prototyping phase. I didn’t have any sophisticated assets yet, I have a cube for the character and the enemy and a 1×1 (Unity unit) plane fore each tile. Still, my laptop couldn’t handle it.

I couldn’t think of any solution back then, so I just minimized the particles emitted by the particle system, removed the shadows of the particles, and removed the emission property of the particles. I’m left with a simple tile emitting a red square for the fire tiles and a dark purple square for the dark tiles. I settled with this and moved on.

After the writing the code for the tile map generator, I write the code for the player; it was just a simple character movement controller using Unity’s rigidbody instead of the character controller, because why not. Just kidding, because I need to simulate realistic physics collision and gravity. Also, I have two camera modes as of this stage, a 3rd person over-the-shoulder camera and a top-down view camera, because I was not sure yet what to do.

I didn’t really allotted a lot of time in the player controls because I know that I will have trouble with something else – artificial intelligence.

AISS

Honestly, I’m not really good with artificial intelligence. I like reading about AI, but there is something about writing it that just throws me off. You can see that the picture above is the only thing I wrote when I was planning how the AI of the enemies will work; the rest I just implemented as I go through writing the AI. Also, the check marks on the images are just made by me when I finished a certain part of the plan and yes, I still haven’t done any player and enemy data (health, experience, damage, etc.) when I reached this point in development.

The first thing I did with the AI was to figure out how the enemy will stay within the bounds of the tile map that was generated when the game started. I fixed this by randomly generating a Vector3 position using the bound of the tile map generator, which I called xTile and yTile. Meaning I just generate a random position from 0 to the maximum tile in the map, both for x- and y- axes. It was a simple implementation and it worked, it also solved the problem I had with how will the enemy go around the map in order to turn the tiles into dark tiles because I was aiming a Splatoon-like gameplay.

The next thing was to make the enemy chase the player. I implemented this in two ways: the enemy will chase the player if the player is in a certain range from the enemy, and the enemy will chase the player if the player was away from the enemy in a certain amount of time. The first one was implemented by Raycasting from the enemy to the player and if the distance of that ray is less than or equal to a certain number, the enemy will start chasing the player. The second one was implemented by writing a timer for each enemy, then, if the timer reaches zero, the enemy will chase the player, then it will reset after a certain amount of time chasing the player.

Applying the functionalities above pretty much built up the artificial intelligence I need for the enemy, but, I also added a functionality on the enemies – I made them jump. This again is random, I was planning to remove this before final build but, as I tested the game, I noticed that the jumping made the enemies look cute, so I kept the jumping motion of the enemies.

After the artificial intelligence I moved to planning how the pointing system will work and how bonuses will work, basically I planned how the win-lose system will work.

winLoseSS

pointSystemSS

After planning these, I began to write the data class.

dataSS

Now, a lot of these changed as I continue to iterate. That’s the beauty of developing a game, the plans are just there to give you something to start with, but most often if not always, you will end up with something far, in one way or another, from the plan.

This day was pretty much focused on just prototyping how things will work, at the end of the day, I ended up with something like this:

build01build02

July 2, 2017

This day I was planning on finishing the data class, implement it, add a save/load functionality, and start with the graphics for the game.

Making a data class was not a problem for me, it’s just a singleton that will persist through the scenes and it’s only consists of variables and properties. The problem I encountered during this stage was THE FREAKING SAVE/LOAD FUNCTIONALITY ISN’T WORKING. I reviewed the past lessons I read about the topic and still couldn’t get it to work. The save functionality was solved pretty quickly, but I could not get the loading functionality work. Then I realized (this may sound funny), about 2 hours in, that I wasn’t saving the loaded information properly to the variables of to the instance of the singleton. That was a noob mistake and I laughed and facepalm’ed myself.

After messing around with the data for the win-lose system, I jumped to Blender and Photoshop to make the assets for the game.

UISS

I started with the blocking where the UI elements will sit on the screen. At this time I still don’t have an art for the main character but, from my Pinterest board, I have a ‘general’ feel in mind, so I jumped to Blender and started modelling the main character and the enemies; and ended up with these:

This days was focused more on aesthetic design and at the end of the day I ended up with this:

July 3, 2017

This day was full of balancing, modifying some of the UI elements, adding post-processing effects for the ‘high’ quality option, and not staying in front of my laptop for pretty much the whole day.

I submitted the game 10 minutes and 13 seconds before the submission deadline,

deadline

Conclusion and realizations:

This jam was fun. Quite challenging but I got through it with proper time management. That is, breaking down the game into small pieces as I can then prioritizing which task will come first. Like most games and developers out there, the next one will be better.

I’ll join the next one for sure! 🙂

Thank you for reading, you can play the game here:

https://itch.io/embed/155801

I Made a Game : Fyrelette (Part 1)

72 Hours. Total of 6 hours of sleep. 3 days of designing, programming, chocolates, and coffee. Hear my story of when I joined TairaGames‘s Dev Squad Jam from June 30, 2017 to July 3, 2017.

TairaGames banner in the itch.io gamejam page

June 30, 2017

The game jam started around 8:00 PM (GMT+8). I didn’t start right away with programming or asset design because I wasn’t at home when the jam started. I was about 2-3 hours late. Instead, I started with game design on my way home and for the next couple of hours after I arrived home.

The rules for the jam are simple: “your game need to conform with the given theme and your game should use two items which will be announced at the start of the jam”. The theme was “Darkness” and the items were “fire” and “map”.

The first thing that came to my mind when I first read this was a survival game or a walking simulator; because of two things. They are both relatively easy to make, I could just make a first person game, design a map or area to walk around (a house, maybe), then write a compelling story and compose a emotionally-striking music; and survival and walking simulator games doesn’t really require a complicated gameplay mechanics. Don’t get me wrong, I love these genres, but, I feel like challenging myself a little more.

RuunerSS.PNG

Another idea came to me, an endless runner. Now, I have an endless runner in my portfolio and I believe that I can make one that might be better than my last. Endless runners are common, people love it; there’s a big replay value for this genre; the mechanics are quite easy; the only problem that I saw was I need to make the artwork and soundtrack of the game, to very compelling in order to compensate for the repetitive gameplay. Or, add another mechanic that will compliment the general endless runner mechanic.

I played around with these ideas for a while then I stumbled into the idea of  the “darkness taking over light” cliche…and Splatoon.

SplatoonSS

As first I wanted to modify the “occupy as much of the map as you can” mechanic of Splatoon by making it a tile-based-turn-based game with 3-dimensional isometric cell-shaded art style. That didn’t sound bad, especially if I add the dice mechanics of the mobile that I was hooked on, Dice Hunter: Quest of the Dicemancer. Each dice has an action which the player can choose during his turn. In each turn, the player ‘tosses’ the dices then the actions (move, defend, attack, cast magic, use an item, dance, etc.) on the ‘board’ are the only actions that the player can perform during his turn. Then, each tile on the map that the player steps on will be ‘his’. The same goes for the enemy, whether AI or human.

Again, I played around with this idea for a while in my head. But, I couldn’t make out the algorithm for the 3D dices. I thought of making the dices rigid (rigidBody in Unity), then just add a force when the player ‘tosses’ the dices, but, I wanted a more code-based approach, and I failed. I can just print the actions in a button or something 2D on the screen but, that will not be as immersive as an ‘actual’ 3D spinning on the screen.

CombinedSS.PNG

My last idea was my last hope. I stayed with the “occupy as much of the map as you can” mechanic of Splatoon and I added a different approach. At the time of writing this blog, the game Nex Machina is gaining popularity. It is an “intense arcade style twin-stick shooter” by Housemarque. I like the top-down or isometric camera angle in games because you can hide some areas in your map, if you restrict the player from rotating the camera; and I grew up playing different shooter games.

I started with sketching how the game would work using Paint. I drew various camera angles (above), some key core components of the game, mechanics to incorporate in the game, some win-lose criteria, and drew random artworks that I might use. I also browsed Pinterest to look for more inspiration in the general look and feel of the game, character designs, and environment/map design. Here’s the Pinterest board I made for this jam.

I was happy with my progress so far; I pretty much designed about a third of the game on paper and in my mind when I woke up for the next day. I plotted the things that I will do regarding the jam for the next couple of days and went to bed.

Thank you for reading, click here for the next one where I tackled writing the AI, the core game mechanics, and making the art assets for the game.

Ice Princess Nix

“I learned that courage was not the absence of fear, but the triumph over it. The brave man is not he who does not feel afraid, but he who conquers that fear.”
Nelson Mandela

Some of you may know already that I love learning and I love art. I started drawing when I was still a kid, around 4 or 5 years old, I guess. And like every one else, I was not that confident with my work. I always think of the idea or fear of showing your creations out in the world then receiving criticisms about things that you might have done if you only have more time to iterate.

I still remember the first time I showed my work back in the 5th grade, during our art class. It was a pastel portrait of the Iron Man suit. Some of my classmates liked it and praised me for doing a good job. But, majority pointed out the proportional mistakes of the portrait. I’m fine in receiving criticisms now – I’m actually looking for it – but back then, it hurt like hell.

Well, that story aside, I “come and go” in doing art because I also make games and there are times when I just want to program and make a prototype instead of making art; and there are also times that I just want to write poems, shorts stories, and other stuff to clear my head.

Initial artwork using pencil and a bond paper
Initial artwork using pencil and a bond paper

This piece is one of my drawings during our break time at the university. The signature was cropped when I scanned the image, but the date is 4/27/2017. During break times, I usually go to the library or the computer laboratory to study about game design, psychology of games, and other game related stuff. Or, I go anywhere with a power outlet and make random game prototypes with my laptop. Or, if I’m burnt out because of hours and hours of working, I go out with my friends to play or just have fun.

I actually don’t know what I was thinking when I was drawing this. I just zoned out and drew a girl standing near a cliff. From there, I thought of making it look like she was about to commit suicide but then, I added a Godzilla-like creature and noticed that it was more interesting. So, I went with it.

I was actually planning on making a digital version of this using Photoshop but, my tablet broke. So, I decided to make it in 3D using Blender instead.

First render without mist
First render without mist

The original setting of the scene was supposed to be on a green mountain; but, I had a hard time doing a shader that looks like realistic soil, so I went with snowy mountains instead.

The stars look fine but, I felt like something was missing. I tried adding vignette (because people love those), but it wasn’t filling the gap that I felt. Then I thought of Uncharted, Tomb Raider, and Skyrim. The idea kicked in and I was like: “Oh! Mist!”

Final render with mist. There are still stars there...somewhere.
Final render with mist. There are still stars there…somewhere.

Then I came up with this, there was still something missing but, I ignored it and just moved on with the story for the scene. Here’s a snippet of what was going on in my mind:

Nix, the Ice Princess of Crystalia, the city hidden in the snowy mountains, is a very kind and charming girl. The people of the city admires her sweet and gentle smile every time she walks around the city.

 

But, one day, his loyal knight, Steiner, rushed to her door and woke her up. “Princess! It’s your father.”, said the knight panting.

 

They went to the castle clinic and saw King Ashura covered with his own blood and his arm bitten off. The clinic was full of soldiers half dead. “They went on to hunt the great winter beast.”, said a young nurse. The princess fell deep into agony until one night, she woke up to a loud growl which sounds like a mixture of a man yelling, an ice mountain lion’s roar, and the echo of death. It was the winter beast, Frigore.

 

The princess and her loyal knight, Steiner, went out to hunt the beast themselves. Although the princess was feeble and weak with the sword, she was well versed in the arcane arts of magic.

 

They approached the location where the sound most likely came from and as they got closer, the sound became louder and louder until they arrived at a cliff and there they saw it.

 

A shadow hidden by the mist of the valley as big as the mountains themselves. The beast stood on two feet and its tail swung with a booming sound. It turned around and growled so loud that Steiner was stunned. Nix waved both of her arms in a circular manner; then a huge sphere of pure magic covered them both just in time to block the shards of ice that flew towards them. The shield protected the princess very well, but Steiner was not so lucky. A small shard hit his helmet so hard that he fell unconscious. After another loud growl, the beast faced the princess and walked towards her.

 

“The Ice Princess – Nix Koud of Crystalia. You dare stand before the great Frigore?!”, said the beast without moving its jaw. The beast stared straight into the princess’s eyes like it was ready to suck her very soul with just its glance.

 

“Telepathy. So, you can understand, winter beast.”, yelled the princess before creating a sign with her hand that caused her hair to grow longer, her eyes to turn red, and the ground around her to tremble.

 

“The secret arts of the dragon slayers! How did you- who are you?!”, said the beast followed by a growl.

 

“I am Nix Koud von Crystalia, the Ice Princess. Daughter of Ashura Koud von Crystalia. Master of the arcane arts of magic – and a Winterhold Dragonborn. Prepare to die, beast!”, yelled the princess while staring at the beast’s eyes.

There, just random words and names that popped up in my head while writing. Anyways, thank you and if you want to see how I did this, you can check it out here: