Group Project Dev Log – 16/02/2018

This week I implemented Firebase Analytics into the project tracking metrics such as Session length, Score and via which route the player fails. I struggled somewhat with integration due to the Documentation and Getting Started guide being somewhat lacking in detail.

The Analytics task was estimated to take most of the week; it was an 8 point task, however, i managed tom complete it in a short amount of time allowing me to move quickly onto Integrating Google AdMob and add the banner ad. Unfortunately i have been unsuccessful setting up my phone as a test device so google is currently serving live ads because of this i will have to disable the live ads.

The essay on Development Management is consuming far more time than originally expecting, causing it to become a burden and risk on the project.

Artwork did not live up to my expectations as it came in, despite my careful planning I should have asked for one complete asset at a time (vertical slice) to review and give feedback to help steer art towards my vision in a more iterative approach. As more assets are completed i will be more careful to review and steer it in the right direction.

Moving forwards i will have to resolve the issue with ads so that i i can safely play-test the game without having to make a separate build with ads disabled. I now also know to allocate more time to writing tasks so that i do not find myself in the same situation again.

Visual Scripting – Sorting things out

Before I am able to place vegetation on the terrain I need to know the slope angle at each point so I can determine whether it is too steep or what kind of plants i want to appear in those circumstances. I could get the tangent/normal data from the FRawMesh from last week however i that would require removing duplicates again which would be both slow and I could become a pain if they don’t match up after the sorting process. I decided to go the easier route and calculate them by sampling the adjacent points.

The first issue is that blueprints only support 1D arrays but i need to address elements with 2D Coordinates, To help with this i wrote a macro that uses the formula i = y * width + x which will do just that.

Sorting_2DindexingSorting_Indexing0

To test that it worked I set the cube at that index to a red material, sadly I do not have a screenshot of this but there were red cubes.

Sorting_ColouringTest

In the testing, the cubes at (0, 0) and (width, height) were in the correct positions in the array; however, due to the way I was removing the duplicate vertices, they were not all sorted causing some rows to be jumbled with the next. I changed the debug cube to also have a Text Renderer that I show the position in the array on.

Sorting_UnsortedDefaultOrder.PNG

My original instinct was to implement my own sorting algorithm in blueprint or C++, in theory i would be able to use the same indexing formula as my comparison for checking, however this would be very time consuming. Instead i found that TArray already has the function TArray::Sort() so I wrote a C++ function that would use it and return the sorted array.
Sorting_UsingSortFunction

TArray UMyFunctionLibrary::Sort(TArray points)
{
    // use TArray::Sort using my predicate to sort the array
    points.Sort(SortPredicate);
    return points;
}

// Function that TArray::Sort can use to compare FVectors
bool UMyFunctionLibrary::SortPredicate(const FVector & a, const FVector & b)
{
    if (a.Y < b.Y)
    {
        // if a's y is less we know it has to be before b
        return true;
    }
    else if (a.Y == b.Y && a.X < b.X)
    {
        // if they're at equal y, if a's x is less than b's x, true
        return true;
    }
    else
    {
        // else b is before a
        return false;
    }
}

It’s worth noting that for simplicity’s sake I used multiple if statements in my predicate function and not the more elegant formula. It is possible that using the formula could be faster but it was quicker to write and is more easily read when using this solution.

Sorting_sorted

Here you can see the successfully sorted array, ready for me to start calculating the slope data.

Group Project Dev Log – 09/02/2018

This week has been productive; all tasks have been completed on time and effective sprint planning and daily scrums have kept the project on track. Some tasks had underestimated story points assigned to them, an example would be Issue #26 as it took longer to complete than expected as i had wasted time attacking the problem from the wrong angle.

Feedback from the art doc was good, I am confident that my vision is well defined in the Style Guide and that the asset list is concise. No art has been completed this week due to time constraints on the artist however it is scheduled to be completed over the weekend.

I worked on fixing/completing the Loop Detection code, Previously it was inconsistent and unfair however now it works better and allows for a the grace period to be after the song too, allowing the player to be slightly late and still register the tap as looping.

Next week I will be continuing the daily scrums with my course leader (producer), I will be adding in the new artwork as it rolls in. Top priority is starting the process of attaining the rights to use the music in the game. Finally I will be adding the analytics functionality into the project as well as implementing Ads.

Sprint 3

Capture

Group Project Dev Log – 06/02/2018

This week I found an artist interested in working on the game so I started both a Visual Design Document and Asset list for her to work on.

Now I have a better idea of what I would like the game together I have created a new scene with placeholder artwork ready to replace with the final artwork when it rolls in.

Next Week I am continuing to work on the Visual Design Document / Asset List and finishing the User Stories on the Core Game Loop.

Sprint 2

Capture

Optimising The Debug Cubes

As I mentioned in the last post, Spawning cubes using the Vertex list was very slow at the higher detail levels due to there being multiple vertices overlapping, such is the nature of meshes. I Will likely not be using the raw vertices for very long however as a small exercise I wrote a small function to remove duplicate vectors from the array, and the results were very successful.

The function runs through all of the vectors in the input array, Checks whether the new array already contains it, if not it gets added to the new list. The new list is then returned.

