Montag, 20. März 2017

Developer Diary 58

When I started working on Lakini's Woods in late 2014, I wrote a game design document, that contained  a basic set of features and core game play mechanics. Up until today I never updated this document and with everything that I have learned until this point it is of course grocely outdated. During the first couple of weeks in 2017 I felt that I had been going around in circles and one of those reasons was, that I had been straying from the original game design way too far. I'm currently reading up on publications, studies and compendiums on game design and game mechanics. I found a collection of amazing reading material:

"Gameplay and Game Mechanics Design: A Key To Quality in Video Games" by Carlo Fabricatore
"Gamedesign: Theory and Practice" Richard Rouse III & Steve Ogden
"Level-Up" by Scott Rogers

At the same time I started playing around with the early 80s generation of NES and SNES video games again, while breaking down their core mechanics and analyzing the overall level structure.

I found games like "Super Mario Bros.", "Tetris" and the very first "Zelda" incredibly enlightening, as these games have a very strict and coherent rule set. A game called "Terranigma" which was released in the late 90s for the SNES caught my attention again. I was stunned by the sheer quality of game design, a beautiful battle system and a clean, solid code that delivers a stable and glitch free game experience from start to finish.





Especially in the case of Terranigma I discovered a major feature, which turns out to be a hallmark of game design quality across all genres: A clear Question /Response Loop:

Every time a player interacts with the game world he "poses a question" for which he expects a definitive answer. Let's say our player character hits the wall of a dungeon with his sword: In this scenario there are several possible outcomes:

1.) The sword collides with the wall (experienced through an animation and a SFX), but nothing else happens

2.) The sword collides with the wall and the weapon breaks.

3.) The sword hits the wall and a hollow SFX is played, indicating that the wall is fragile and can be torn down

4.) The sword goes through the wall, without any consequences

5.) The sword goes through the wall, hitting enemies on the other side of it

6.) The sword hits the wall, triggering a hidden door mechanism on the other end of the room

If every time the player attacks the wall, he receives a different response scenario, without an apparent reason, then he can never confidently trust the rule set of the game. Terranigma does this flawlessly on multiple levels and it raises the overall quality of the game immensely.

To compare: "Secret of Mana" or better known as "Seiken Densetsu" for the SNES had a much less stable Question/Response Loop. Even though the game is great and I love playing it, I find that the code is much weaker and that glitches happen all throughout the game. If my player token is hit by an enemy in this game, based on the location of both hit boxes there is at times great uncertainty of whether or not my player token will receive damage. This creates frustrating experiences ... especially in "close call" situations where you have to rely on the position of your character and the fact that he is outside of the enemy's damage range.

I realize that I should have started out with all of these considerations 3 years ago. But at the time I had no idea how to write code or work with Unreal Engine 4. At least now I know how to do all of these things.

Because I didn't know any better I initially contracted parts of the game, that I wanted to have finished (models, VO) right at the beginning to other crew members. And the people that worked for me provided me with great results, and all of their hard work will be a part of the final project ...... but it's slowly sinking in, that my initial design contained some major errors that I'm just now finding out about. And I shouldn't have involved other people without re-thinking my basic concept.

I was wrong about many things .... ironically I was right about all the things that other designers warned me about in the beginning. For example the dharmapala system can basically remain just as it is, without losing any FPS and the overall environment design including the selfbuilding world can also be incorporated. I can even keep the code just as it is, without having to make any changes to it.

But there will be no items, there will be no weapons apart from the elementals and there will be a much cleaner interaction system that eliminates all possibilities for collision errors. I will keep the "Reichsmark" currency system though. They simply look beautiful when they are placed inside the game world and they correspond well with the buildings and the soldiers chasing Jonah.

In order to create a decent and coherent design I will need to read up on a ton of books and papers first, and for some time I will need to get back to the first generation of games and take them apart piece by piece, to better understand their overall structure and mechanics. I don't want to make the same mistake twice.










Mittwoch, 8. März 2017

