Make Us Go

I’m not really an engine, tools, build, automation, localization, or audio engineer.

I’m a Get It Done engineer, which informs the kind of work that I typically do. I like working on projects where I can interact with my customers directly, and I also deeply like projects that help others get their work done.

Three aspects have stood out that I find compelling:

Visibility

I like setting up feedback loops so the knowability of the basic state of the product is readily available. Does it compile? Is content all present and working? Do tests pass? Do the people who have a stake in the state of the product have the means to know what it is? Are the people who have made changes confident that their change works correctly and doesn’t impact others?

Productivity

I am fond of the quote, ‘The most powerful force in the universe is compound interest’ (apocryphally attributed to Einstein). A percentage improvement to the engine, processes, assets, and/or toolchain that results in faster development times is a win, as that percentage difference accumulates for each person daily.

Availability

I want to maximize the reach of whatever I work on. I want what I do to connect with the largest audience possible. This is why I love localization, dialogue, and narrative systems. I want everyone to hear the story, connect, and feel represented.

I do not favour elaborate frameworks or attempting to design everything beforehand. I’ve seen numerous attempts to do so fail because those efforts lose sight of the problem being solved. I prefer organic growth and feedback loops with whoever is using the system being built to progressively refine to actual needs. I think that various coding methodologies are useful in proportion to the churn in the code, facilitating scaling up code to maximize clarity and resilience to change. This is why I like Kanban: it is clear what the most important tasks are and targeting them.

CI/CD Scaling for Multiple Projects

While building the Jenkinsfile.groovy for a single project is straightforward, we want to share the logic across multiple C# projects.

I won’t go into the details as I did with my other posts about the process I went through. I moved the logic for Jenkinsfile.groovy into a Jenkins shared library, which is publicly available at Jenkins Library Sample.

Continue reading

CI/CD Code Coverage

Code coverage measures how much of the code is covered when running tests. This is a useful indicator of how effective tests are. One of the features we want to add is to set a minimum bar for testing to increase the quality of our components.

Visual Studio 2022 Community Edition doesn’t automatically include code coverage features out of the box. There are some things we can do to expose it in Jenkins during our build processes, validate the results, and possibly fail the build based on it. Within Visual Studio itself, you can install Fine Code Coverage from the Visual Studio Marketplace or consider tools such as NCrunch.

Adding additional steps to Jenkins won’t take long to get code coverage data and expose it on the Jenkins build page.

Continue reading

CI/CD Publishing NuGet Packages

Initially, when building C# projects, I would have multiple solutions directly referencing the projects to be built. Sometimes, the solutions would have an extraordinary number of projects in them, so I could update them all in parallel.

However, this isn’t an ideal scenario as it makes it easy to blend code and develop tighter dependencies between modules that make future software development harder. By decomposing projects into smaller, more discrete and manageable components, we can increase the rigour around changes we make and have greater confidence in the code quality.

The use of NuGet to store versions of my packages means the applications I build can be small and lean and can work with already-defined mechanisms for publishing and retrieving packages.

I don’t want to publish my personal NuGet packages to a public repository (at least not without developing some confidence in the process first). So I have set up a Sonatype Nexus Repository to host NuGet packages.

I’ll go through the steps for configuring the Nexus Repository, Jenkins, and Visual Studio projects.

Continue reading

CI/CD Building a C# Project in Jenkins

The goal for this stage of development is to get our C# project listed in Jenkins and building. The next iteration will be adding testing.

This step follows the work from CI/CD Scanning GitHub for Repositories from Jenkins, where Jenkins is set up to scan for projects, but it now needs the files required to build.

Continue reading

CI/CD Scanning GitHub for Repositories from Jenkins

The next step is to get Jenkins to search GitHub for repositories to build.

I want all the projects in my GitHub repository that qualify to be built automatically, so if I add a new project with the right setup, it will automatically build it.

This can be achieved by having Jenkins scan your GitHub repository to gather all projects. GitHub supports pushing to Jenkins when repositories change, but that is more complicated when Jenkins is behind a firewall and cannot be directly contacted (we’ll be relying on polling in this case instead).

Continue reading

Unreal Engine & Localization

The Unreal Engine has some rather nifty functionality for dealing with localization. We have also made numerous modifications to facilitate our workflow, but I’ll stick to what is in vanilla Unreal (this is based on 4.25).

There are three different string types to use within Unreal:

  • FString: These are traditional strings most people are used to. When creating a new string it will allocate memory to store the data. Equality comparisons need to check the actual string data.
  • FName: When you create a name, it is stored in a table in memory permanently (there is no clean up of unused names). Two FNames with the same value point to the same index, which makes equality comparisons very fast: they just compare indices. But the memory usage can grow without bound.
  • FText: These are localized strings that go through a process of being gathered, translated, and having their values stored in a separate file called a locres file. When evaluating an FText, there is a lookup for the actual value to use.

Epic provides a tokenization system using curly braces, { and }, where you can provide parameters (either positional or named) for an FText format string.

However, we added another one using square brackets, [ & ], where we would take the token within and look up the value as an FName in various tables that were provided to look up information.

Continue reading