VertListOptimisation

I also tidied up the level blueprint when adding in the new function by using a sequence, this serves no purpose other than to make the code look nicer and easier to read. I also added a “Print Text” node to write the number of vectors in the list to the screen.

OptimisedCubeSpawning

Firstly I ran the level with the optimisation node disconnected so that I could see both how long it took to run and note down the number of vectors, Then I reconnected the node and ran again, taking note of the number of vectors.

The results were really impressive, Without the optimisation it took ages to start the level and it was incredibly laggy, this was down to the 55,296 cubes that were spawned in, many of which were overlapping each other. With the optimisation it started almost immediately with only a little frame lag and an impressive 9,409 cubes spawned. I will also make it clear that there were the same number of cubes visible so I had only removed duplicate cubes.

Unreal 4 Custom Terrain Node

A Brief Introduction

This week I started work on creating the custom nodes I need in Unreal Engine 4 to create my procedural vegetation tool.
UE4’s documentation is well none for being lacking however when it comes to creating custom blueprint nodes it is exceptionally more difficult to find useful information on the subject and I spent many hours banging my head against a brick wall getting nowhere.

My goal for this week was somehow getting access to the data contained within the Landscape class, as this is not possible to do with blueprints I had to look into custom node creation, which in Unreal engine is called a Blueprint Function Library.

Writing a custom node in C++

You can create a Blueprint Function Library by right clicking in the content browser, selecting “New C++ Class…” and selecting “Blueprint Function Library”.

When Writing a custom node you must put UFUNCTION() before your function, in this you can define how the blueprint editor will see your node, name it and define various keywords for searching. Blueprint functions must all be public and static.

Pins

What I have gathered so far is that pins are assigned as the parameters in the function signature; Pointers and Variables are inputs, References and the return type are outputs (if not void). I want to take in the Landscape object, an int to use as the level of detail for exporting the mesh and to return an array of vectors for the vertices, the function parameters are as follows:
ALandscape * landscape, int sampleLod, TArray &amp; points

The documentation shows that the parent class of a landscape actor(ALandscape) is ALandscapeProxy which has the functionality to export the mesh data to an FRawMesh struct so I added an include for “Developer/RawMesh/Public/RawMesh.h”. The RawMesh struct is not available in Blueprints so I use the points referance, I set it to the vertex array in the raw mesh.

Problems

An important point that is missing from the documentation is that you have to manually add modules to the .build.cs file for the linker to actually link the various libraries that the RawMesh and Landscape classes are in. This is done by adding the module names to this line in the build file:
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "RawMesh", "Landscape" });
I assume that the module names are the same as the header files that you include like they were in my case however I do not know as the documentation surrounding the build system is very complicated.

Finished Code

Here’s my finished code:

// in Header
UFUNCTION(BlueprintPure, DisplayName = "Get Landscape Stuff", Category = "Landscape Helpers")
static void GetMesh(ALandscape * landscape, int sampleLod, TArray & points);

// in Cpp
void UMyFunctionLibrary::GetMesh(ALandscape * landscape, int sampleLod, TArray & points)
{
// Raw mesh structure we'll export to
FRawMesh rawMesh;
// Export the landscape to the Raw Mesh using the supplied LOD
// Higher number means lower detail, less points (faster to demo with cubes)
landscape->ExportToRawMesh(sampleLod, rawMesh);
// Finally put the vertex positions in the raw mesh to the points array referance
points = rawMesh.VertexPositions;
}

It is important to note that the Editor must be restarted after compiling a custom node for it to show up in the blueprint editor, this can be time consuming and the docs do not mention it but if you are unable to fund your nodes or they are not showing the right pins, try restarting the editor.

Here’s my node in the blueprint editor:
Node

To check that I was getting the correct data I spawned a cube at each point in the array, This is very slow when using the lower LOD value, this is because the vertices are per face, in theory meaning that all vertices are duplicated 8 times (not including on the edges of the terrain, however here’s the node setup:

terrainLevelBP.PNG

This gave the following render, a successful result.

CubesOnLandscape

Pink Fluffy Project Management

This week I have started development on my second rapid prototyping game, a gamification of a button app, I wondered what would happen if you gave a player a button that plays a music loop and then gave them points for looping it; This is the basis for the game I am currently creating.

This week (and last friday) has been mostly project planning and design, I already had a base prototype of the game which had the button, score and high score.

For this project i am using Agile and Scrum, I chose to use Github with the Zenhub plugin, this adds more agile functionality to Github’s existing issue tracking features.

Prior to this I had used Jira on my degree however I had never fully embraced Agile with things like Epics and even correctly writing user stories, Atlassian have a fantastic guide on Epics, stories, versions, and sprints which helped me to understand how i should be writing user stories, arranging them into Epics and Zenhub’s method of assigning abstract points to user stories as a way of gauging the complexity of tasks feels far sensible than purely working on time estimates for the entire project.

I have also designed the game in terms of user stories in place of writing a design doc, it was far more simple and allowed me to really quickly see the scope of the game as a whole and see what user stories should be converted to epics and more finely chopped up into smaller stories.

Here’s a list of resources I found useful when setting up the project from a management perspective: