BorsukSoftware.Utils.StreamMerging released

As part of a project we’re working on, we needed to be able to consume multiple chunks of compressed data on disc as a single uncompressed stream. We couldn’t find any existing libraries to do this so we had to create our own and as it’s rather generic, we thought we’d share it in case anyone else finds it useful.

It currently targets .net standard 2.1 in order to use instances of Span<..>, but it can also be modified relatively easily to use .net standard 2.0.

The package can be downloaded from nuget and the source code is available on our GitHub page.

Borsuk Software is now on nuget.org

We’re pleased to announce that, where appropriate, our .net libraries are now available for consumption directly on nuget.org.

The source code for each of the packages is available on GitHub.

Currently, we have packages for:

  • Data Cube
  • Object Flattener
  • Object Comparer

Further packages will be uploaded shortly (including an updated object graph which is coming soon).

For more details on the underlying functionality / rationale behind these packages, please see their respective repositories in GitHub.

Please do let us know if you use these packages or if you have any suggestions etc. This can be done either by commenting or through GitHub issues.

Using native Nuget packages

Nuget packages have become the de facto way for .net libraries to be consumed by other projects and interestingly, Microsoft also use this technology to supply some of their C++ libraries – specifically they use this to provide the code used to connect to Xbox Live (Microsoft.Xbox.Live.SDK.Cpp.UWP). This got us thinking as to how to best share common code between our games. This shared code is within a library called BorsukCore.

Initially, we had the following approach to a clean build:

  • Build BorsukCore (Includes our custom code, the DirectX toolkit and a few other libraries)
  • Build SpacegirlCore
  • Build SpacegirlWindowsCore
  • Build Spacegirl (Win32 build)

Note that we had an equivalent build step for the UWP build (to cover the MS store / X1) and this doesn’t show the testing projects.

This meant that not only each time that a change was made to BorsukCore, the whole build would be performed, but that was also true for each change on the main game code. This increased the turn around time for each iteration. This wasn’t too bad for SG1, but got annoying when this was SG2 came along.

To that end, we set out to change matters by creating Nuget packages for the various projects built as part of BorsukCore. We mimicked the approach of MS by having separate Nuget packages for header files and .lib files. This left us with:

  • BorsukSoftware.Games.BorsukCore – headers
  • BorsukSoftware.Games.BorsukCore.x64 – libraries for both debug and release builds

We also have similar packages for our build of GoogleTest (which we use for unit testing the C++ game code), as the implementation of these is identical to the main ones, we don’t go into the details of these.

Structure of the packages

BorsukSoftware.Games.BorsukCore

  • build
    • native
      • include (directory)
      • BorsukSoftware.Games.BorsukCore.targets

BorsukSoftware.Games.BorsukCore.x64

  • build
    • native
      • lib
        • x64
          • debug (directory of libs)
          • release (directory of libs)
    • BorsukSoftware.Games.BorsukCore.x64.targets

NB It’s really important that the names of the .targets files are the same as the containing Nuget package otherwise when one tries to add them later in Visual Studio one will get infuriating errors.

Building the packages

There are lots of articles already available on the web detailing how to build the packages. The following are probably the best starting points (we used these to guide us)

Note that article #2 is wrong when it says that VS doesn’t do anything to help. If the .targets files are named consistently with the name of the package then VS will be your friend! This point is made clear in article #3.

Uploading the packages

This entirely depends on the CI process that one uses. We have a CI job which:

  • builds the core libraries in both debug and release modes
  • Runs the unit tests
  • Creates the packages from the .nuspec files
  • Uploads them to our internal repository

Consuming the packages

Once the packages have been uploaded, then one can simply add a Nuget reference to them in VS and everything should work. VS will automatically add a link to your .targets file from the project’s file. If this doesn’t happen, then this is usually because the .targets file isn’t named consistently with the name of the Nuget package.

Summary

By moving to the nuget packages approach we were able to improve our development experience both by avoiding the need to rebuild everything on each commit (~3 minutes a time) and also making it easier to put together prototypes using the common library.