Developer Diary 57 - New Approach to Foliage

This is a study on various uses of foliage models and exponential height fog underwater. Depending on how they affect FPS during realtime chunk generation I may have to ... revert to fixed level setups. I hope I don't have to. But they sure look beautiful:





Sonntag, 26. Februar 2017

Developer Diary 56

I implemented the code and now players can determine their own view distance based on their RAM and Video Memory.

I also added spawning algorithms for large structures, cities and villages. They still need some fine-tuning, but they create decent results. It's a lot of fun to just fly through the world or let everything drown under Mahakala's rain.





Montag, 20. Februar 2017

Developer Diary 55

I'm so fucking proud of this:


This is the final Code Layout of a landscape generator, in which view distance and chunk generation is adjustable by the player.

Now let's implement it!

Sonntag, 19. Februar 2017

Developer Diary 54

I fell sick yesterday and during the last two weeks I've barely made any progress due to constant Engine Version Updates and experiments with the Forward Rendering feature... I had massive problems with water reflections during runtime and was hoping it would be fixed with UE 4.15 but to no avail.

So I spent some time reading up on Microsoft Hololens and various other VR and augmented reality technologies that will hit the market in the coming years.

Another thing I wanted to try out was this:






It must be possible to create a unifying formula to spawn landscape objects and foliage instances. After some pondering I came up with the stuff above... With this I can now create a code that builds the landscape for a set number of tiers around the center landscape chunk. The player will be able to set the number of tiers based on his own hardware (High Specs = 8 Tiers / Low Specs 4,3,2 Tiers). This should be a beautiful way to sidestep framerate issues and to gain complete control over all spawners and their actors.

My progress is still very slow .... and I find it incredibly demotivating at times ... but all I can do is take it one day at a time. Maybe one day it will pay off. I don't know. At least it's fun to think about this kind of stuff.


Dienstag, 7. Februar 2017

Developer Diary 53


I tested the game and made some screenshots. This one looked awesome .... mabye a good BG for a logo?


Montag, 6. Februar 2017

Developer Diary 52 - Thinking Out Loud



Ok, so for the last couple of days I couldn't figure out a bunch of problems that I have been mulling over for a week now .... I wrote a long mail to a friend of mine about this, and it seemed to open my eyes to a different solution.

So this post is just going to be a long ramble about code and framerate issues, so that I can get this thought process out of my head and onto a piece of paper. I hope it will lead to a solution or at least some fresh ideas....

I've created a couple of blueprints that spawn the entire game environment and are responsible for the placement of foliage, interactables and trees. But I have the following problems:

- How do I connect the maze spawner with the natural environment? 
The maze spawner needs an even ground for it to work, because if there are hills, the player is able to simply jump over the borders. I could implement a tunnel, or a gate, that leads the player into a new atmosphere.

- What would that tunnel look like?
The front would have to resemble Gothic architecture, made out of black marble and several towers built around it. It would lead into a tunnel, with the exit leading through the Southern Gate of the Maze Blueprint. But where does this tunnel spawn? On top of a hill? That looks shitty as hell. Inside a hill? But the player will collide with the landscape model, and I can't create landscape holes through code at the exact location the tunnel will spawn... Underwater? But then the maze would have to be underwater as well.
But if I clamp the spawn Z coordinate of the gate to a high value (e.g. Z of Landscape + 1000) it will almost always spawn on top of a hill. I can create a large foundation reaching into the ground and the gate itself simply leads to a staircase upwards. After the staircase there is a closed tunnel bridge, with Gothic windows left and right. Once the player leaves the tunnel, he's standing in the center of the maze blueprint. I can even add one of the Wall Cycles to this blueprint, so the tunnel doesn't appear to lead into thin air.
I'll need to create a collision box inside the tunnel bridge, and on End Overlap all former landscapes will be destroyed. But what if the player turns around? .... Maybe he can't turn around .... maybe there is a door, that keeps him from going back, and the collision box appears after the player has passed the door .... that might work ....

