Author: avin

  • Unity Web build configuration

    I always have issues when publishing to a Unity Web target – usually the issues stem from compressed builds. Here is the configuration I use.

    Build Profiles / Platform Settings

    • Set Code Optimization to Runtime Speed rather than Shorter Build Time

    Player Settings

    • Set Company Name
    • Set Product Name
    • Set Version

    Player Settings / Resolution and Presentation

    • Set Default Canvas Width and Height to same as game
    • Set WebGL template to PWA
    • Set Product Description

    Player Settings / Other Settings

    • Set Managed Stripping Level to Minimal (if you get errors with the default of Low)

    Player Settings / Publishing Settings

    • Set Compression Format to Gzip

    Apache 2

    Add a .htaccess file with the content from the section Use the virtual host in .htaccess method.

    Ensure the user and group of the folder is set to www-data:www-data (chown) otherwise the Content-Type set in the .htaccess is not run (despite the .htaccess file is still parsed and shows up in the Apache error log).

  • Asteroids

    It’s been a while (I got busy with a new job, and kind of forgotten about doing this gaming series), but the next game I’ve made using Unity is an Asteroids clone. Source code on GitHub.

  • Pong

    The next game I’ve made using Unity is a Pong clone. Supports two players on keyboard. Source code on GitHub.

  • Snek

    The next game I’ve made using Unity is a Snake clone – Snek. Supports two players on keyboard. Source code on GitHub.

  • Floppy Bird

    I’ve played around with Unity a few years ago (which never eventuated in anything), Roblox Studio last year (which was great to introduce programming to my kids), and Unreal Engine this year (which I felt was overwhelmingly the most difficult). I’ve come back to Unity with a view of recreating some simple games to understand their mechanics and keep me up-to-date on C# and .NET. The first game I’ve created is a Flappy Bird clone, and I got my kids to help me with the graphics for the game.

    Thanks to the WebGL compilation target, you can play it here (use space or click/touch to fly) and and find the source code on GitHub.

  • Theming Power BI Organizational Custom Visuals

    I’ve recently created a Power BI Custom Visual for our BOQ report headers, as we have a specific header visual style that we want all reports to have:

    Normally when theming a custom visual that you import as a file, you just need to use the guid property of the custom visual (in pbiviz.json) as the key in the theme JSON file. For example, we use BOQGroupHeader in both pbiviz.json and theme.json:

    pbiviz.json

    {
        "visual": {
            "name": "BOQGroupHeader",
            "displayName": "BOQ Group Header",
            "guid": "BOQGroupHeader",
        }
    }

    theme.json

    {
        "visualStyles": {
            "BOQGroupHeader": {
              "*": {
                "background": [
                  {
                    "show": false
                  }
                ],
                "title": [
                  {
                    "show": false
                  }
                ]
              }
            }
        }
    }

    However, when users download the custom visual from Power BI Service as a Organisational Visual, the theme file does not work. This is because Microsoft must change the guid property of the visual to ensure it doesn’t collide with file imported visuals vs Organisational Visuals.

    If you open up the pbix file, you can find that Microsoft add a suffix of _OrgStore to the Organisational Visual, and this needs to be added to the theme file for the custom visual then to use that theme.

    So our new theme.json looks like:

    {
        "visualStyles": {
            "BOQGroupHeader_OrgStore": {
              "*": {
                "background": [
                  {
                    "show": false
                  }
                ],
                "title": [
                  {
                    "show": false
                  }
                ]
              }
            }
        }
    }
  • Trimming and fading out video/audio with ffmpeg

    I recently wanted to trim and fade out an MP4 file. I wasn’t inclined at the effort of putting it in a non-linear editor and was looking for a quick way to achieve this.

    I found that ffmpeg had the necessary functionality to do this. The command I used in the end was:

    ffmpeg -i in.mp4 -ss 00:00:00 -t 00:05:00 -vf "fade=t=out:st=297:d=3" -af "afade=t=out:st=297:d=3" out.mp4

    The commands are:

    • -i in.mp4 is the input file
    • -ss 00:00:00 is where the video should start from (set this to other than zero to trim the start)
    • -t 00:05:00 is the duration of the video, trimming any video after that
    • -vf "fade=t=out:st=297:d=3" is a video filter which fades out at 297 seconds (4:57) over a 3 second duration
    • -af "afade=t=out:st=297:d=3" is the corresponding audio filter which fades out at 297 seconds (4:57) over a 3 second duration
    • out.mp4 is the output file

    The video and audio filters have several more properties you can play with, such as if you want to fade to white using a log curve for the audio fade.

    You can also combine filter commands by separating them with a comma, if you want both a fade in and fade out, for example:

    -vf "fade=t=in:st=0:d=3,fade=t=out:st=297:d=3" -af "afade=t=out:st=0:d=3,afade=t=out:st=297:d=3"

  • Finding overlapping MIDI notes

    I’ve been using Beeano Midi Player to visualise MIDI tracks on a piano roll for inclusion in piano tutorial videos. As the software doesn’t support the sustain pedal for indicating the duration of a held note, I’ve been extending a note in the MIDI track to occupy the entire held duration, and at the same time, using quantisation. Beeano is a bit temperamental processing overly quantised MIDI tracks, where two held notes of the same pitch that are snug against each other are considered overlapping. Beeano plays the first note, but cuts out for the second overlapping note in the visualisation.

    MIDI doesn’t have the concept of a note duration; instead a held note is represented by a MIDI on event at a pitch and a MIDI off event at the same pitch to represent a held note. In addition to the MIDI off event, the MIDI spec also indicates that a zero velocity MIDI note on can also represent the end of a note.

    A prevention method for these overlapping notes is to not overly quantise notes such that note ends finish at the same time as the next note (at the same pitch) starts. However, if that is required, instead of checking each note, a quick remediation method is to select all notes in the track using a sequencer, and decrease the length a few ticks.

    I found this last step helped immensely with my tracks, but I was still finding the occasional overlapping note when running through Beeano. This could be due to the recording device, but I’m not sure.

    To detect these overlapping notes, I wrote a quick Python script that would report on these overlaps. This helps narrow the search down trememdously.

  • Monophonic filtering using Scripter in Mainstage/Logic Pro

    I was recently building a patch in Mainstage where I wanted both a string/pad as well as a bell sound that would accent the top note of each chord that I played. I looked around for a technique to only keep the top note in a chord for Mainstage, and came across this post; but unfortunately the linked site for the Polyphonic Filter was not accessible. But it pointed me towards the Scripter plugin.

    The Scripter plugin in Mainstage/Logic Pro allows Javascript to handle the MIDI signal. Based on some examples from Apple, I created the following script, which keeps the top-most note in a chord and silences the lower notes. I put this script just on my bells channel strip, so the string/pad wouldn’t be affected.

    The result was a little hit and miss in a live setting – it worked when I played ascending chord progressions, but was inconsistent when playing descending progressions, depending on when my fingers hit the keyboard. The script would be ok in a sequenced performance where you can specify the order of notes being played. I needed it in a live performance; I ended up not using the plugin, and just played the bells accent separately with my right hand and string/pad chords with my left hand.

  • Extracting legend symbology from ArcGIS Server Map Services

    Our user experience team were looking to do a refresh on our symbology that we use for our Map Services that we host on ArcGIS Server. They wanted to see all symbols used in the map service so they could pass it on to our graphic designer to redesign the icons. While you can see each symbol by adding /legend to the map service URL, there was no way to see all symbols on a single page. There isn’t any native way in ArcGIS Server or Desktop to be able to easily extract this either.

    My first approach was to try and use Javascript to iframe each Map Service legend page into a single HTML page. But due to the same origin policy being set on the web adaptor of our ArcGIS Server machines, this wasn’t feasible.

    Instead, I wrote a Node.JS script to scrape the symbols from ArcGIS Server using Puppeteer. The script handles map services that only have a single symbol vs grouped symbols, and only outputs the unique symbols.