Why are my trees and foliage actors not de-spawning properly when they are out of sight?
My foliage blueprint creates hundreds of linetraces by channel straight up into the ground along the Z axis. When one of those linetraces collides with a landscape actor, it saves the trace impact point and spawns a tree actor at this location. The spawn scale varies greatly. But with a varying spawn scale, the visibility collision sphere of each tree actor also varies. Usually it would be easy to solve, by simply setting the spawn scale to 1,1,1, in the foliage spawner, while randomizing mesh scale inside the tree actor. But the tree meshes aren't centered properly in their native files. Which means that as soon as I change the scale, each tree will be off center. The solution in this case would be to manipulate each mesh in 3dsMax and set them up in a way so that they are centered properly again. And as I think about this .... there is probably no way around this .... for some reason I can't stand 3ds Max. I was hoping there would be a different solution .... but now that I see it written down .... damn .....

How can I create, cost effective, spawnable, low poly grass and implement it into the foliage spawner?
First of all I probably should use "Mobile Woodland Grass" Models from the "Realistic Grass" Package in Unreal. It looks great and has a very low vertex and poly count. But the problem is, that if I start spawning them in the same way I did with the trees, I will create massive framerate problems. I want the grass to only spawn around the player. I want it to appear at a range, where the player doesn't see it appearing. And I want it to be destroyed when it's far enough away from the player so he doesn't notice its destruction.
For the grass to disappear I can simply set up a visibility collision sphere around the grass actor. I can randomize the mesh scale slightly, since this mesh is actually centered. The best way to deal with grass is probably to separate it from the tree spawning foliage blueprint. So I guess it would be smart to create a "grass spawner". This grass spawner has to follow the player throughout the game. It would spawn grass all around the player (get player character -> get actor location -> break vector -> x+10000 -> y+10000 -> make vector a.s.o). There would be a "grass counter" to manage the total number of grass models on the ground. All this blueprint does is spawn grass on the ground based on linetrace impact points. They will destroy by themselves through their own visbility sphere.

Why not simply use a culling volume?
For some reason I always experience a massive FPS drop when I implement a culling volume in my world. Of course I could transform each grass actor into an instanced static mesh .... but let's picture a situation in which the player moves East twice, and then suddenly moves West twice again. The previously spawned grass will reappear and be completely out of line with the newly spawned landscape's Z coordinate, because all the culling volume does is "hide" the instanced mesh. And from what I've learned so far, destruction is cheaper than hiding stuff.

How can I create abysses?
I previously created a "Black Death Volume". As soon as the player collides with it, he will be "Game Over" and the player character will disappear. Now the problem remains: How can I create a situation in which the player has to jump from platform to platform in order to survive? If it is possible to spawn landscape actors with the "worldspawner", then it will also be possible to spawn "platforming segments" with it. These platforming segments would probably consist of a landscape mesh with very steep mountains (set world3dscale  -> Mesh -> z = 8). With these mountains a death volume of equal size and a "platform spawner" will be created. The platform spawner will ensure, that the player can actually enter this landscape segment while at the same time randomizing the players route to overcome this landscape segment. Additionally I could tweak the item spawner in a way, so that it will spawn special items only on platforming landscape segments.

How can I deal with the AI without the use of navigation volumes?
In part this problem is already solved, with Obersturmführer and Wehrmachtgefreiter.Their behaviortree is set to "Move Directly Toward" while they are clamped down to the landscapes Z value. And even if they follow the player underwater it mostly looks wicked, to see them wade through an ocean, while still aiming for the player. But there must be a timeframe and a ruleset for how long they will follow a player. Not all enemies can spawn at all locations. The crawling Giant can only appear in the maze, the Worms can only appear in abysses and the Mantas can only appear underwater. If each AI is specifically programmed to only function in its natural habitat, then it is much easier to set up AI without the use of navigation volumes.

Wow.... looks like this blog post was a good idea .... it's much easier to go through all these steps by writing them down .... it's as if my brain doesn't have enough capacity to work through this all at once ....

S.M