<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
	<channel>
		<title></title>
		<description></description>
		<link>http://www.angryant.com</link>
		
			<item>
				<title>New Gear</title>
				<description>&lt;p&gt;In 2015 I did a review of my &lt;a href=&quot;https://www.angryant.com/2015/02/26/Trusted-Gear/&quot;&gt;active toolbox&lt;/a&gt;. As obviously a lot has changed since then, particularly with pandemic-mode operations, I figured an update would be appropriate.&lt;/p&gt;

&lt;p&gt;I had hoped to have done a post on a new build agent setup we are working on, but unfortunately JetBrains support are still having some trouble replicating problems we are experiencing with Linux-based TeamCity Unity build agents. You will just have to look forward to that - hopefully not too far into the new year.&lt;/p&gt;

&lt;p&gt;A central theme in the current toolbox is self-hosting and flexibility in general. Third party provided services are great until you get near the edge of intended use cases - which usually works well, but holds the capacity to (hopefully only) slightly frustrate every project flow you go through. We first dipped our toes in self-hosting some services pre-pandemic but since moving to be fully distributed we went all in - to the point of currently only relying on external services for text chat, email, and mobile build distribution.&lt;/p&gt;

&lt;p&gt;That said, I will strive to keep the format of the earlier post - focusing primarily on local machine tools. So as mentioned the update here is flexibility and obviously a use case change as well, given the steep drop in need for working on the go.&lt;/p&gt;

&lt;h2 id=&quot;platform&quot;&gt;Platform&lt;/h2&gt;
&lt;p&gt;The 2013 MacBook Pro got retired - initially in favour of a company workstation at the office and a personal one at home, for once pieced together from parts matching &lt;em&gt;my&lt;/em&gt; needs rather than the sales considerations of a manufacturer of prebuilts. Moving our operations fully distributed, resulting in the company workstation moving in with me, the personal workstation then got converted into a server - replacing the basic Synology box which had previously been sufficient for the limited services we self-hosted when sitting multiple non-family-members in offices were a thing.&lt;/p&gt;

&lt;p&gt;This change of hardware platform obviously meant a move away from macOS - marking the first change in the toolbox. Prior to retiring the laptop I had started dual booting &lt;a href=&quot;https://ubuntu.com/download/desktop&quot;&gt;Ubuntu&lt;/a&gt; on it in order to gauge how far the Linux desktop experience had moved since last I had a look at it. A clear goal in general was an increase in flexibility - not just limited to hardware choice, so if given an actually modern and fully functional desktop experience I was definitely going to prefer Linux over Windows. At the end of my trial run I was satisfied with the experience and had gradually moved to cross-platform software on the macOS installation as well - in order to reduce the number of new things I would need to deal with when jumping completely.&lt;/p&gt;

&lt;p&gt;After landing well on the new platform and properly acclimating I did move around a bit before settling on my current setup, but as a migration point &lt;a href=&quot;https://ubuntu.com/download/desktop&quot;&gt;Ubuntu&lt;/a&gt; (with the default &lt;a href=&quot;https://www.gnome.org/&quot;&gt;GNOME&lt;/a&gt; desktop environment) was excellent. For anyone doing the research today I would recommend trying out &lt;a href=&quot;https://zorin.com/os/&quot;&gt;Zorin OS&lt;/a&gt; as the migration point in stead - regardless of where you consider migrating from.&lt;/p&gt;

&lt;p&gt;I prefer to not use headspace for more tools than necessary, so I opted to use Ubuntu server for our self-hosted efforts - in order to work with the same underlying tooling available in the terminal application of my desktop. The before-mentioned moving around did eventually see me leave Ubuntu for both use cases - in favour of &lt;a href=&quot;https://nixos.org/&quot;&gt;NixOS&lt;/a&gt; as the underlying system, with &lt;a href=&quot;https://kde.org/plasma-desktop/&quot;&gt;Plasma&lt;/a&gt; as the desktop environment on my workstation. Note that while &lt;a href=&quot;https://kde.org/plasma-desktop/&quot;&gt;Plasma&lt;/a&gt; may initially look to be “the Windows experience but on top of Linux”, the primary selling point of the environment is accessible customisation. If I were to describe my current setup in more familiar terms, it would probably be: a macOS-like header bar &amp;amp; launcher, no dock, window auto-tiling, and a functionality-focused high-contrast if dark colour scheme. You can basically adjust it to your hearts content, making it an optimal fit for your particular flow - which is what drew me to it.&lt;/p&gt;

&lt;p&gt;I would not recommend &lt;a href=&quot;https://nixos.org/&quot;&gt;NixOS&lt;/a&gt; as a migration entry point, but long term the paradigm shift is well worth it to me. The advantages are numerous, but personally I am mostly drawn by the declarative OS configuration enabling a single text file to describe a complete system and all of its settings. The flexibility on Linux is great, but just like any other system there are a ton of different locations to review &amp;amp; configure the full experience (Windows settings applications meme: Engage!). Having a single file I can use to quickly review what a system is and to modify it is absolutely excellent. It is no animated semi-transparent GUI of smooth loveliness, but I’ll take it.&lt;/p&gt;

&lt;p&gt;For control over hardware resources, service segregation, and advanced tools management I have opted to run a hypervisor on both server and workstation. Aside from massive cloud servers and game consoles, hypervisors are great for configuring and running a number of personal virtual machines on the same hardware - in particular when you have clearly segmented services and goals to work with. From a security standpoint network segregation in this environment is not as solid as with individual machines, given that virtual machine escape exploits are a thing. However neither my private nor our company threat model includes threat actors with the necessary budget and given that the alternative is third party services susceptible to the very same attacks, this configuration is entirely acceptable. This setup means that my day to day desktop experience is actually a virtual machine. Though with a dedicated graphics card and plenty of resources &amp;amp; CPU priority associated that distinction is entirely unnoticeable. In addition to this primary VM, the workstation runs a router for the different VMs, CI agents for the different projects, and other tools like distributed bake &amp;amp; generative services, devkit tools with picky environment requirements, and that sort of thing.&lt;/p&gt;

&lt;p&gt;As an aside, I also ended up running &lt;a href=&quot;https://nixos.org/&quot;&gt;NixOS&lt;/a&gt; on my tablet - though here I opted for &lt;a href=&quot;https://www.gnome.org/&quot;&gt;GNOME&lt;/a&gt; rather than &lt;a href=&quot;https://kde.org/plasma-desktop/&quot;&gt;Plasma&lt;/a&gt; as the desktop experience. While explicitly not designed for touch devices, I find it the better experience of the two on such hardware. In addition to buttery smooth regular reading of books &amp;amp; comics + browsing + media activities, the gaming experience on the tablet is great - using Steam in-home streaming to run games from a VM on the server running an attached dedicated graphics card, with controls either via touch or the excellent Steam Controller. This on a minimum-spec dual-core device with four gigabytes of memory.&lt;/p&gt;

&lt;h2 id=&quot;tracking&quot;&gt;Tracking&lt;/h2&gt;
&lt;p&gt;OmniGroup only develop their software for the fruit company ecosystem, which meant I would of-course have to find an alternative to OmniFocus. Given the difficulty in finding a suitable project &amp;amp; TODO tracking solution described in the last toolbox post, this was by far the toughest workflow change.&lt;/p&gt;

&lt;p&gt;Thankfully our self-hosting journey overlapped nicely with the local toolbox change here as I found an excellent combination of user experience and flexibility in the &lt;a href=&quot;https://www.jetbrains.com/youtrack/&quot;&gt;YouTrack&lt;/a&gt; solution we were already using for company project tracking. While a fully hosted version is available as well, we had already opted for self-hosted in order to more easily run some custom integration with the rest of our flow. The resulting setup is one install for the company, one for the family, and optionally one per project if it involves tightly integrated external parties.&lt;/p&gt;

&lt;p&gt;The underlying data structures can have a whole lot of fields associated with each task/entry - making it a full Jira-like complex beast if that is what you want - or a simple TODO app if that is more your target. Combined with a mobile app and a very flexible system of searches/queries bookmarked or exposed in lists, dashboards, reports, and agile boards, I have found that I can easily tailor an experience to anything from a complex project through small efforts to grocery shopping without slamming into too many walls or facing highly “enterprisey” experiences for very simple use cases.&lt;/p&gt;

&lt;p&gt;For flow integration we use the official &lt;a href=&quot;https://www.nuget.org/packages/YouTrackSharp/&quot;&gt;.net API&lt;/a&gt; - as we as much as possible strive to standardise all our code- &amp;amp; data base to C# and markdown respectively. The experience here has been great as well. We have primarily used the API to update other systems based on changes in tasks, but our wishlist does currently include more bidirectional integration which should be fully supported by the API.&lt;/p&gt;

&lt;p&gt;My calendar is still a central part of my day to day flow - essentially feeding tasks from the tracker through a planning phase and into the calendar. Continuing to use the iCloud calendar setup either through the web app or integrated with a local client is an option, but for forward-looking flexibility and a more stable experience I have opted for a self-hosted solution here as well. A couple of options are available here but probably of most broad appeal would be the CalDav service built into &lt;a href=&quot;https://nextcloud.com/&quot;&gt;Nextcloud&lt;/a&gt;. So long as the service runs https, you can add the account to iOS just fine and on the desktop I have worked with a couple of different options until finally settling on the very lovely, but still-pre-release &lt;a href=&quot;https://apps.kde.org/kalendar/&quot;&gt;Kalendar&lt;/a&gt; project.&lt;/p&gt;

&lt;h2 id=&quot;typing&quot;&gt;Typing&lt;/h2&gt;
&lt;p&gt;Since the last toolbox update the life of this typist has improved significantly. While &lt;a href=&quot;https://www.sublimetext.com/&quot;&gt;Sublime Text&lt;/a&gt; is still great and a very important part of my toolbox, OmniSharp unfortunately did not last as a stable experience. Thankfully &lt;a href=&quot;https://www.jetbrains.com/rider/&quot;&gt;Rider&lt;/a&gt; picked up that slack and then some, offering a rock solid IDE with an extensive suite of tools and of-course neat integration with the other JetBrains products in our arsenal. As a tool for .net and Unity development, &lt;a href=&quot;https://www.jetbrains.com/rider/&quot;&gt;Rider&lt;/a&gt; has been a no-brainer for a while. Praise aside, particularly for our IL patching workflows I am not really satisfied with the assembly/IL browsing functionality of &lt;a href=&quot;https://www.jetbrains.com/rider/&quot;&gt;Rider&lt;/a&gt; when it comes to external assemblies rather than the assembled result of a loaded project. For this need I am still a very happy camper with the &lt;a href=&quot;https://github.com/icsharpcode/AvaloniaILSpy&quot;&gt;Avalonia ILSpy&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;Worth noting when speaking of &lt;a href=&quot;https://www.sublimetext.com/&quot;&gt;Sublime Text&lt;/a&gt; is &lt;a href=&quot;https://www.sublimemerge.com/&quot;&gt;Sublime Merge&lt;/a&gt; - another newcomer since last update. While &lt;a href=&quot;https://git-fork.com/&quot;&gt;Fork&lt;/a&gt; is still excellent and would be my first recommendation to anyone, &lt;a href=&quot;https://www.sublimemerge.com/&quot;&gt;Sublime Merge&lt;/a&gt; offers better platform support and an interface striking just the right balance for me between simplification and utility.&lt;/p&gt;

&lt;p&gt;Given that we standardise on markdown as much as possible, expanding the toolbox with a dedicated markdown editor only made sense. While it offers a lot more than just that, &lt;a href=&quot;https://obsidian.md/&quot;&gt;Obsidian&lt;/a&gt; is my pick for markdown editing. At time of writing the WYSIWYG editor is very freshly released, but none the less it is my daily driver for the purpose.&lt;/p&gt;

&lt;h2 id=&quot;searching&quot;&gt;Searching&lt;/h2&gt;
&lt;p&gt;Developed specifically for the fruit company ecosystem, &lt;a href=&quot;https://kapeli.com/dash&quot;&gt;Dash&lt;/a&gt; is another previously mentioned tool in need of replacement. Thankfully the developer is very open to clients on other platforms having great access to the largely-community-supplied documentation packages. The consequence is a healthy selection of alternatives, of which I went for &lt;a href=&quot;https://zealdocs.org/&quot;&gt;Zeal&lt;/a&gt;. Available on Linux, macOS, and Windows, this offline documentation viewer is just as excellent a tool to me as &lt;a href=&quot;https://kapeli.com/dash&quot;&gt;Dash&lt;/a&gt; was on macOS.&lt;/p&gt;

&lt;p&gt;I honestly did not really have much use of the editor integration of &lt;a href=&quot;https://kapeli.com/dash&quot;&gt;Dash&lt;/a&gt; in the past, so only having the global shortcut + search tags for accessing &lt;a href=&quot;https://zealdocs.org/&quot;&gt;Zeal&lt;/a&gt; was not a real change for me. Integration may be available, but given the base I was operating on I just did not go looking for it. Thankfully more alternatives are available and perhaps even a fully editor embedded client - in case that is more relevant to you.&lt;/p&gt;

&lt;h2 id=&quot;navigation&quot;&gt;Navigation&lt;/h2&gt;
&lt;p&gt;Before the platform &amp;amp; services shift mentioned throughout this write-up, I decided to complete my workstation ergonomics by looking at peripherals which for some inexplicable reason I had ignored through years of paying attention to desk, lighting, seating, and monitors. Perhaps the reason is that this aspect of ergonomics has an odd air of fringe vs. the other aspects.&lt;/p&gt;

&lt;p&gt;Previously I had been using a flat wireless keyboard with short key travel and a nicely large wireless touchpad. There are a ton of options and semi-religious opinions in this area, but after a while I settled on a vertical wireless mouse (a regular mouse where your hand orientation ends up more vertical than regular horizontal) and a mechanical split keyboard. I found the &lt;a href=&quot;https://www.ergodox.io/&quot;&gt;ErgoDox&lt;/a&gt; open source design very compelling and the number of available options based on it equally so. Aside from being split, the layout is also column stagger rather than the default row stagger - resulting in a more natural primary vertical movement of your fingers rather than constant sideways switching.&lt;/p&gt;

&lt;p&gt;Once I had the board in hand I realised the further room for ergonomic optimisation. Since the available boards implementing the &lt;a href=&quot;https://www.ergodox.io/&quot;&gt;ErgoDox&lt;/a&gt; design are fully customise-able via the &lt;a href=&quot;https://qmk.fm/&quot;&gt;QMK&lt;/a&gt; project, you can use visual editors to redefine key functions as you like or even dive fully into the C-based firmware and write your own custom layout &amp;amp; -functionality there. I used this opportunity to further reduce finger stretch by removing use of some keys entirely and moving other functionality to layers (while not accurate, if you think if the shift key as changing the keyboard layout to a layer of capital letters and different symbols, you have the general idea) - including a numpad and pre-baked shortcut keys like the &lt;code class=&quot;highlighter-rouge&quot;&gt;copy&lt;/code&gt; key you double-tap to &lt;code class=&quot;highlighter-rouge&quot;&gt;cut&lt;/code&gt; or the word left/right keys positioned just above the left/right arrow keys - which again are flanked by the line start/end keys.&lt;/p&gt;

&lt;p&gt;Combining these ergonomic layout optimisations with baked shortcut keys and function keys mapped in &lt;a href=&quot;https://kde.org/plasma-desktop/&quot;&gt;Plasma&lt;/a&gt; to different functionality in different applications (like the macOS shortcut mapping demonstrated in the last toolbox post), my work environment took a significantly step forward on ergonomics, functionality, and sheer accessible speed.&lt;/p&gt;

&lt;p&gt;As a bonus, the &lt;a href=&quot;https://www.ergodox.io/&quot;&gt;ErgoDox&lt;/a&gt; board I opted for came with per-key LED lighting. As I understand it you are supposed to utilise this for fancy animated effects, providing a clear speed &amp;amp; precision boost when gaming - and while I could certainly use both, I opted instead for using it to highlight key functions in the active layer - like a clear inverted T-shape for the arrow keys or a grid for the numpad etc.&lt;/p&gt;

&lt;h2 id=&quot;wrap&quot;&gt;Wrap&lt;/h2&gt;
&lt;p&gt;And that is about it. All these years later I do not have any current conference plans, but my toolbox certainly keeps adapting to my current needs. Overall I feel much more efficient and flexible in my day to day and am happy to have a feeling of being able to do much more with my local and extended environment - to adapt to personal and company needs on any given effort. I hope that this update has helped inspire you - if nothing else then to review &lt;em&gt;your&lt;/em&gt; current toolbox - perhaps to see if anything in there could stand a revisit compared to available alternatives today.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.angryant.com/2015/02/26/Trusted-Gear/&quot;&gt;“Trusted Gear” post&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://ubuntu.com/download/desktop&quot;&gt;Ubuntu desktop&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://zorin.com/os/&quot;&gt;Zorin OS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://nixos.org/&quot;&gt;NixOS&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://kde.org/plasma-desktop/&quot;&gt;Plasma&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/youtrack/&quot;&gt;YouTrack&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.nuget.org/packages/YouTrackSharp/&quot;&gt;YouTrackSharp&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://nextcloud.com/&quot;&gt;Nextcloud&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://apps.kde.org/kalendar/&quot;&gt;Kalendar&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.jetbrains.com/rider/&quot;&gt;Rider&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.sublimetext.com/&quot;&gt;Sublime Text&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/icsharpcode/AvaloniaILSpy&quot;&gt;Avalonia ILSpy&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.sublimemerge.com/&quot;&gt;Sublime Merge&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://git-fork.com/&quot;&gt;Fork&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://obsidian.md/&quot;&gt;Obsidian&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://kapeli.com/dash&quot;&gt;Dash&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://zealdocs.org/&quot;&gt;Zeal&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.ergodox.io/&quot;&gt;ErgoDox&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://qmk.fm/&quot;&gt;QMK&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
				<published>2021-12-30 00:00:00 +0100</published>
				<link>http://www.angryant.com/2021/12/30/New-Gear/</link>
			</item>
		
			<item>
				<title>Unity, iOS, TeamCity, AppCenter</title>
				<description>&lt;p&gt;You can take the developer out of the tools company, but weaning the developer of tool making is another thing entirely. As per usual, at &lt;a href=&quot;https://framebunker.com&quot;&gt;framebunker&lt;/a&gt; we remain focused on applying tools development where sensible to increase the efficiency multiplier on all efforts involved in development. This of-course includes a continuous integration setup, where we find another JetBrains solution to fitting our needs very nicely: TeamCity.&lt;/p&gt;

&lt;p&gt;Aside from being able to rely on prior experience, we enjoy the flexibility afforded by the solution, suite of available plugins, and direct integration with other parts of our setup. The party trick? Integration in Rider allows not just running of build configurations based on what is already checked in to some branch, but also based on your current local state - for “hey, check this out!” and similar scenarios. Is this offered by other CI setups? Don’t know - probably? Is it cool? Very yes.&lt;/p&gt;

&lt;h2 id=&quot;the-inaudible-x-factor&quot;&gt;The [inaudible] X factor&lt;/h2&gt;

&lt;p&gt;While we find ourselves working in many different environments from time to time, we seem to gravitate towards Unity and iOS. When you add continuous integration to the mix, that means dealing with the Xcode cli for building and signing something actually useful in distribution. And this is where I wrote my TODO on writing this post. If you take a look around the wider interwebs for clues on how this interface works, you will come across a broad range of advice on how such a feat is achieved. All different, most fully correct at time of writing.&lt;/p&gt;

&lt;p&gt;Historically things have changed in this area at least every couple of years which seems to pretty much coincide, with some padding, with how often I need to work with it. So every time I need to set something up, the environment has changed. Obviously underlying technology changes quite naturally over time, but in most cases that does not lead to people also radically changing the interface for said technology - desktop operating systems deal in windows, icons, and cursors, most cars have four wheels and a steering wheel, etc. - even if the technology underlying both has changed quite a bit over the years. Not so in this case. Exaggeration? Probably, but not by a whole lot.&lt;/p&gt;

&lt;h2 id=&quot;overview&quot;&gt;Overview&lt;/h2&gt;

&lt;p&gt;Anyway, this is not the prime topic of the post - just part of its inspiration. I wanted to describe the whole flow outlined in the title of this post and provide some insight at each step. Hopefully you will find useful bits here and there even if the whole flow is not relevant to your needs - just as I picked up bits and pieces from other posts as well as the very helpful AppCenter support department (comparatively not a lot of community material out there, given how young the product is).&lt;/p&gt;

&lt;p&gt;Overall the flow goes like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;An iOS title is being developed in Unity. For us this means version 2019.4 - the latest LTS release at time of writing.&lt;/li&gt;
  &lt;li&gt;Collaboration happens via git - pushed to and pulled from a local server. Specifics are largely irrelevant to this flow, but in our case we use &lt;a href=&quot;https://gitea.io/&quot;&gt;Gitea&lt;/a&gt; - including its support for git-lfs. Providing related support is an instance of the Unity cache server.&lt;/li&gt;
  &lt;li&gt;TeamCity is connected to the relevant project repositories and some build configurations are set to trigger as soon as fresh commits are detected. Among other things this provides us with up to date builds of the project available for download via the web interface.&lt;/li&gt;
  &lt;li&gt;For iOS builds that is not necessarily all that useful (aside from verifying that things build and pass tests) as you need to run an install flow in order to get on-device testing. Further, everyone relevant for distribution of test builds do not necessarily have access to our build server. So we rely on &lt;a href=&quot;https://appcenter.ms&quot;&gt;AppCenter&lt;/a&gt; (formerly Hockey App - at least this portion of it) to handle distribution of builds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of the above runs in Docker containers on our service network - with the exception of the macOS and Windows build agents which run in VMs on developer machines (enjoying that lovely trend of high core count desktop &lt;a href=&quot;https://www.amd.com/en/products/ryzen-threadripper&quot;&gt;CPUs&lt;/a&gt;). In either case configurations easily transfered to other infrastructure - for example when dealing with client projects.&lt;/p&gt;

&lt;p&gt;And why not do that? All of the above is definitely available for “free” or a minor fee, running on infrastructure maintained by someone else. Mostly flexibility. Running on someone else’s computer is great when you first start it up and everything lines up perfectly with your needs at the time. Reality, that is at least ours, unfortunately rarely remains on static spec - at which point maybe you can upgrade to a different plan or migrate to a different service, but more likely you end up just sucking it up and compromising your needs in order to not rock the service boat. Without spending time on depressing detail we have similarly had bad and potentially disastrous experiences with service operator support quality. Suffice to say I have no plans to again invite a session well past midnight of jumping VPN exit nodes to circumvent overzealous protection schemes while frantically laboring to salvage our data out of the fire of “computer says no”.&lt;/p&gt;

&lt;h2 id=&quot;unity-to-ios&quot;&gt;Unity to iOS&lt;/h2&gt;

&lt;p&gt;Building Unity projects on a CI setup means running the editor via command-line interface - loading the appropriate project in the right import target mode, cache server connected, invoking the appropriate editor script function you write to initiate the build you want, and finally routing output properly back to the CI system. Not a ton of work, but since a “runner” plugin for Unity projects already exists for TeamCity, we decided to not reinvent that particular wheel - relying on this plugin hopefully seeing some support. Our experience with it has unfortunately not been super smooth, so we may revisit that decision in the future.&lt;/p&gt;

&lt;p&gt;A couple of things to keep in mind:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“Build and run” is what you would usually click in the Unity editor UI in order to end up with Xcode building a nice iOS app for you. Not so when going via Unity build pipeline API. In stead the flow is:
    &lt;ul&gt;
      &lt;li&gt;Build (not run) - this produces an Xcode project for you.&lt;/li&gt;
      &lt;li&gt;Optional modification of the generated Xcode project - utech has &lt;a href=&quot;https://docs.unity3d.com/ScriptReference/iOS.Xcode.PBXProject.html&quot;&gt;a library&lt;/a&gt; available for this.&lt;/li&gt;
      &lt;li&gt;Instruct Xcode to build the generated (and possibly further modified) Xcode project via command-line interface.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;While the build function in your editor script must be static, the class implementing it cannot be. Similarly you should avoid nesting it further than one level in namespacing. Failing any of these will lead to Unity not being able to invoke the function via its command-line parameter.&lt;/li&gt;
  &lt;li&gt;Builds must take place inside one call stack originating in the function invoked via command-line - so being reliant on processes which need to be requested via Unity API before then being collected via an EditorApplication.update invocation or similar, issuing the final build call, is a no-go. This may well be a result of how the TeamCity plugin structures the actual command-line invocation of Unity, which is part of why we have a review of that plugin scheduled.&lt;/li&gt;
  &lt;li&gt;Over a number of Unity updates we have unfortunately seen a loss of some build-related functionality. Our solution has been to patch out these regressions directly in the UnityEditor assemblies, but that may not be an option for everyone. I hope to be sharing that setup and such patches in the not too distant future, but we’re not in a position where work on that front pays the bills - so no timeline promises. Build-relevant issues at time of writing (LTS 2019.4):
    &lt;ul&gt;
      &lt;li&gt;Preprocessing scenes is no longer possible - only postprocessing is.
        &lt;ul&gt;
          &lt;li&gt;Our patch bypasses the scene postprocess setup entirely and invokes our own, with the same sort of attribute markup, as appropriate. Internally it relies on a callback injected before Unity runs its scene processing - thus facilitating preprocessing. I am not aware of a non-patching alternative.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;As promising as it was, the quite new compile pipeline API invokes its events before the produced assemblies are actually moved into place on disk. As a result, any further work on said assemblies is at best not possible (no assemblies there) or at worst defeated (assemblies are modified, only to immediately be overwritten with newly generated copies). Bypassing this issue is further complicated by IL2CPP which makes timing even more critical (no longer a matter of “late enough”, but also “before IL2CPP”).
        &lt;ul&gt;
          &lt;li&gt;Our patch relies on the compiler pipeline API as a source of “what has been built” (usually “everything”, so gains vs. just assuming “all of the assemblies” are minimal), but otherwise completely bypasses it. For playmode patching we just respond to domain unload and for builds a new callback is injected at a point just prior to IL2CPP invocation, when updated assemblies are known to have been written to disk. I am not aware of a non-patching alternative - particularly when IL2CPP is in play.&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Aside from patching the Unity editor with these things (and other non-build-related stuff), we really enjoy the advantages of build-time changes to project assemblies afforded us by this post-processing flow. More than just code generation (like generating an enum based on Unity layer names), being able to modify, expand, and contextualise the actual code flow based the complete project - not just based on code structure, but actual usage as dictated by asset data - is quite exhilarating. Anyway, that’s an aside - not really build related. As stated - more on this in a later post (tm).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We implement the invocation of our Unity build script as one of two build steps (using the Unity plugin) of our TeamCity iOS build configuration. The other is the invocation of the Xcode CLI for building, signing, and packaging the Unity-generated project. This step is configured as the Command Line runner type, with the following “custom script”:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;xcodebuild archive &lt;span class=&quot;nt&quot;&gt;-project&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;output-path/Unity-iPhone.xcodeproj&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-scheme&lt;/span&gt; Unity-iPhone &lt;span class=&quot;nt&quot;&gt;-archivePath&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;output-path/name.xcarchive&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At time of writing that is really it! If you have worked with the Xcode CLI before or trawled the interwebs in search of this one line, you know how much other work has previously been involved. Fingers crossed that the above remains supported - if not static - for years to come. This of-course assumes that your build agent has already been configured to properly build and sign iOS applications when you invoke manually from the Unity editor UI.&lt;/p&gt;

&lt;p&gt;The result of this step is an xcarchive - almost what we need for distribution.&lt;/p&gt;

&lt;h2 id=&quot;ios-to-appcenter&quot;&gt;iOS to AppCenter&lt;/h2&gt;

&lt;p&gt;Whether you need to iterate with on-device builds or are sharing progress with the team or external groups, you will eventually need to distribute your build. Signing configuration of-course has to be configured via Xcode and associated online services and I am sure it is possible to automate distribution that way as well - ultimately via TestFlight on the client side. However since that route is currently not mandated, we prefer to keep our multi-platform flow joined for as long as possible - hence AppCenter (or, originally HockeyApp - business will business).&lt;/p&gt;

&lt;p&gt;Signing configuration aside, this is our only external service dependency. Given the subject matter, I am inclined to give this one a pass - especially as it means not needing to maintain an additional externally accessible network when distributing to external groups, and the much more manageable hit we would sustain should the service fail us. That said, I am certainly curious about self-hosted options.&lt;/p&gt;

&lt;p&gt;While our iOS build configuration in TeamCity is set to trigger when new changes are detected, distribution is either a manual or scheduled step (“gimme NAO” vs nightly builds). Dependent on the project, several distribution configurations exist - one for each group “team”/”testers”/”this partner”/”that partner” as well as “me”. We rely on the TeamCity build configuration template and parameters features to avoid too much duplication between related, but specialised configurations. In the case of the AppCenter ones a template defines the parameters which it then uses in its “command line” build step, while inherited configurations define different values of those parameters (or use the default). For example, the “me” configuration defines the &lt;code class=&quot;highlighter-rouge&quot;&gt;AppCenterGroup&lt;/code&gt; parameter as &lt;code class=&quot;highlighter-rouge&quot;&gt;Direct-CI-%teamcity.build.triggeredBy.username%&lt;/code&gt;, which the template uses in the “custom script” of its “command line” runner:&lt;/p&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;COMMAND&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'appcenter'&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;COMMAND&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$APPCENTER_CLI_INSTALL_PATH$COMMAND&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;

zip &lt;span class=&quot;nt&quot;&gt;-ry&lt;/span&gt; Project.%env.BUILD_NUMBER%.zip Payload
&lt;span class=&quot;nb&quot;&gt;mv &lt;/span&gt;Project.%env.BUILD_NUMBER%.zip Payload/Project.%env.BUILD_NUMBER%.ipa
&lt;span class=&quot;nb&quot;&gt;echo&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Starting upload now&quot;&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$COMMAND&lt;/span&gt; distribute release &lt;span class=&quot;nt&quot;&gt;--file&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%system.teamcity.build.workingDir%/Payload/Project.%env.BUILD_NUMBER%.ipa&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--app&lt;/span&gt; %AppCenterApp% &lt;span class=&quot;nt&quot;&gt;--group&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%AppCenterGroup%&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--token&lt;/span&gt; %AppCenterToken%
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;These configurations are based on the output of the earlier described iOS build configurations. As such they rely on a snapshot dependency from there, with the rule: &lt;code class=&quot;highlighter-rouge&quot;&gt;Project.iOS.*.xcarchive.zip!Products/Applications/**=&amp;gt;Payload/&lt;/code&gt;. This instructs TeamCity to collect the zip of the previously generated xarchive and from it copy out the contents of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Products/Applications&lt;/code&gt; subfolder - into a local &lt;code class=&quot;highlighter-rouge&quot;&gt;Payload&lt;/code&gt; folder. A couple of things to be aware of both in this and how it gets used in the above script:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The choice of the “Payload” folder name is convention. A valid ipa file is a zip archive with the application contained in a subfolder by this name.&lt;/li&gt;
  &lt;li&gt;Moving the zip file into the Payload folder after compression is not related to the upload process at all. In stead, I simply make use of the fact that I have the build configuration artifact dependency configured to “Clean destination paths before downloading artifacts”. So by moving the archive in there I make sure that the build agent clears it along with the uncompressed app when next it runs this configuration. Note that this does not conflict with having the build configuration use the ipa as its artifact.&lt;/li&gt;
  &lt;li&gt;Note that while the earlier script example was cross-platform (aside from Xcode being macOS-only), this is a shell script written for Linux or macOS. Initially I had this be a batch script run on our Windows build agent, but since we wanted the distribution step to always be available (as opposed to whenever a developer machine with a Windows build agent was online) and the Windows environment ironically wasn’t ideal for running this tool, I moved it to an Ubuntu-based Docker [container][&lt;a href=&quot;https://github.com/AngryAnt/teamcity-appcenter-agent-docker&quot;&gt;teamcity-appcenter-agent-docker&lt;/a&gt; which could run along with TeamCity and our other services.&lt;/li&gt;
  &lt;li&gt;While &lt;code class=&quot;highlighter-rouge&quot;&gt;zip&lt;/code&gt; is the program you want for zip compression under Ubuntu, on the Windows 10 command-line, you need to use &lt;code class=&quot;highlighter-rouge&quot;&gt;tar&lt;/code&gt; - which conversely does not produce zip archives on Ubuntu.&lt;/li&gt;
  &lt;li&gt;appcenter-cli does not provide any status output - hence the &lt;code class=&quot;highlighter-rouge&quot;&gt;echo&lt;/code&gt; command. A &lt;code class=&quot;highlighter-rouge&quot;&gt;--debug&lt;/code&gt; flag is available, but turning it on only outputs the REST data sent and received - no additional error information or status reporting results.&lt;/li&gt;
  &lt;li&gt;Not all AppCenter tokens are created equal. Make sure to use &lt;code class=&quot;highlighter-rouge&quot;&gt;appcenter-cli&lt;/code&gt; to create the token eventually supplied to its distribute invocation - tokens created via the web UI are not valid for this use.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;build-agent-setup&quot;&gt;Build agent setup&lt;/h3&gt;

&lt;p&gt;As mentioned, while the TeamCity server itself runs in a Docker instance, the build agents performing the brunt of the actual build-related tasks generally run as VMs on developer machines - with the above exception. This gives us much more free hands to configure the build environments for the tasks needing performed - aside from setting up and running the build agent software itself.&lt;/p&gt;

&lt;p&gt;For the AppCenter build agent that means installing &lt;a href=&quot;https://nodejs.org/download/release/v10.23.0/&quot;&gt;nodejs&lt;/a&gt; and the &lt;a href=&quot;https://github.com/Microsoft/appcenter-cli&quot;&gt;appcenter-cli&lt;/a&gt; tool. A couple of notes on that:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;While the appcenter-cli documentation does mention that it requires nodejs 10, that is not a &lt;em&gt;minimum&lt;/em&gt; spec, but an &lt;em&gt;absolute&lt;/em&gt;. Installing latest nodejs and hoping for the best will, at time of writing, only lead to long debugging sessions.&lt;/li&gt;
  &lt;li&gt;When setting up a Windows-based build agent for AppCenter use, you will want to not just install the appcenter-cli node package as a global package, but first modify the nodejs “prefix” from the default location somewhere in the current user path to something global (I go for &lt;code class=&quot;highlighter-rouge&quot;&gt;C:\nodejs&lt;/code&gt;) - ensuring build agent accessibility regardless of its user mode now or later.&lt;/li&gt;
  &lt;li&gt;You may have noticed the &lt;code class=&quot;highlighter-rouge&quot;&gt;APPCENTER_CLI_INSTALL_PATH&lt;/code&gt; variable used in the distribution script. This is just an environment variable set on the build agent - not something specific to TeamCity like the configuration parameters. Not only does this facilitate easy adaptation to different build agents offering the same capability - it is also usable as an agent requirement defined in the TeamCity build configuration. &lt;code class=&quot;highlighter-rouge&quot;&gt;APPCENTER_CLI_INSTALL_PATH&lt;/code&gt; points to where appcenter-cli is installed, so any agent with that environment variable set should be able to run build configurations dependent on that tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For other agents (or the same - if you do not want to run appcenter-cli on unique agents), we just need a licensed Unity install of the appropriate version, the TeamCity agent software, and a Java runtime to run it. macOS agents with iOS-build capability will also need Xcode and its cli installed. Notes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The TeamCity install provides the agent software - just navigating to the agents overview in the web UI provides an install link. Once the agent is up and running (having been authorized by an administrator via the web UI), the TeamCity install takes care of keeping the agent software up to date.&lt;/li&gt;
  &lt;li&gt;While Windows agents get a nice little UI installer, the macOS ones are a bit more manual. Minimal steps to get things going at time of writing are as follows (just pasted from our wiki):
    &lt;ol&gt;
      &lt;li&gt;Unzip &lt;code class=&quot;highlighter-rouge&quot;&gt;buildAgent.zip&lt;/code&gt; file to &lt;code class=&quot;highlighter-rouge&quot;&gt;~/buildAgent&lt;/code&gt;.&lt;/li&gt;
      &lt;li&gt;Configure &lt;code class=&quot;highlighter-rouge&quot;&gt;~/buildAgent/conf/buildAgent.properties&lt;/code&gt;:
        &lt;ul&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;serverUrl=http\://[DNS-or-IP]\:[PORT]&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;name=[MachineName]-macOS(optionally function and number)&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;workDir=[full user folder path]/buildAgent/work&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;tempDir=[full user folder path]/buildAgent/temp&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;systemDir=[full user folder path]/buildAgent/system&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;env.TEAMCITY_JRE=[full user folder path]/buildAgent/jre&lt;/code&gt;&lt;/li&gt;
          &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;ownPort=9090&lt;/code&gt;&lt;/li&gt;
        &lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Create the folder &lt;code class=&quot;highlighter-rouge&quot;&gt;~/buildAgent/logs&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;Load the agent for initial connect and auto-upgrade from the server &lt;code class=&quot;highlighter-rouge&quot;&gt;sh buildAgent/bin/mac.launchd.sh load&lt;/code&gt;&lt;/li&gt;
      &lt;li&gt;(Administrator authenticates the agent via the web UI)&lt;/li&gt;
      &lt;li&gt;Copy &lt;code class=&quot;highlighter-rouge&quot;&gt;~/buildAgent/bin/jetbrains.teamcity.BuildAgent.plist&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;~/Library/LaunchAgents/&lt;/code&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;Further / more up to date details are available in &lt;a href=&quot;https://www.jetbrains.com/help/teamcity/setting-up-and-running-additional-build-agents.html#Installing+Additional+Build+Agents&quot;&gt;this&lt;/a&gt; section of the TeamCity documentation.&lt;/li&gt;
  &lt;li&gt;The days of Java being easily available on macOS are unfortunately gone. Disregard the java install flow suggested by macOS / Xcode and in stead install / fix Homebrew, using it to install the necessary Java version (at time of writing Java 8):&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-sh highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;brew cask &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;adoptopenjdk8
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;If opting to run appcenter-cli in a QUEMU/KVM based VM, do note that its upload process seems especially susceptible to problems in the default VM driver for the NIC. Making sure that this is set as &lt;code class=&quot;highlighter-rouge&quot;&gt;virtio&lt;/code&gt; in stead eliminated some hefty delays when we were still running in a full VM-based agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;wrap-and-future&quot;&gt;Wrap and future&lt;/h2&gt;

&lt;p&gt;In general we are pretty happy with this setup. Iteration speed is really snappy, it serves all our needs, and the full flexibility facilitates some pretty cool options. Services are backed up off-premises on the same schedule as everything else and support delays &amp;amp; limitations are zero. Obviously establishing things took a bit more doing than signing up for some services and connecting them, but that cost is nowhere near a place where I would consider trading in all the upsides we have found.&lt;/p&gt;

&lt;p&gt;Aside from that review of the Unity TeamCity plugin, we are not likely to be doing a ton of tinkering with this part of our service setup in the immediate future, but one opportunity I did come across while setting up the AppCenter flow was managing distribution group composition via the cli. If so inclined, it might be interesting to have an infrequently run configuration use this to synchronise distribution groups with the Xcode signing groups - especially in a scenario where large groups of recipients are managed and frequently modified. Not currently relevant for us, but it seemed like an interesting project.&lt;/p&gt;

&lt;p&gt;Anyway, that’s about it. I hope you found something useful in this overview and best of luck in whatever it is you do.&lt;/p&gt;

</description>
				<published>2020-12-29 00:00:00 +0100</published>
				<link>http://www.angryant.com/2020/12/29/Unity-iOS-TeamCity-AppCenter/</link>
			</item>
		
			<item>
				<title>RAID0 NVMe on Ubuntu</title>
				<description>&lt;p&gt;A bit of an odd topic after a period of silence, but it’s something that annoyed me greatly recently and so I wanted to spare others that experience. Meanwhile, what has been keeping the updates? &lt;a href=&quot;http://framebunker.com&quot;&gt;framebunker&lt;/a&gt; and &lt;a href=&quot;http://playstaticsky.com&quot;&gt;StaticSky&lt;/a&gt; have! In case you missed it, I started (slowly) brushing off and open-sourcing some of our work there (yes, I’ll do what I can to move through my “to open source” list faster): &lt;a href=&quot;https://github.com/framebunker/Utilities&quot;&gt;https://github.com/framebunker/Utilities&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update January 2020&lt;/em&gt;:
Found &amp;amp; updated the link to the blog post which mentioned the appropriate sectors to clear on SSDs for md. Also one of the people who assisted in the Keybase team, David Hauken, wrote &lt;a href=&quot;https://david.hauken.us/posts/2019/11/ubuntu-desktop-raid0-roll-out-with-optional-luks-disk-encryption/&quot;&gt;a post on this topic&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;challenge&quot;&gt;Challenge&lt;/h2&gt;

&lt;p&gt;So anyway, I set up a new computer at home - the age of my 2013 laptop showing. On that I wanted to run Ubuntu off a full-disk encrypted drive. However a core point of the build is speed and full-disk encryption (via LUKS) does not necessarily go hand in hand with that.&lt;/p&gt;

&lt;p&gt;To offset that, I decided to go for a configuration with two PCIe4 NVMe sticks running in RAID0 (well cooled). Simple enough in principle, but then you hit the community coverage on the topic of “RAID0 is dangerous! Remember to back up your things and don’t pour water on your hardware”. It would appear that an Ubuntu (or event Linux) configuration like this is not super common.&lt;/p&gt;

&lt;p&gt;Luckily there were enough bits and pieces out there to, in combination with invaluable assistance from the people of the &lt;code class=&quot;highlighter-rouge&quot;&gt;sysadmins_unite&lt;/code&gt; Keybase team, string together a solution.&lt;/p&gt;

&lt;h2 id=&quot;process&quot;&gt;Process&lt;/h2&gt;

&lt;p&gt;If, like me, you are migrating an existing install to this setup then first make a backup of that install. I just used rsync - making sure that all file flags etc. were left intact in the copy. In creating the RAID0 across the two NVMe sticks any data already present on either will of-course be lost.&lt;/p&gt;

&lt;p&gt;Next, burn the Ubuntu installer onto a bootable medium. This approach probably work on a ton of other configurations, but given that I have only used it with Ubuntu 18.04, I am going to describe them in that known-to-work context.&lt;/p&gt;

&lt;p&gt;Boot into your installer and fire up a terminal. In these steps it is assumed that the two NVMe sticks mount at &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/nvme0n1&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/nvme1n1&lt;/code&gt;. If that is not the case in your setup, replace in the correct name where used. On my setup I was able to verify the mount points both in this installer terminal and in the Asus BIOS.&lt;/p&gt;

&lt;p&gt;The first step is to install the &lt;code class=&quot;highlighter-rouge&quot;&gt;mdadm&lt;/code&gt; tool - for creation and management of md RAID configurations. Note that critical to this particular usecase is the clearing of superblocks and overwriting of first one gigabyte of data. Most guides I came across would instruct clearing data at the end of the target drives, but one (&lt;del&gt;I unfortunately lost the link - sorry about that&lt;/del&gt; never mind - &lt;a href=&quot;https://exastuff.blogspot.com/2018/06/software-raid-with-nvme-devices.html&quot;&gt;found it&lt;/a&gt; in an old window of research tabs) pointed me to the first gigabyte. As I understand it, this is specific to how md operates on SSD or at least NVMe.&lt;/p&gt;

&lt;p&gt;Configuring your RAID:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install mdadm
sudo mdadm --zero-superblock /dev/nvme0n1
sudo mdadm --zero-superblock /dev/nvme1n1
sudo dd if=/dev/zero of=/dev/nvme0n1 bs=1M count=1000
sudo dd if=/dev/zero of=/dev/nvme1n1 bs=1M count=1000
sudo mdadm --create --verbose --level=0 --raid-devices=2 /dev/md0 /dev/nvme0n1 /dev/nvme1n1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With your raid up and running in your installer session, I really hope you did not forget to copy data you really wanted off those sticks. Anyway, the next step is to run the Ubuntu installer, opting to do “something else” when typical vs. not-quite-typical install configuration is chosen. This takes you to a screen where you get to specify which drives and partitions are get used for what in your fancy new install. Necessary config:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Format your new &lt;code class=&quot;highlighter-rouge&quot;&gt;/dev/md0&lt;/code&gt; drive. For me that was formatting to LUKS and then adding an ext4 partition to that. You could also format directly to ext4 if you do not want the encryption, but in that case you might want to do that outside of the installer - for optimum performance. See the later section for specifics on that.&lt;/li&gt;
  &lt;li&gt;Specify that the installer use your final ext4 partition as root &lt;code class=&quot;highlighter-rouge&quot;&gt;/&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;Use a different drive and partition for EFI and &lt;code class=&quot;highlighter-rouge&quot;&gt;/boot&lt;/code&gt;. This is critical as your bios will not know how to assemble the md RAID and boot from it - you need &lt;code class=&quot;highlighter-rouge&quot;&gt;/boot&lt;/code&gt; to handle that. There were some very creative suggestions in &lt;code class=&quot;highlighter-rouge&quot;&gt;sysadmins_unite&lt;/code&gt; on where one might put &lt;code class=&quot;highlighter-rouge&quot;&gt;/boot&lt;/code&gt;, but I simply have a SATA drive in my rig used for more rough work and first tier backup. I just set up &lt;code class=&quot;highlighter-rouge&quot;&gt;/boot&lt;/code&gt; and EFI partitions there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it - configure the rest of the installer as you like and run it to completion. When it does complete and prompt you to restart, don’t do that. The RAID still only really exists within this installer session so if you reboot now, you might as well start over.&lt;/p&gt;

&lt;p&gt;The Ubuntu installer will have your new install partition mounted at &lt;code class=&quot;highlighter-rouge&quot;&gt;/target&lt;/code&gt;. You need to make some edits to it in order to have it properly mount and run off your RAID from boot. If you closed the terminal from before, open up a new one and run this:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo mount /dev/[partition used for /boot] /target/boot
sudo mount --bind /dev /target/dev
sudo mount --bind /sys /target/sys
sudo mount --bind /proc /target/proc
sudo cp /etc/resolv.conf /target/etc/
sudo gedit /target/etc/default/grub
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In gedit you need to update the value of &lt;code class=&quot;highlighter-rouge&quot;&gt;GRUB_CMDLINE_LINUX&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;domdadm&quot;&lt;/code&gt;, save, and close the editor.&lt;/p&gt;

&lt;p&gt;Finally you need to add &lt;code class=&quot;highlighter-rouge&quot;&gt;mdadm&lt;/code&gt; to your new install, which will also apply your grub change along with its own to the boot setup, after which we are good to reboot and test the install:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo chroot /target
apt-get install mdadm
exit
sudo reboot now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you just wanted a fresh install, then this is the “profit!” step. Otherwise, restore your previous install onto your new root partition and update it to support your new boot setup by rebooting into the installer again and running this in a terminal:&lt;/p&gt;
&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sudo apt-get install mdadm
sudo mdadm -A -s
sudo mkdir /target
sudo mount /dev/md0 /target
sudo mount --bind /dev /target/dev
sudo mount --bind /sys /target/sys
sudo mount --bind /proc /target/proc
sudo cp /etc/resolv.conf /target/etc/
sudo chroot /target
apt-get install mdadm
exit
sudo reboot now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And &lt;em&gt;that&lt;/em&gt; is your “profit!” step.&lt;/p&gt;

&lt;h2 id=&quot;ext4&quot;&gt;ext4&lt;/h2&gt;

&lt;p&gt;If you just want to run ext4 as fast as possible directly on your RAID drive, you might want to manually work out the configuration of that partition to optimally work with the underlying RAID configuration. Key here is specifying the correct stride and stripe-width:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Chunk = 512 (output by or set via mdadm)&lt;/li&gt;
  &lt;li&gt;Block = 4 (ext4 dictated)&lt;/li&gt;
  &lt;li&gt;Devices = 2&lt;/li&gt;
  &lt;li&gt;Stride = 512 / 4 = 128&lt;/li&gt;
  &lt;li&gt;Stripe width = 2 * 128 = 256&lt;/li&gt;
  &lt;li&gt;Resulting in the formatting command &lt;code class=&quot;highlighter-rouge&quot;&gt;sudo mkfs.ext4 -v -L nvmeRAID -m 1 -b 4096 -E stride=128,stripe-width=256 /dev/md0&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;wrapup&quot;&gt;Wrapup&lt;/h2&gt;

&lt;p&gt;I hope this works out for you. It definitely took me more research, trial, and error than I would have liked to arrive at a functional approach. At this point I have been running the resulting setup for a month or two without the hint of an issue.&lt;/p&gt;
</description>
				<published>2019-12-07 00:00:00 +0100</published>
				<link>http://www.angryant.com/2019/12/07/RAID0-NVMe-on-Ubuntu/</link>
			</item>
		
			<item>
				<title>A Change of Gears</title>
				<description>&lt;p&gt;Having completed my latest contract, working splendidly with Charles and Nicholas over at &lt;a href=&quot;http://framebunker.com&quot;&gt;framebunker&lt;/a&gt;, we decided to extend our combined reach and potential by joining forces.&lt;/p&gt;
&lt;p&gt;I got into contracting in the first place in order to find a new team. This year I had made it my mission to end that search and as it turned out, the team was much closer than expected.&lt;/p&gt;
&lt;p&gt;What this means:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Contracting continues, now through &lt;a href=&quot;http://framebunker.com&quot;&gt;framebunker&lt;/a&gt;. If you have a job that needs doing, &lt;a href=&quot;http://framebunker.com/#contact&quot;&gt;give us a shout&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;We enter into final production on &lt;a href=&quot;http://playstaticsky.com&quot;&gt;Static Sky&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;As &lt;a href=&quot;http://playstaticsky.com&quot;&gt;Static Sky&lt;/a&gt; ramps down, we spin up new and exciting production &amp;#8211; stay tuned for more updates on that.&lt;/li&gt;
	&lt;li&gt;I pick up the slack on the feed here as we launch a series of technical blog posts from &lt;a href=&quot;http://framebunker.com&quot;&gt;framebunker&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;Both &lt;a href=&quot;/behave&quot;&gt;Behave&lt;/a&gt; development and &lt;a href=&quot;http://GameAINorth.com&quot;&gt;Game AI North&lt;/a&gt; organisation continue unaffected.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am very excited about this change as it allows us all to be more productive, while maintaining a more stable work environment. I look forward to share more in 2018.&lt;/p&gt;



</description>
				<published>2017-12-28 00:00:00 +0100</published>
				<link>http://www.angryant.com/2017/12/28/A-Change-of-Gears/</link>
			</item>
		
			<item>
				<title>CoreObject</title>
				<description>&lt;p&gt;I once built a talk with a collection of new hacks. This talk went through a couple of almost-delivered scenarios and with the &lt;a href=&quot;http://GameAINorth.com&quot;&gt;new side projects&lt;/a&gt; I have since accumulated, scheduling gets difficult.&lt;/p&gt;
&lt;p&gt;So I would rather share this stuff in post form now than stall for a possible eventuality. I have no idea how frequent I will be able to post, but here is one at least.&lt;/p&gt;
&lt;h2&gt;Challenge&lt;/h2&gt;
&lt;p&gt;Most Unity projects get spread across multiple scenes very quickly. This is advantageous not only for clearly segmented production, but also for tweaking of load times, streaming, and much more.&lt;/p&gt;
&lt;p&gt;An unfortunate side effect of this is an increase of challenges in referencing objects in a live session, across those scenes. Desired targets include objects baked into specific scenes and specific instances created at runtime.&lt;/p&gt;
&lt;p&gt;Common approaches to solving this include dependency injection and directory singletons &amp;#8211; both of which work really great. Unfortunately they both introduce a level of indirection in the Unity serialisation system, making it impossible to track cross-scene dependencies with generic tools. This also usually adds a programming- or finicky book-keeping step to the process of introducing new conceptual instances.&lt;/p&gt;
&lt;p&gt;If we could solve this challenge, we would end up with a clear dependency chain in the serialisation system, which would allow us to fully utilise the tracking and tooling benefits this yields, while greatly reducing the barrier to add new concepts and interact with existing ones.&lt;/p&gt;
&lt;h2&gt;Detour&lt;/h2&gt;
&lt;p&gt;With each scene a serialised island, there is one more (ignoring bundles) serialisation hub which all scenes can access: Assets.&lt;/p&gt;
&lt;p&gt;Both the instance and its consumer can reference the same asset, which we can then use to facilitate a connection between the two. Further, with both referencing the same asset, we now have that dependency information in the serialisation system. Also, adding new conceptual instances is just a matter of creating a new asset, assigning it to either end.&lt;/p&gt;
&lt;p&gt;Another bonus is easy listing of all conceptual instances by simply finding all assets of the type. You can demonstrate this via the object picker. Should you prefer a drop-down selector to the object picker, such would be a fairly straight forward piece of property drawer code. You could even utilise asset folder structure to define drop-down nesting.&lt;/p&gt;
&lt;h2&gt;Implementation&lt;/h2&gt;
&lt;p&gt;The base (5.3 tested) implementation of this needs three pieces:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;A &lt;code&gt;ScriptableObject&lt;/code&gt; type representing the conceptual instance as an asset.
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;https://gist.githubusercontent.com/AngryAnt/65b1289fe0af88c6e5fce7f3001bd0c8/raw/CoreObject.cs&quot;&gt;Example abstract&lt;/a&gt;, &lt;a href=&quot;https://gist.githubusercontent.com/AngryAnt/65b1289fe0af88c6e5fce7f3001bd0c8/raw/CoreGameObject.cs&quot;&gt;example concrete&lt;/a&gt;.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;One &lt;code&gt;MonoBehaviour&lt;/code&gt; registering a source.
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;https://gist.githubusercontent.com/AngryAnt/65b1289fe0af88c6e5fce7f3001bd0c8/raw/CoreGameObjectInstance.cs&quot;&gt;Example&lt;/a&gt;.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;A serialized reference to the &lt;code&gt;ScriptableObject&lt;/code&gt; type or a &lt;code&gt;MonoBehaviour&lt;/code&gt; acting as a gateway to the instance &amp;#8211; similar to a &lt;code&gt;MeshFilter&lt;/code&gt; component.
	&lt;ul&gt;
		&lt;li&gt;&lt;a href=&quot;https://gist.githubusercontent.com/AngryAnt/65b1289fe0af88c6e5fce7f3001bd0c8/raw/Test.cs&quot;&gt;Example&lt;/a&gt;.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In the given example, the instances being passed around are just &lt;code&gt;GameObjects&lt;/code&gt;. However in a real world scenario you may also want to create &lt;code&gt;CoreObject&amp;lt;T&amp;gt;&lt;/code&gt; derivatives passing references to specific components. Not only does this facilitate quicker access to the components you need &amp;#8211; it also naturally separates &lt;code&gt;CoreObjects&lt;/code&gt; into categories.&lt;/p&gt;
&lt;p&gt;A corresponding instance component could look a little something like &lt;a href=&quot;https://gist.githubusercontent.com/AngryAnt/65b1289fe0af88c6e5fce7f3001bd0c8/raw/CoreCharacterInstance.cs&quot;&gt;this&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Variants&lt;/h2&gt;
&lt;p&gt;While this base functionality has plenty of utility, I have on occasion played around with variants on the concept. For one, the base idea passes a single-source instance producer to multiple consumers, but there is no reason why you could not use this setup to register/unregister to a list of instances in stead.&lt;/p&gt;
&lt;p&gt;A personal favourite variant is more fundamentally different. In stead of facilitating references, the core objects wrap &lt;code&gt;UnityEvents&lt;/code&gt; &amp;#8211; turning them into global &amp;#8220;game events&amp;#8221;. This allows you to completely decouple event producers and consumers, while maintaining dependency tracking through the serialisation system.&lt;/p&gt;
&lt;p&gt;The pattern I mostly use such events in start with the producers invoking the event via a serialised &lt;code&gt;UnityEvent&lt;/code&gt;. Say you expose a &amp;#8220;fire&amp;#8221; &lt;code&gt;UnityEvent&lt;/code&gt; to which you add a particle effect invocation, audio playback, and finally the invocation of the &lt;code&gt;CoreGameEvent&lt;/code&gt; &amp;#8220;gunshot&amp;#8221;.&lt;/p&gt;
&lt;p&gt;This &amp;#8220;gunshot&amp;#8221; event would then be referenced by &lt;code&gt;CoreGameEventHandler&lt;/code&gt; components which also exposes a &amp;#8220;handle&amp;#8221; &lt;code&gt;UnityEvent&lt;/code&gt;. The action list of this event could then include stuff like switching the soundscape, putting NPCs into an alert state, trigger an auto save, and whatever else might be useful.&lt;/p&gt;
&lt;p&gt;Not only do you get decoupling of produces and consumers &amp;#8211; you also get to centralise handling details around the individual consumers as opposed to leaving them all jumbled up at the producer.&lt;/p&gt;
&lt;p&gt;So what do you think? Do you use something similar? What cool variants and tooling do you employ?&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/65b1289fe0af88c6e5fce7f3001bd0c8&quot;&gt;Source and examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;





</description>
				<published>2017-07-04 00:00:00 +0200</published>
				<link>http://www.angryant.com/2017/07/04/CoreObject/</link>
			</item>
		
			<item>
				<title>Unity Protocol Buffers</title>
				<description>&lt;p&gt;Time for another &amp;#8220;ah, crap &amp;#8211; better put &lt;strong&gt;something&lt;/strong&gt; up here before heading to &lt;span class=&quot;caps&quot;&gt;GDC&lt;/span&gt;&amp;#8221;-post. And since I did some re-tinkering with the integration of &lt;a href=&quot;https://developers.google.com/protocol-buffers/&quot;&gt;protobuf&lt;/a&gt; in Behave late last year, some sharing on that topic seemed in order.&lt;/p&gt;
&lt;p&gt;So yes, stuff is happening with Behave &amp;#8211; no abandonment has taken place. On the contrary I have been working on several, long-running, feature branches. I&amp;#8217;ll get around to merging some of those in and doing another release. More on that soonish.&lt;/p&gt;
&lt;p&gt;Anywho, last I checked, &lt;a href=&quot;https://github.com/mgravell/protobuf-net&quot;&gt;protobuf-net&lt;/a&gt; was still a more complete solution than the younger &lt;a href=&quot;https://github.com/google/protobuf/tree/master/csharp&quot;&gt;protobuf for C#&lt;/a&gt; one, so I still stick with protobuf-net and can therefore only talk about that here. However it looks like the latter is seeing more rapid development, so I&amp;#8217;ll probably review my choice when next I need to tinker with the integration.&lt;/p&gt;
&lt;p&gt;More interestingly, some of the initial people behind protobuf have since gone and built the new and shiny &lt;a href=&quot;https://capnproto.org&quot;&gt;Cap&amp;#8217;n Proto&lt;/a&gt;. This looks to be even more powerful than its predecessor, but at time of writing it is still not as mature or implementation-rich as protobuf. Critically for the context of this post, there is no C# implementation yet. Cool stuff, though &amp;#8211; worth keeping an eye on.&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;So what is the Protocol Buffers project? Succinctly, it is a compact binary serialisation format with very fast cross-platform and -language implementations. Super useful when you need to quickly move some data between memory and some other location &amp;#8211; a file / a network peer / whatever.&lt;/p&gt;
&lt;p&gt;It was first designed, implemented, and maintained by Google for communications between network peers on their internal network. Since then, it has been implemented in a number of different languages &amp;#8211; including the &lt;a href=&quot;https://github.com/mgravell/protobuf-net&quot;&gt;protobuf-net&lt;/a&gt; implementation, built and maintained by &lt;a href=&quot;https://github.com/mgravell&quot;&gt;Marc Gravell&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Serialisation use in Behave has gone through a couple of distinct phases:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;.net binary serialiser for asset.&lt;/li&gt;
	&lt;li&gt;protobuf-net for asset.&lt;/li&gt;
	&lt;li&gt;protobuf-net for asset and remote debugger protocol.&lt;/li&gt;
	&lt;li&gt;&lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; for asset, protobuf-net for remote debugger protocol.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Additionally I&amp;#8217;ve used protobuf-net for runtime saving or build pipelines on various client projects.&lt;/p&gt;
&lt;p&gt;Aside from speed and compression, protobuf-net vs. the .net binary serialiser was also an escape of the frustrating lack of support for versioning or even simple structural refactors of serialised types. The switch to &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; for the .behave asset files of-course came when I decided that merge-ability could be a fun thing to support.&lt;/p&gt;
&lt;p&gt;On top of this general migration, I also went through a couple of different protobuf-net integrations &amp;#8211; as my use cases and requirements changed. It just so happens that this gave me full coverage of the three approaches supported by protobuf-net, so no need for extra research before writing this post. Win!&lt;/p&gt;
&lt;h2&gt;Integration&lt;/h2&gt;
&lt;p&gt;For serialisation to work, you need a a serialiser and a schema. Protobuf-net offers a couple of ways for you to provide those:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;[Attribute] markup with runtime generated serialiser.&lt;/li&gt;
	&lt;li&gt;[Attribute] markup with pre-generated serialiser.&lt;/li&gt;
	&lt;li&gt;.proto file description with pre-generated serialiser.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I did this list in order of simplicity, which also happens to be the order in which I switched through them in the integration with Behave.&lt;/p&gt;
&lt;p&gt;The first option is very .net esque and protobuf-net is indeed compatible both with its own serialisation attributes and the more general-purpose .net serialisation attributes. However since your interest here is in a Unity context, I&amp;#8217;m sure that you have already spotted the problem with this approach.&lt;/p&gt;
&lt;p&gt;Given that my initial use for protobuf-net was just for asset serialisation (which is editor-time only), I had no problem with the serialisation solution relying on &lt;span class=&quot;caps&quot;&gt;JIT&lt;/span&gt; compilation in order to construct the serialiser at runtime. However as soon as I expanded my use case to include the runtime debugger, relying on &lt;span class=&quot;caps&quot;&gt;JIT&lt;/span&gt; would mean not supporting the debugger on &lt;span class=&quot;caps&quot;&gt;AOT&lt;/span&gt; platforms like iOS and consoles. Further, as Unity continues transitioning to their IL2CPP solution, you&amp;#8217;re looking at a future where most will want to do &lt;span class=&quot;caps&quot;&gt;AOT&lt;/span&gt; on all platforms.&lt;/p&gt;
&lt;p&gt;So when introducing the remote debugger (previous debugger implementation was just 100% in-editor), I started to pre-generate the serialiser. This entails feeding your compiled assembly with [Attribute] markup to the protobuf-net precompile tool, which in turn generates an assembly with the serialiser type. For an example of how I used to do that, here&amp;#8217;s a &lt;a href=&quot;https://gist.github.com/AngryAnt/7223d692ec9d2fd12053e5b04f57296a&quot;&gt;snippet of perl&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Extraction&lt;/h2&gt;
&lt;p&gt;Everything works! Win, right? Well&amp;#8230; as I was expanding debugger support to non-C# targets and doing a general code cleanup, I got increasingly annoyed by having serialisation implementation detail in my general data type code. So I started looking at how protobuf-net supports the standard protobuf .proto format for schema definition.&lt;/p&gt;
&lt;p&gt;As things stand, it takes a bit of work &amp;#8211; specifically &lt;a href=&quot;https://github.com/mgravell/protobuf-net/pull/163&quot;&gt;this work&lt;/a&gt; &amp;#8211; to get going, but once there it is solid. In stead of using the precompile tool, you need to build and run the protogen tool from the protobuf-net repository. If you&amp;#8217;re on Windows, things may just work straight out of the gate, but you may want to see what is in my patch anyway.&lt;/p&gt;
&lt;p&gt;So how does this work? Well, the input is no longer [attribute] marked assemblies, but in stead a .proto definition file. You can find great detail on that in the general &lt;a href=&quot;https://developers.google.com/protocol-buffers/&quot;&gt;protobuf&lt;/a&gt; documentation, but you may want to consult the &lt;a href=&quot;https://github.com/mgravell/protobuf-net&quot;&gt;protobuf-net&lt;/a&gt; docs for implementation specifics/limits. Also, the output is not an assembly, but simply a C# file.&lt;/p&gt;
&lt;p&gt;Keep in mind that protogen relies on the protoc tool from the general Google protobuf tools. I fetched this from homebrew as the &amp;#8220;protobuf&amp;#8221; package.&lt;/p&gt;
&lt;p&gt;Again I have a &lt;a href=&quot;https://gist.github.com/AngryAnt/16c548412cdf1dba30140e8cdd97dc64&quot;&gt;snippet of perl&lt;/a&gt; to illustrate use &amp;#8211; as well as an &lt;a href=&quot;https://gist.github.com/AngryAnt/f053be0c4c66fafde17d679c2d09a9c9&quot;&gt;example .proto file&lt;/a&gt;. In this case the Behave debugger protocol definition.&lt;/p&gt;
&lt;p&gt;Using this approach, I now have a nicely separated codebase and no duplication of schema definition between the C# debugger runtime and others. One trick remains though&amp;#8230;&lt;/p&gt;
&lt;h2&gt;Object pooling&lt;/h2&gt;
&lt;p&gt;A mildly active Behave debugger session involves a lot of messages. I have very little interest in blowing up the garbage collector by constantly instantiating new messages and leaving them to get collected. So how do we integrate an object pool setup with the generated protobuf-net serialiser?&lt;/p&gt;
&lt;p&gt;While not exactly as pretty as I would like, my answer is making use of the partialness of the generated types &amp;#8211; in order to add &lt;a href=&quot;https://gist.github.com/AngryAnt/1ed005b443202f6dcebc9649d59ae2d2&quot;&gt;a static pool and -constructor&lt;/a&gt; to hook it up.&lt;/p&gt;
&lt;p&gt;And that&amp;#8217;s pretty much what I&amp;#8217;ve got. If I missed something or you have related questions, feel free to ping me and I&amp;#8217;ll try to update this post when I can.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://developers.google.com/protocol-buffers/&quot;&gt;protobuf&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mgravell/protobuf-net&quot;&gt;protobuf-net&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/google/protobuf/tree/master/csharp&quot;&gt;protobuf for C#&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://capnproto.org&quot;&gt;Cap&amp;#8217;n Proto&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mgravell&quot;&gt;Marc Gravell&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/7223d692ec9d2fd12053e5b04f57296a&quot;&gt;Precompiler perl&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/mgravell/protobuf-net/pull/163&quot;&gt;protogen patch&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/16c548412cdf1dba30140e8cdd97dc64&quot;&gt;protogen perl&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/f053be0c4c66fafde17d679c2d09a9c9&quot;&gt;Protocol.proto&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/1ed005b443202f6dcebc9649d59ae2d2&quot;&gt;Object pool integration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;








</description>
				<published>2017-02-17 00:00:00 +0100</published>
				<link>http://www.angryant.com/2017/02/17/Unity-Protocol-Buffers/</link>
			</item>
		
			<item>
				<title>Behave 2.7</title>
				<description>&lt;p&gt;The serialisation update is here! Ok maybe that is not the most exciting change for everyone, but I for one am quite happy about having finally shipped it. Aside from making life a lot simpler for anyone vaguely interested in collaborating on Behave libraries across version control systems, this lays the groundwork for a good number of runtime changes I have been wanting to do for a while.&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;Aside from just fixing up serialisation, this release focuses on improving editor usability with a good selection of tweaks and features. Some choice examples:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Behaviour tree minimap navigation.&lt;/li&gt;
	&lt;li&gt;Subtle indicator of tree origin direction when it is out of canvas view.&lt;/li&gt;
	&lt;li&gt;&amp;#8220;Larger fonts&amp;#8221; toggle for better visibility.&lt;/li&gt;
	&lt;li&gt;Hiding of component- and sidebar, plus a bunch of other canvas navigation tweaks.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Onward&lt;/h2&gt;
&lt;p&gt;After clearing this serialisation system obstruction out of the way, the road is now open for a host of planned features. Most of these are aimed at improving runtime flexibility, by increasing the available options for the tools you are already familiar with.&lt;/p&gt;
&lt;p&gt;If you happen to be at this years &lt;span class=&quot;caps&quot;&gt;GDC&lt;/span&gt; in a little months time, perhaps we could meet and exchange ideas on this?&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://u3d.as/5hA&quot;&gt;Behave 2 for Unity on the asset store&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/behave/&quot;&gt;Project information&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
Changelist:


2.7:
 - New library serialisation.
     - Backwards compatible with all 2.x variants.
     - All other formats are deprecated: text, binary, export/asset.
         - Exports are auto-upgraded, but please make sure to follow editor instructions when opening asset-type libraries.
         - Run your upgrades now. Future versions of Behave will not support deprecated serialisation.
     - Support for pre-2.0 decorators finally dropped.
     - Faster and less frequent serialisation.
     - Designed for optimal inter action with version control systems.
     - Custom inspector for Behave libraries is dropped in Unity 4.
         - Aside from the visuals, this just means that the Behave window now only can be launched by double-clicking the library or via the Window menu.
 - Behaviour tree minimap navigation - activate via alt+space.
 - Float/Clamp toggle for turning off canvas clamping when setting up large new tree structures.
 - Subtle indicator of tree origin direction when it is out of canvas view.
 - &quot;Warn on non-mandatory actions and contexts&quot; compiler toggle to support team communications.
 - &quot;Larger fonts&quot; toggle for better visibility.
 - Hiding of component- &amp;amp; sidebar.
 - Similar to reference components, components (and connections) referencing records can now also be double-clicked to navigate there.
 - Compiler adapted to new Unity distribution structure on OS X with Unity 5.4.
 - Home screen update.
 - Improved editor performance - particularly on larger libraries.
 - Better error handling for establishing debugger connections.
 - Tidying up and calming antivirus software by using Unity project Temp folder in stead of global temp.


2.6.4:
 - Fixed protobuf compatibility with Unity Windows.NET build targets.


2.6.3:
 - Fixed compiler execution on certain versions of OS X.
 - Minus one popup in the Windows compilation process.


2.6.2:
 - Fixed Windows compiler issue.


2.6.1:
 - Addressed Unity 5.1 compiler configuration compatibility issue.


2.6:
 - Removed backwards compatibility with Behave 1.x assets. That should be sufficient grace.
 - Removed a number of utility types from publicly accessible namespace - should be a lot less cluttered now.
 - Changed Tree.TickWrapping to now take exception handling behaviour parameter as an enum in stead of a boolean.
 - Changed Tree.LastTickTime to return DateTime ticks rather than a UnityEngine.Time.time value.
 - Fixed corner case where Unity could lock up while stripping Behave.
 - Fixed setting of Tree.LastTicked and Tree.ActiveID. Both will always reset to ActionType.Unknown, never -1.
 - Fixed compiler being able to handle Unity being installed on a path containing spaces.
 - Improved compiler error messages.
 - Added intellisense documentation to the runtime API.
 - Added int[] Tree.SupportedActions.
 - Added Tree.Owner for better handling of agent reassigning in pooling scenarios and similar.
 - Added ICollection. GetAsInt (int) and GetAsBool (int).
 - Action handler classes.
     - Added IActionClass and Tree.SetForwards (int, IActionClass) for init/tick/reset handling to a specific class instance.
     - Added Tree.ReflectForwards (GameObject) setting forwards for MonoBehaviours implementing IActionClass.
 - Editor polish.
     - &quot;Now Behave library being edited&quot; label now comes with a shortcut &quot;Create&quot; button.
     - More informative load messages in the home screen, including progress bars.
     - With Unity 5 dropping the engine feature delta, in-editor video viewing is now available on non-pro licenses as well.


2.5.4:
 - Address Unity 5 compatibility issue with the home screen.


2.5.3:
 - Fix issue with home screen not closing.


2.5.2:
 - Play nice on Unity free again.


2.5.1:
 - More rigid network code for setting up the debugger.
 - Upgraded protobuf-net distribution to r668, Unity, full.
 - Drowned out debug logging accidentally included in 2.5.0.


2.5:
 - Optional text serialisation.
     - Switch between text and binary serialisation in library settings.
     - Full and partial exports to text or binary file.
     - NOTE: Libraries opened in this version of Behave will be upgraded and are afterwards not backwards compatible.
 - Compiler upgrade.
     - Added lots of little CPU and memory optimisations.
     - Added tree analysis leading to larger memory saves on references when possible.
     - Improved handling of circular references.
     - Improved error reporting.
     - Changed name validation.
         - Underscores are no longer allowed in names - in order to avoid name clashes with pathed assets.
         - Fixed previously allowing leading numbers in names.
 - Runtime API.
     - Added library.ReflectForwards (ICollection, object).
     - Added library.SupportedRecords (ICollection).
     - Added blueprint.SupportedTrees.
     - Added Library.DidInstantiate (ICollection / Tree).
     - Changed generated enums to be valued continuously.
     - Changed get calls for unhandled records to now return -1.
 - Editor polish.
     - Improved debugger view.
         - Improved control bar layout.
         - Improved rendering of active referenced trees.
         - Fixes to follow-focus.
         - Debug view no longer re-crops to current visible tree area, preventing the previous behaviour of the view jumping around even without follow-focus enabled.
         - Improved sidebar listing of available- and connected runtimes.
         - Improved handling of disconnecting runtimes.
         - Improved tracking of available runtimes. No more need for refreshing.
         - Improved UI for adding debugger overrides.
         - Added &quot;Add overrides enabled&quot; setting (on by default).
     - Library vertical scrollbar replaced by standalone scroll buttons top / bottom when relevant - reducing visual noise.
     - Smaller tweaks and fixes.
 - Improved internal test coverage.


2.4.2:
 - Fixed some issues related to handling priority selectors in the recently update debugger.


2.4.1:
 - Fix corner case when restructuring library assets.


2.4:
 - Introducing “records”.
     - Float fields stored in “collections” - essentially ‘smart tables’.
     - Blackboard fields.
     - Utility curves.
     - Utility graphs.
     - Behaviour Tree integration.
          - “Tester” component.
          - “Writer” component.
          - Record mode for Priority Selector component.
 - Editor behavioural change: Deleting a tree no longer deletes reference nodes targeting that tree from other trees. Their target is merely cleared.
 - Editor behavioural change: The Reference node is only available in the component bar if the library contains more than one tree. Same behaviour for Tester and Writer with records.
 - Behavioural change: Invert flag is now properly applied by the Priority Selector.
 - Debugger connection stability improvement.
 - Connection disabling has been removed. This confusing feature caused more harm than good.
 - Video player now displays video title and description.


2.3.5:
 - Fix home screen video player.


2.3.4:
 - Better error messages in case of insufficient file access privileges (OHAI Perforce).
 - Added simple version check to the home screen.
 - New icons for Priority Selector and &quot;form new tree&quot;.
 - Smaller, embedded, JSON library.
 - Fix annoying behaviour with tree renaming where text fields would keep last entry.
 - Fix similar behaviour with component text fields on tree selection change.
 - Unity 5 compatibility fixes (tested on beta 2).


2.3.3:
 - Fix focus handling issue with auto-complete.
 - Parametrisation is now correctly applied for reset handler calls.


2.3.2:
 - Fix sidebar item duplication and deletion only functional during rename.


2.3.1:
 - Fix GUI error being logged on tree selection.
 - Proper handling of currently edited library asset being deleted.


2.3:
 - Added support for instant repeaters.
 - Added support for mandatory contexts.
 - Added optional target parameter to Tree.ResetForwards.
 - Added Tree.TickWrapping method.
 - Added debugger auto-launch settings to library build options.
 - Added home screen - shown on launch or via the Help menu, full of resources.
 - Behavioural change: Decorators no longer forward the instant flag of their child node.
 - Behaviour of decorators receiving a Running signal from their control connection is now defined.
 - Dependencies now shipped as separate (replaceable) files for minimal project impact.
 - Editor polish.
     - Added support for running multiple editor debugging instances on one machine.
     - Added focus-follow for debugger and canvas.
     - Added both scrollwheel/pad and drag-to-scroll support to all canvas views.
     - Drag connection to occupied input slot to replace.
     - Directly drag-drop trees from the sidebar onto the canvas as reference nodes.
     - Instant flag doesn't show on nodes connected to parents ignoring the flag.
     - &quot;Last edited library&quot; now tracked per project.
     - Last selected tree is now also restored between sessions and playmode transitions.
     - A bunch of minor adjustments and improvements.
     - Performance + memory + disk space optimisations.
     - Minor bugfixes.
 - New documentation layout and enhancements (already released as available).
 - Reshuffling of code to make way for exciting new things down the road.


2.2.2:
 - Addressed protobuf issue causing Parallel component completion setting to not get stored correctly.


2.2.1:
 - Fixed issue causing parallel components to fail compilation.


2.2:
 - Behavioural change: Support for multiple different action handler signatures is discontinued effective immediately.
    - Generated agent blueprint as well as accepted reflected signatures are now only:
        - public BehaveResult [Tick/Init][Name]Action (Tree sender);
        - public void Reset[Name]Action (Tree sender);
 - Added Tree class accessors - all valid only during an active init/tick/reset handler call:
    - string ActiveStringParameter
    - float ActiveFloatParameter
    - IAgent ActiveAgent
    - object ActiveData
 - Rather than waiting for the Unity bugfix, the built-in compiler API is now bypassed in favour of direct compiler binary execution.
    - An additional system-level mono SDK install is no longer needed to work around this Unity bug.
 - Tree.SetForward now returns boolean success value rather than logging error when passed unused action.
 - Full-library export now also available from the library settings in stead of menu-only access.
 - Even more UI polish: Better word-wrap, more contrasts for emphasis, instant flag hidden in unaffected scenarios and much more.
 - &quot;Form new tree&quot; nicely moves the new subtree up around the root socket rather than retaining the old position.
 - Default frame-rate of DebugUpdater now set to 20 fps rather than every frame. Gun safety and all that.
 - Massive codegen size save for larger libraries - from optimisation of tree-agent introspection codegen. Compile-time win.
 - More rigid parameter evaluation (remove needless occasional extra codegen).
 - Fixed copy and duplication procedures incorrectly not copying parameter values.
 - Force Unity to write serialised data before compiling.


2.1.1:
 - Fixed issue with tree paramterisation breaking debugger visualisation.


2.1:
 - Added autocomplete on action names, string parameters and component contexts.
 - Added mandatory actions (present in library regardless of use in trees).
 - Added partial library export and library merging / import-to-library.
 - Added Behave stripping - leave behind only a very lean Behave runtime, for redistribution or super slim deploy.
 - Added parameterised trees - get even more re-use out of your trees by overriding context and variables per reference.
 - Behavioural change: Tree.Reset will now delay resetting tree variables until after complete component reset.
 - Behavioural change: Tree.Tick will no longer automatically reset the tree upon completion. This plays very well with:
 - Added Tree.TickContinuously (int iterationCap = 1024) - ticks tree till completion or iteration cap is reached.
 - Added BehaveResult Tree.Result (bool value) utility function to side with Tree.Invert (BehaveResult value).
 - Added int Debugging.Local.ConnectionCount property - facilitating debug behaviour dependent on Behave debugger presence.
 - Moved default install path from Assets/Behave to Assets/Plugins/Behave.
    - WARNING: See Readme.txt upgrade guide.
 - Fixed decorator control node removal resulting in detached control connection.
 - Fixed decorator incorrectly not forwarding the instant status of its child node.
 - Fixed scenario where agent classes would get reflected for handlers even if blueprint derived.
 - Fixed unexpected corner cases of bad library configuration failing compiles (now causing warnings or simply being ignored).
 - Fixed Behave window breaking down when exiting play mode after having been active there.
 - Fixes to context getting incorrectly reset in some scenarios.
 - Fixed copy / paste functionality missing in some text fields.
 - Lots of UI polish and minor fixes.


2.0:
 - New editor.
    - Unified all controls into one window.
    - Completely customised look - compatible with both Unity light and dark skin.
    - Keyboard authoring interface in addition to drag &amp;amp; drop.
 - Debugger upgrade.
    - Remote debugging.
    - Tick and reset.
    - &quot;Unplug&quot; for debugger-only control.
    - Breakpoints.
    - Action overrides - override the return values of specified actions.
 - Decorator rewrite.
    - Deprecated old decorator.
       - Still compiles, but cannot be added.
    - Decorators are now control-type components.
       - No specific decorator handlers on agents.
       - Control is achieved via third connection socket.
    - Two initial decorator types: Repeater and Interrupter.
 - Asset restructuring.
 	- No more collections - for nesting, use paths in tree names.
 	- New serialization format - see Readme.txt for upgrade instructions.
    - Collections are gone. Use Unix-style path names for tree organisation.
 - IAgent.Tick (Tree, bool) changed to IAgent.Tick (Tree)
	- Init calls can now only be handled explicitly
 - Full coverage online documentation and other community resources.
 - Countless fixes and polish items.

1.5:
 - Added Tree.TickActive - indicating if a tree is currently executing a tick or if it has completed evaluation.
 - In-tick tree reset requests now result in a reset at the end of tree evaluation rather than an immediate one.
 - Removed the legacy compatibility assembly (for compatibility with pre-1.2 assets) from the default distribution.
 - Fixed &quot;X must be instantiated using the ScriptableObject.CreateInstance method instead of new X&quot; warnings.

1.4:
 - Fixed decorator incorrectly initializing on every returning tick when tick handler returned Running.
 - Fixed debugger view dependency on active tree editor - causing reported null reference exception.
 - Fixed missing scrollbars on browser window.
 - Reduced logging noise from debug builds.
 - Agent blueprints can now be MonoBehaviour based.
 - Clarified wording on &quot;library not loaded&quot;.
 - Now handling reset a bit cleverer - potential performance boost.
 - Changed the default success criteria of Parallel components from SuccessOrFailure to Success.
 - Added &quot;instant&quot; flag to components. Components marked instant will affect sequences and selectors when moving between child nodes. When a child node marked &quot;instant&quot; completes, rather than waiting for the next tree tick to tick the following child node, the sequence or selector does it immediately.
 - The compiler progress bar returns.
 - Editing a Behave asset now focuses the asset browser last instead of the tree editor.
 - Behave can now be installed in any subfolder of Assets - provided its internal folder structure remains intact.
 - Compilation speed improvements.
 - Enabled references across collection borders.
 - Added Tree.DataSize - returning the number of bytes used by a tree instance. This is also displayed in the debugger window.

1.3:
 - Fixed priority selector init flag resetting.
 - Fixed reference handling on tree renaming and deletion.
 - Fixed references still pointing at old collection post collection duplication.
 - Fixed compilation of actions and decorators with non-integral float parameters.
 - Fixed GUI list behaviours.
 - Fixed passing context back and forth between referenced trees and referrer.
 - Fixed reordering connections not causing save state to be set.
 - Various GUI tweaks.
 - Runtime optimisations.
 - Enabled scrolling of the tree list in the debugger window.
 - Exposed Tree.ReflectForwards.
 - Added Tree.ResetForwards.
 - Added agent blueprints - connecting to agent handlers through virtual methods rather than reflected handlers.
 - Made connections selectable in the tree editor via the connection nub.
 - Moved connection managing from the inspector to the tree editor, where it is more visible and handy.
 - Added support for disabling connections - for faster, less destructive debugging.
 - Double-click reference component to jump to referenced tree.
 - Changed &quot;Cannot update unregistered tree&quot; handling from an exception to an error message. Still need more info.
 - Now showing string and float parameters in the tree editor if either is set.

1.2:
 - Fixed release building.
 - Added the priority selector, introducing the API points:
    - int IAgent.SelectTopPriority (Tree sender, params int[] IDs);
    - enum BL[LibraryName].PriorityType { PriorityName, ..., Unknown };
 - Added support for branch contexts, introducing the API points:
    - enum BL[LibraryName].ContextType { ContextName, ..., Unknown };
    - int Tree.ActiveContext { get; }
 - Changed IAgent interface:
    - Tick (bool init, Tree sender) -&amp;gt; Tick (Tree sender, bool init)
 - Added &quot;Select asset&quot; button to the standard inspector.
 - Interface polish.

1.1:
 - Made compatible with Unity 3.0 - including ensuring that the 2.5-2.6.1 bug preventing compilation on Windows is fixed on the Unity side.
 - UI tweaks and polish.
 - Added the option to have return values of nodes be inverted.
 - Fixed compiler bug when facing sequence or selector with only one child node.
 - Renamed Library.Tree -&amp;gt; Library.InstantiateTree.
 - Added Tree.Tick () and Tree.Reset () methods using the IAgent instance given at instantiation of the tree.
 - Removed the abstract Library class.
 - Changed generated library class:
    - Trees -&amp;gt; TreeType.
    - Actions -&amp;gt; ActionType.
    - Decorators -&amp;gt; DecoratorType.
    - Tree InstantiateTree (int, IAgent) -&amp;gt; static Tree InstantiateTree (TreeType, IAgent)
    - int TreeID (Tree) -&amp;gt; static TreeType Type (Tree)
    - bool IsAction (int) -&amp;gt; static bool IsAction (int)
    - bool IsDecorator (int) -&amp;gt; static bool IsDecorator (int)
 - Upped editor performance.
 - New asset structure change with automatic import of Behave 1.0 assets.
 - Changed action and decorator handlers. These are now the handlers mapped:
    - public BehaveResult Init[Name][Action/Decorator] (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data);
    - public BehaveResult Tick[Name][Action/Decorator] (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data);
    - public void Reset[Name][Action/Decorator] (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data);
    - public BehaveResult Init[Name][Action/Decorator] (Tree sender);
    - public BehaveResult Tick[Name][Action/Decorator] (Tree sender);
    - public void Reset[Name][Action/Decorator] (Tree sender);
    - public BehaveResult [Name][Action/Decorator] {get; set;}
 - Added support for collection duplication.
 - Moved debug rendering into the editor with its own dedicated debugger window, including actor listing.
 - Debugger now renders active sub-trees as well.

1.0:
 - Lots o fixes for Unity 2.5 compatibility.
 - Closer editor integration with new UI.
    - Component bar.
    - Node inspection.
 - Runtime tree debugging.
 - Direct mapping of action and delegate handlers via reflection.
 - Kitty demo.

0.3b:
 - Various tweaks to the editor UI.
 - Optimised the compiler.
 - Fixed the following editor bugs from the bug list:
    - When the editor scrips are recompiled and when the user enters and exits play mode, running editors will loose references, causing undetermined behaviour.
    - When a compile fails, the Behave compiler is locked and unusable – requiring a unity relaunch.
 - Implemented the following wishlist items:
    - Behaviour tree decorators.
    - Stand-alone edition of the Behave editor.
    - Behaviour tree debugging features.

0.2b:
 - Made the demo project a whole lot more interesting.
 - Implemented the editor wish list item: Ability to move trees between collections.
 - Various tweaks to the editor UI.
 - Fixed a ton of bugs in the compiler.
 - Fixed the following editor bugs from the bug list:
    - Not able to delete collections from library.
    - Not able to delete trees from library.
    - Not able to rename collections from library.
    - Not able to rename trees from library.
    - Missing &quot;tree has been changed, save changes?&quot; dialog.

0.1b:
 - Some documentation is available.
 - Compiler is now creating sensible output.
 - A simple test tree and script using it is provided with the demo.
 - Documentation is linked directly from the unity help menu.
 - Less spamming of the log with debug information.

Pre-release:
 - Magic happened. Behave was born.
&lt;/pre&gt;</description>
				<published>2016-02-13 00:00:00 +0100</published>
				<link>http://www.angryant.com/2016/02/13/Behave-2-7/</link>
			</item>
		
			<item>
				<title>Learn</title>
				<description>&lt;p&gt;I&amp;#8217;m just about to wrap up a weeks vacation before it&amp;#8217;s back on the horse again &amp;#8211; as I leave for the &lt;a href=&quot;http://nucl.ai&quot;&gt;nucl.ai&lt;/a&gt; conference Sunday morning. If you&amp;#8217;re going, maybe I&amp;#8217;ll see you there? If not, you should go check out the &lt;a href=&quot;http://aigamedev.com/broadcasts/nuclai15-stream/&quot;&gt;live stream&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Basis&lt;/h2&gt;
&lt;p&gt;Anyway, so in my vacation I built a little project when I could find a bit of time here and there. It was inspired by work on a client project earlier in the year, where we looked at wiring up a neural network for analysis of a noisy sensor.&lt;/p&gt;
&lt;p&gt;The problem at the time was that although I could find a few C# NN libraries here and there, they were either not really a good fit or had a not-so-open open-source license like &lt;span class=&quot;caps&quot;&gt;GPL&lt;/span&gt; (good thing I don&amp;#8217;t have comments enabled here, eh?).&lt;/p&gt;
&lt;p&gt;Anyway, that felt a bit silly, so I figured that I&amp;#8217;d at least get the ball rolling on a somewhat sane, &lt;span class=&quot;caps&quot;&gt;MIT&lt;/span&gt; licensed, alternative. Either that or just have some fun with it until someone would point me at the obvious alternative solution, which I had overlooked in my earlier search.&lt;/p&gt;
&lt;h2&gt;Project&lt;/h2&gt;
&lt;p&gt;In its initial shape, the library just lets you construct a layered network, randomize its weigths, train it with a straight forward implementation of back-propagation with adjustable learning rate and momentum, and of-course run it.&lt;/p&gt;
&lt;p&gt;There is no serialisation interface yet, I&amp;#8217;ll probably want to do a simplification pass over it, and I have a few edge case tests I&amp;#8217;d like to run. However all of that is noted on the project &lt;span class=&quot;caps&quot;&gt;TODO&lt;/span&gt; and shouldn&amp;#8217;t amount to all that much work &amp;#8211; in case you fancy taking a stab at it.&lt;/p&gt;
&lt;p&gt;I did set up a little Unity project for testing though (the library itself does not depend on anything in Unity). It has a few debug views, a test scenario of the &lt;span class=&quot;caps&quot;&gt;XOR&lt;/span&gt; case, and a curve visualisation of training error. Look, I uploaded several pretty pictures:&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;https://player.vimeo.com/video/133789555&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;h2&gt;Access&lt;/h2&gt;
&lt;p&gt;Feel like giving it a go? As mentioned, the license is &lt;span class=&quot;caps&quot;&gt;MIT&lt;/span&gt;, so you can really do whatever with it. However should you want to contribute, pull requests are most welcome. I don&amp;#8217;t know how much time I can spare on this next to contracts and Behave, but at least it was a fun thing to work-on-while-not-working.&lt;/p&gt;
&lt;p&gt;Whatever the case, this is where you can find the repositories:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/AngryAnt/Learn&quot;&gt;Learn&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/AngryAnt/LearnUnityTest&quot;&gt;Unity test project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


</description>
				<published>2015-07-17 00:00:00 +0200</published>
				<link>http://www.angryant.com/2015/07/17/Learn/</link>
			</item>
		
			<item>
				<title>Behave 2.6</title>
				<description>&lt;p&gt;Still plenty of open feature branches on Behave, but now is the time for the next drop. With a little over a week till Unite Europe and shortly thereafter nucl.ai (formerly GameAIconf), I&amp;#8217;m also heading into a bit of a plenty-to-do period. Perhaps we&amp;#8217;ll meet at the conference and have a chat about it?&lt;/p&gt;
&lt;h2&gt;Contents&lt;/h2&gt;
&lt;p&gt;With only minor editor tweaks, the 2.6 release of Behave focuses primarily on &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; changes and added capabilities. The more exciting of these is probably the addition of action classes, allowing you to implement actions not just as singular event handlers on agent classes, but as standalone classes &amp;#8211; or in the case of Unity, as components.&lt;/p&gt;
&lt;p&gt;The reference documentation has been updated with a &amp;#8220;Composition&amp;#8221; section describing the setup in more detail.&lt;/p&gt;
&lt;p&gt;Do note that in this release, Behave is no longer backwards compatible with Behave 1.x assets.&lt;/p&gt;
&lt;h2&gt;Onwards&lt;/h2&gt;
&lt;p&gt;Unfortunately some planned features are taking a bit longer as they depend on a serialisation system refactor, requiring an extended period of focus. The groundwork for this has been effectuated and given time, should shoulder an effective change leading to interesting new capabilities.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://u3d.as/5hA&quot;&gt;Behave 2 for Unity on the asset store&lt;/a&gt;.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;/behave/&quot;&gt;Project information&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
Changelist:


2.6:
 - Removed backwards compatibility with Behave 1.x assets. That should be sufficient grace.
 - Removed a number of utility types from publicly accessible namespace - should be a lot less cluttered now.
 - Changed Tree.TickWrapping to now take exception handling behaviour parameter as an enum in stead of a boolean.
 - Changed Tree.LastTickTime to return DateTime ticks rather than a UnityEngine.Time.time value.
 - Fixed corner case where Unity could lock up while stripping Behave.
 - Fixed setting of Tree.LastTicked and Tree.ActiveID. Both will always reset to ActionType.Unknown, never -1.
 - Fixed compiler being able to handle Unity being installed on a path containing spaces.
 - Improved compiler error messages.
 - Added intellisense documentation to the runtime API.
 - Added int[] Tree.SupportedActions.
 - Added Tree.Owner for better handling of agent reassigning in pooling scenarios and similar.
 - Added ICollection. GetAsInt (int) and GetAsBool (int).
 - Action handler classes.
     - Added IActionClass and Tree.SetForwards (int, IActionClass) for init/tick/reset handling to a specific class instance.
     - Added Tree.ReflectForwards (GameObject) setting forwards for MonoBehaviours implementing IActionClass.
 - Editor polish.
     - &quot;Now Behave library being edited&quot; label now comes with a shortcut &quot;Create&quot; button.
     - More informative load messages in the home screen, including progress bars.
     - With Unity 5 dropping the engine feature delta, in-editor video viewing is now available on non-pro licenses as well.


2.5.4:
 - Address Unity 5 compatibility issue with the home screen.


2.5.3:
 - Fix issue with home screen not closing.


2.5.2:
 - Play nice on Unity free again.


2.5.1:
 - More rigid network code for setting up the debugger.
 - Upgraded protobuf-net distribution to r668, Unity, full.
 - Drowned out debug logging accidentally included in 2.5.0.


2.5:
 - Optional text serialisation.
     - Switch between text and binary serialisation in library settings.
     - Full and partial exports to text or binary file.
     - NOTE: Libraries opened in this version of Behave will be upgraded and are afterwards not backwards compatible.
 - Compiler upgrade.
     - Added lots of little CPU and memory optimisations.
     - Added tree analysis leading to larger memory saves on references when possible.
     - Improved handling of circular references.
     - Improved error reporting.
     - Changed name validation.
         - Underscores are no longer allowed in names - in order to avoid name clashes with pathed assets.
         - Fixed previously allowing leading numbers in names.
 - Runtime API.
     - Added library.ReflectForwards (ICollection, object).
     - Added library.SupportedRecords (ICollection).
     - Added blueprint.SupportedTrees.
     - Added Library.DidInstantiate (ICollection / Tree).
     - Changed generated enums to be valued continuously.
     - Changed get calls for unhandled records to now return -1.
 - Editor polish.
     - Improved debugger view.
         - Improved control bar layout.
         - Improved rendering of active referenced trees.
         - Fixes to follow-focus.
         - Debug view no longer re-crops to current visible tree area, preventing the previous behaviour of the view jumping around even without follow-focus enabled.
         - Improved sidebar listing of available- and connected runtimes.
         - Improved handling of disconnecting runtimes.
         - Improved tracking of available runtimes. No more need for refreshing.
         - Improved UI for adding debugger overrides.
         - Added &quot;Add overrides enabled&quot; setting (on by default).
     - Library vertical scrollbar replaced by standalone scroll buttons top / bottom when relevant - reducing visual noise.
     - Smaller tweaks and fixes.
 - Improved internal test coverage.


2.4.2:
 - Fixed some issues related to handling priority selectors in the recently update debugger.


2.4.1:
 - Fix corner case when restructuring library assets.


2.4:
 - Introducing “records”.
     - Float fields stored in “collections” - essentially ‘smart tables’.
     - Blackboard fields.
     - Utility curves.
     - Utility graphs.
     - Behaviour Tree integration.
          - “Tester” component.
          - “Writer” component.
          - Record mode for Priority Selector component.
 - Editor behavioural change: Deleting a tree no longer deletes reference nodes targeting that tree from other trees. Their target is merely cleared.
 - Editor behavioural change: The Reference node is only available in the component bar if the library contains more than one tree. Same behaviour for Tester and Writer with records.
 - Behavioural change: Invert flag is now properly applied by the Priority Selector.
 - Debugger connection stability improvement.
 - Connection disabling has been removed. This confusing feature caused more harm than good.
 - Video player now displays video title and description.


2.3.5:
 - Fix home screen video player.


2.3.4:
 - Better error messages in case of insufficient file access privileges (OHAI Perforce).
 - Added simple version check to the home screen.
 - New icons for Priority Selector and &quot;form new tree&quot;.
 - Smaller, embedded, JSON library.
 - Fix annoying behaviour with tree renaming where text fields would keep last entry.
 - Fix similar behaviour with component text fields on tree selection change.
 - Unity 5 compatibility fixes (tested on beta 2).


2.3.3:
 - Fix focus handling issue with auto-complete.
 - Parametrisation is now correctly applied for reset handler calls.


2.3.2:
 - Fix sidebar item duplication and deletion only functional during rename.


2.3.1:
 - Fix GUI error being logged on tree selection.
 - Proper handling of currently edited library asset being deleted.


2.3:
 - Added support for instant repeaters.
 - Added support for mandatory contexts.
 - Added optional target parameter to Tree.ResetForwards.
 - Added Tree.TickWrapping method.
 - Added debugger auto-launch settings to library build options.
 - Added home screen - shown on launch or via the Help menu, full of resources.
 - Behavioural change: Decorators no longer forward the instant flag of their child node.
 - Behaviour of decorators receiving a Running signal from their control connection is now defined.
 - Dependencies now shipped as separate (replaceable) files for minimal project impact.
 - Editor polish.
     - Added support for running multiple editor debugging instances on one machine.
     - Added focus-follow for debugger and canvas.
     - Added both scrollwheel/pad and drag-to-scroll support to all canvas views.
     - Drag connection to occupied input slot to replace.
     - Directly drag-drop trees from the sidebar onto the canvas as reference nodes.
     - Instant flag doesn't show on nodes connected to parents ignoring the flag.
     - &quot;Last edited library&quot; now tracked per project.
     - Last selected tree is now also restored between sessions and playmode transitions.
     - A bunch of minor adjustments and improvements.
     - Performance + memory + disk space optimisations.
     - Minor bugfixes.
 - New documentation layout and enhancements (already released as available).
 - Reshuffling of code to make way for exciting new things down the road.


2.2.2:
 - Addressed protobuf issue causing Parallel component completion setting to not get stored correctly.


2.2.1:
 - Fixed issue causing parallel components to fail compilation.


2.2:
 - Behavioural change: Support for multiple different action handler signatures is discontinued effective immediately.
    - Generated agent blueprint as well as accepted reflected signatures are now only:
        - public BehaveResult [Tick/Init][Name]Action (Tree sender);
        - public void Reset[Name]Action (Tree sender);
 - Added Tree class accessors - all valid only during an active init/tick/reset handler call:
    - string ActiveStringParameter
    - float ActiveFloatParameter
    - IAgent ActiveAgent
    - object ActiveData
 - Rather than waiting for the Unity bugfix, the built-in compiler API is now bypassed in favour of direct compiler binary execution.
    - An additional system-level mono SDK install is no longer needed to work around this Unity bug.
 - Tree.SetForward now returns boolean success value rather than logging error when passed unused action.
 - Full-library export now also available from the library settings in stead of menu-only access.
 - Even more UI polish: Better word-wrap, more contrasts for emphasis, instant flag hidden in unaffected scenarios and much more.
 - &quot;Form new tree&quot; nicely moves the new subtree up around the root socket rather than retaining the old position.
 - Default frame-rate of DebugUpdater now set to 20 fps rather than every frame. Gun safety and all that.
 - Massive codegen size save for larger libraries - from optimisation of tree-agent introspection codegen. Compile-time win.
 - More rigid parameter evaluation (remove needless occasional extra codegen).
 - Fixed copy and duplication procedures incorrectly not copying parameter values.
 - Force Unity to write serialised data before compiling.


2.1.1:
 - Fixed issue with tree paramterisation breaking debugger visualisation.


2.1:
 - Added autocomplete on action names, string parameters and component contexts.
 - Added mandatory actions (present in library regardless of use in trees).
 - Added partial library export and library merging / import-to-library.
 - Added Behave stripping - leave behind only a very lean Behave runtime, for redistribution or super slim deploy.
 - Added parameterised trees - get even more re-use out of your trees by overriding context and variables per reference.
 - Behavioural change: Tree.Reset will now delay resetting tree variables until after complete component reset.
 - Behavioural change: Tree.Tick will no longer automatically reset the tree upon completion. This plays very well with:
 - Added Tree.TickContinuously (int iterationCap = 1024) - ticks tree till completion or iteration cap is reached.
 - Added BehaveResult Tree.Result (bool value) utility function to side with Tree.Invert (BehaveResult value).
 - Added int Debugging.Local.ConnectionCount property - facilitating debug behaviour dependent on Behave debugger presence.
 - Moved default install path from Assets/Behave to Assets/Plugins/Behave.
    - WARNING: See Readme.txt upgrade guide.
 - Fixed decorator control node removal resulting in detached control connection.
 - Fixed decorator incorrectly not forwarding the instant status of its child node.
 - Fixed scenario where agent classes would get reflected for handlers even if blueprint derived.
 - Fixed unexpected corner cases of bad library configuration failing compiles (now causing warnings or simply being ignored).
 - Fixed Behave window breaking down when exiting play mode after having been active there.
 - Fixes to context getting incorrectly reset in some scenarios.
 - Fixed copy / paste functionality missing in some text fields.
 - Lots of UI polish and minor fixes.


2.0:
 - New editor.
    - Unified all controls into one window.
    - Completely customised look - compatible with both Unity light and dark skin.
    - Keyboard authoring interface in addition to drag &amp;amp; drop.
 - Debugger upgrade.
    - Remote debugging.
    - Tick and reset.
    - &quot;Unplug&quot; for debugger-only control.
    - Breakpoints.
    - Action overrides - override the return values of specified actions.
 - Decorator rewrite.
    - Deprecated old decorator.
       - Still compiles, but cannot be added.
    - Decorators are now control-type components.
       - No specific decorator handlers on agents.
       - Control is achieved via third connection socket.
    - Two initial decorator types: Repeater and Interrupter.
 - Asset restructuring.
 	- No more collections - for nesting, use paths in tree names.
 	- New serialization format - see Readme.txt for upgrade instructions.
    - Collections are gone. Use Unix-style path names for tree organisation.
 - IAgent.Tick (Tree, bool) changed to IAgent.Tick (Tree)
	- Init calls can now only be handled explicitly
 - Full coverage online documentation and other community resources.
 - Countless fixes and polish items.

1.5:
 - Added Tree.TickActive - indicating if a tree is currently executing a tick or if it has completed evaluation.
 - In-tick tree reset requests now result in a reset at the end of tree evaluation rather than an immediate one.
 - Removed the legacy compatibility assembly (for compatibility with pre-1.2 assets) from the default distribution.
 - Fixed &quot;X must be instantiated using the ScriptableObject.CreateInstance method instead of new X&quot; warnings.

1.4:
 - Fixed decorator incorrectly initializing on every returning tick when tick handler returned Running.
 - Fixed debugger view dependency on active tree editor - causing reported null reference exception.
 - Fixed missing scrollbars on browser window.
 - Reduced logging noise from debug builds.
 - Agent blueprints can now be MonoBehaviour based.
 - Clarified wording on &quot;library not loaded&quot;.
 - Now handling reset a bit cleverer - potential performance boost.
 - Changed the default success criteria of Parallel components from SuccessOrFailure to Success.
 - Added &quot;instant&quot; flag to components. Components marked instant will affect sequences and selectors when moving between child nodes. When a child node marked &quot;instant&quot; completes, rather than waiting for the next tree tick to tick the following child node, the sequence or selector does it immediately.
 - The compiler progress bar returns.
 - Editing a Behave asset now focuses the asset browser last instead of the tree editor.
 - Behave can now be installed in any subfolder of Assets - provided its internal folder structure remains intact.
 - Compilation speed improvements.
 - Enabled references across collection borders.
 - Added Tree.DataSize - returning the number of bytes used by a tree instance. This is also displayed in the debugger window.

1.3:
 - Fixed priority selector init flag resetting.
 - Fixed reference handling on tree renaming and deletion.
 - Fixed references still pointing at old collection post collection duplication.
 - Fixed compilation of actions and decorators with non-integral float parameters.
 - Fixed GUI list behaviours.
 - Fixed passing context back and forth between referenced trees and referrer.
 - Fixed reordering connections not causing save state to be set.
 - Various GUI tweaks.
 - Runtime optimisations.
 - Enabled scrolling of the tree list in the debugger window.
 - Exposed Tree.ReflectForwards.
 - Added Tree.ResetForwards.
 - Added agent blueprints - connecting to agent handlers through virtual methods rather than reflected handlers.
 - Made connections selectable in the tree editor via the connection nub.
 - Moved connection managing from the inspector to the tree editor, where it is more visible and handy.
 - Added support for disabling connections - for faster, less destructive debugging.
 - Double-click reference component to jump to referenced tree.
 - Changed &quot;Cannot update unregistered tree&quot; handling from an exception to an error message. Still need more info.
 - Now showing string and float parameters in the tree editor if either is set.

1.2:
 - Fixed release building.
 - Added the priority selector, introducing the API points:
    - int IAgent.SelectTopPriority (Tree sender, params int[] IDs);
    - enum BL[LibraryName].PriorityType { PriorityName, ..., Unknown };
 - Added support for branch contexts, introducing the API points:
    - enum BL[LibraryName].ContextType { ContextName, ..., Unknown };
    - int Tree.ActiveContext { get; }
 - Changed IAgent interface:
    - Tick (bool init, Tree sender) -&amp;gt; Tick (Tree sender, bool init)
 - Added &quot;Select asset&quot; button to the standard inspector.
 - Interface polish.

1.1:
 - Made compatible with Unity 3.0 - including ensuring that the 2.5-2.6.1 bug preventing compilation on Windows is fixed on the Unity side.
 - UI tweaks and polish.
 - Added the option to have return values of nodes be inverted.
 - Fixed compiler bug when facing sequence or selector with only one child node.
 - Renamed Library.Tree -&amp;gt; Library.InstantiateTree.
 - Added Tree.Tick () and Tree.Reset () methods using the IAgent instance given at instantiation of the tree.
 - Removed the abstract Library class.
 - Changed generated library class:
    - Trees -&amp;gt; TreeType.
    - Actions -&amp;gt; ActionType.
    - Decorators -&amp;gt; DecoratorType.
    - Tree InstantiateTree (int, IAgent) -&amp;gt; static Tree InstantiateTree (TreeType, IAgent)
    - int TreeID (Tree) -&amp;gt; static TreeType Type (Tree)
    - bool IsAction (int) -&amp;gt; static bool IsAction (int)
    - bool IsDecorator (int) -&amp;gt; static bool IsDecorator (int)
 - Upped editor performance.
 - New asset structure change with automatic import of Behave 1.0 assets.
 - Changed action and decorator handlers. These are now the handlers mapped:
    - public BehaveResult Init[Name][Action/Decorator] (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data);
    - public BehaveResult Tick[Name][Action/Decorator] (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data);
    - public void Reset[Name][Action/Decorator] (Tree sender, string stringParameter, float floatParameter, IAgent agent, object data);
    - public BehaveResult Init[Name][Action/Decorator] (Tree sender);
    - public BehaveResult Tick[Name][Action/Decorator] (Tree sender);
    - public void Reset[Name][Action/Decorator] (Tree sender);
    - public BehaveResult [Name][Action/Decorator] {get; set;}
 - Added support for collection duplication.
 - Moved debug rendering into the editor with its own dedicated debugger window, including actor listing.
 - Debugger now renders active sub-trees as well.

1.0:
 - Lots o fixes for Unity 2.5 compatibility.
 - Closer editor integration with new UI.
    - Component bar.
    - Node inspection.
 - Runtime tree debugging.
 - Direct mapping of action and delegate handlers via reflection.
 - Kitty demo.

0.3b:
 - Various tweaks to the editor UI.
 - Optimised the compiler.
 - Fixed the following editor bugs from the bug list:
    - When the editor scrips are recompiled and when the user enters and exits play mode, running editors will loose references, causing undetermined behaviour.
    - When a compile fails, the Behave compiler is locked and unusable – requiring a unity relaunch.
 - Implemented the following wishlist items:
    - Behaviour tree decorators.
    - Stand-alone edition of the Behave editor.
    - Behaviour tree debugging features.

0.2b:
 - Made the demo project a whole lot more interesting.
 - Implemented the editor wish list item: Ability to move trees between collections.
 - Various tweaks to the editor UI.
 - Fixed a ton of bugs in the compiler.
 - Fixed the following editor bugs from the bug list:
    - Not able to delete collections from library.
    - Not able to delete trees from library.
    - Not able to rename collections from library.
    - Not able to rename trees from library.
    - Missing &quot;tree has been changed, save changes?&quot; dialog.

0.1b:
 - Some documentation is available.
 - Compiler is now creating sensible output.
 - A simple test tree and script using it is provided with the demo.
 - Documentation is linked directly from the unity help menu.
 - Less spamming of the log with debug information.

Pre-release:
 - Magic happened. Behave was born.
&lt;/pre&gt;</description>
				<published>2015-06-13 00:00:00 +0200</published>
				<link>http://www.angryant.com/2015/06/13/Behave-2-6/</link>
			</item>
		
			<item>
				<title>Trusted Gear</title>
				<description>&lt;p&gt;Yay! &lt;span class=&quot;caps&quot;&gt;GDC&lt;/span&gt; is next week! Will I see you there?&lt;/p&gt;
&lt;p&gt;Ahem. Straying a bit from my usual theme here of writing about whatever little snippet or gadget I&amp;#8217;ve come up with, for this post I will in stead share some detail on recent changes to my tool-chain of choice, which I&amp;#8217;m quite happy about.&lt;/p&gt;
&lt;p&gt;Every craftsman has his or her opinion on tooling, but just about everyone share the desire to tune their toolbox. Even if your opinion / taste / whatever does not align with mine, I hope that you find something useful in here.&lt;/p&gt;
&lt;p&gt;If you really had your sights on getting some funky code snippet out of this post, here&amp;#8217;s an unholy perl module for firing off native prompt dialogs on OS X and Windows:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/9732081d1c76dd3de9d3&quot;&gt;Unholy perl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And with that out of the way, let&amp;#8217;s get something else sorted: This post will likely come off as an ad for a bunch of different software. Other than mentioning it here, I do not intend to do anything about that.&lt;/p&gt;
&lt;p&gt;Note that I primarily work on OS X and some of the tools mentioned in this post are only available on that platform. You might still find at least inspiration in those areas though &amp;#8211; likely very nice Windows and Linux alternatives exist. I did not look.&lt;/p&gt;
&lt;p&gt;However if you are not on OS X, but on a tight schedule, just skip all sections other than the &amp;#8220;Typing&amp;#8221; section (which is probably where you&amp;#8217;ll find the best stuff anyway).&lt;/p&gt;
&lt;h2&gt;Tracking&lt;/h2&gt;
&lt;p&gt;Everyone has a system for remembering projects and TODOs. If you in stead keep it all in your head, I am glad that you&amp;#8217;re not a very busy person &amp;#8211; if you are busy, I would worry.&lt;/p&gt;
&lt;p&gt;Over time I have tried many different systems for keeping track of it all &amp;#8211; having had it as a focus of mine ever since severe physical stress symptoms reminded me that my methods were entirely inadequate.&lt;/p&gt;
&lt;p&gt;One tool that I kept coming back to and which I have recently re-focused on is &lt;a href=&quot;http://www.omnigroup.com/omnifocus/&quot;&gt;OmniFocus&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;While OmniFocus is by no means perfect (I have my fair share of open suggestion posts with the developers), it does provide me with the best feature combination I have seen in this type of tool. Important to me are:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;No restrictions or requirements on nesting/indentation depth of items.
	&lt;ul&gt;
		&lt;li&gt;The system has the notion of &amp;#8220;tasks&amp;#8221; existing in &amp;#8220;projects&amp;#8221;, but aside from this I can use folder nesting of projects and nesting of tasks as much as I like &amp;#8211; assigning whatever meaning I want to that.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;Everything is synchronised painlessly between fully-featured clients on my laptop, my phone, and my tablet. And it remains accessible when offline.&lt;/li&gt;
	&lt;li&gt;Easy, fast, unintrusive task entry.
	&lt;ul&gt;
		&lt;li&gt;The mobile clients have an always accessible &amp;#8220;add to inbox&amp;#8221; button and the OS X client a global task-entry shortcut.&lt;/li&gt;
		&lt;li&gt;The shortcut fires up a little window over whatever you are currently working, allowing you to quickly type in what you need to remember to do, hitting enter when you&amp;#8217;re done. Optionally you can add more task details before hitting enter and continuing with whatever you were doing.
		&lt;ul&gt;
			&lt;li&gt;This is absolutely perfect when you remember a &lt;span class=&quot;caps&quot;&gt;TODO&lt;/span&gt; unrelated to your current task or someone comes by your desk with a request.&lt;/li&gt;
			&lt;li&gt;My shortcut for task entry is ctrl+alt+space. I do not recall if this is the default.&lt;/li&gt;
		&lt;/ul&gt;&lt;/li&gt;
		&lt;li&gt;The OS X client also comes with a &amp;#8220;service&amp;#8221; integration, allowing you to easily create new tasks from other applications &amp;#8211; like one based on a file or a snippet of text or perhaps an email.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;Optional additional classification and data collection.
	&lt;ul&gt;
		&lt;li&gt;Putting tasks in projects is your absolutely minimum flow. Even that I suppose is optional, as you could simply put all your tasks in your inbox. On top of this, you can scale it as little or as much as makes sense for your particular case. I use everything from no additionals to everything &amp;#8211; all dependent on the nature of the task.
		&lt;ul&gt;
			&lt;li&gt;Aside from putting tasks in optional projects in optional folders, each task can also have an associated context. Different tasks in the same project can have different contexts and contexts can have additional information associated with them &amp;#8211; like a location.&lt;/li&gt;
			&lt;li&gt;Assigning a due date to a task will put it in your Forecast view &amp;#8211; allowing you to easily view what needs to get done today. This view can also show a quick overview of todays calendar and you can get notifications as the due time of a task is reached.&lt;/li&gt;
			&lt;li&gt;Each task can have an associated attachment. Anything from a snippet of text to a file / an email / whatever.&lt;/li&gt;
		&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/resources/posts/2015-02-26-Trusted-Gear/OmniFocus.png&quot; style=&quot;clear:both;float:none;&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I use OmniFocus for all project and task tracking. However I do not try to replace my calendar with it. Scheduled events still go in my calendar (I just use iCal) and I also use my calendar to keep track of what I do with my time when on a contract.&lt;/p&gt;
&lt;p&gt;This allows me to easily summarize for client reports when needed and I have a little Automator workflow calculate the total number of hours spent contracting this week &amp;#8211; allowing me to easily balance the hours.&lt;/p&gt;
&lt;h2&gt;Typing&lt;/h2&gt;
&lt;p&gt;Once I am done dreaming up ideas and tasks, like so many others, the majority of my time is spent as a typist &amp;#8211; translating those tasks into computer-friendly gibberish of one kind or another. Most of the time I find myself typing C#.&lt;/p&gt;
&lt;p&gt;For quite a while I would bounce around between different editors for this task.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;VisualStudio with resharper for maximum efficiency &amp;#8211; at the cost of either rebooting into Windows or running around in the strange parallel universe of virtualisation.&lt;/li&gt;
	&lt;li&gt;MonoDevelop for an approximation of the tools provided by VisualStudio, feeling not quite native anywhere, but very beta.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.sublimetext.com&quot;&gt;Sublime Text&lt;/a&gt; for beautiful, responsive, unintrusive text rendering, with a wonderland of user-configurable keyboard shortcuts and extensions. And absolutely nothing in terms of VS- and MD-like project-wide assistance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Then a while ago I added a bookmark to the &amp;#8220;check this out&amp;#8221; pile, for a project called &lt;a href=&quot;http://www.omnisharp.net&quot;&gt;OmniSharp&lt;/a&gt;. The promise was simple:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;Get full Intellisense-like completion and resharper-like code analysis.&lt;/li&gt;
	&lt;li&gt;Use it in your text editor of choice.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Ha! Madness.&lt;/p&gt;
&lt;p&gt;That was probably at least a half year ago &amp;#8211; until I finally found some time to put aside my scepticism for a bit and try to set it up with Sublime.&lt;/p&gt;
&lt;p&gt;You know what? It works!&lt;/p&gt;
&lt;p&gt;This is what I currently use of the OmniSharp + Sublime Text feature set:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;Compile check on save &amp;#8211; with errors, warnings, and resharper-like code suggestions.
	&lt;ul&gt;
		&lt;li&gt;Some suggestions I do not agree with and luckily, as with resharper, configuration lets you easily filter those out. Unity also suppresses some warnings when compiling, so I elected to filter those out as well.&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;li&gt;File auto-format when triggered by shortcut.&lt;/li&gt;
	&lt;li&gt;Intellisense-like auto-complete &amp;#8211; file, project and library-wide.&lt;/li&gt;
	&lt;li&gt;Jump to definition / list reference points.&lt;/li&gt;
	&lt;li&gt;Rename.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am probably forgetting something, but suffice to say, I no longer feel the need to switch away from Sublime Text to boost efficiency on an unfamiliar codebase.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/resources/posts/2015-02-26-Trusted-Gear/Sublime.png&quot;&gt;&lt;img src=&quot;/resources/posts/2015-02-26-Trusted-Gear/Sublime-Thumb.png&quot; alt=&quot;&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With regards to shortcuts and configuration, there are a bunch of little tweaks you can set up for Sublime, so of-course I have done exactly that. The good part is that Sublime preferences are all &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; formatted text files, so they are easily shared in a gist:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/aab9ff86c2595410d165&quot;&gt;Preferences in a gist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For text editing, that produces a lovely fullscreen view like the one on the right (click for full size). Tasty, right?&lt;/p&gt;
&lt;h2&gt;Searching&lt;/h2&gt;
&lt;p&gt;After lolcat searches and menacingly typing at people who are wrong, I probably spend the majority of my browser time doing reference manual lookups. Extensions like &lt;a href=&quot;http://safarikeywordsearch.aurlien.net&quot;&gt;Safari Keyword Search&lt;/a&gt; in combination with embedded search engines or Google site search have somewhat streamlined this task, but it never really worked solidly and of-course required that I be online while working.&lt;/p&gt;
&lt;p&gt;Enter &lt;a href=&quot;http://kapeli.com/dash&quot;&gt;Dash&lt;/a&gt;. I can&amp;#8217;t remember who brought it up on twitter, but that&amp;#8217;s where I came across it and bookmarked it for later study. The idea is quite simple: It provides an offline search engine for docsets of your choosing &amp;#8211; much like man pages.&lt;/p&gt;
&lt;p&gt;You get to specify which docsets to download, associate a search key with each docset (IE &amp;#8220;cpp:&amp;#8221; and &amp;#8220;.net:&amp;#8221;), and specify a global shortcut for launching the search window &amp;#8211; as you would Spotlight on OS X. But wait: There&amp;#8217;s more!&lt;/p&gt;
&lt;p&gt;Downloadable docsets include topic-specific downloads of wiki-fied Stackoverflow questions and answers. And since you can associate multiple docsets with the same search key, these are easily accessed when you search.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/resources/posts/2015-02-26-Trusted-Gear/Dash.png&quot; style=&quot;clear:both;float:none;&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;On top of all of this, Dash also comes with an iPad and iPhone client and integration for a bunch of different editors, environments and other tools &amp;#8211; including Sublime Text.&lt;/p&gt;
&lt;p&gt;You can find my Dash integration settings in the Sublime settings linked above. For global launch shortcut I chose ctrl+shift+space &amp;#8211; I do not recall if this is the default.&lt;/p&gt;
&lt;h2&gt;Navigation&lt;/h2&gt;
&lt;p&gt;If you, like me, grow a tad too accustomed to the default Sublime Text shortcut of alt+cmd+left/right for tab switching, I would recommend giving it a go as a global shortcut across applications. Configuring System Preferences &amp;#8211; Keyboard as shown below did the trick for me. I primarily use it in Terminal and Safari.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/resources/posts/2015-02-26-Trusted-Gear/Global-Tabs.png&quot; style=&quot;clear:both;float:none;&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;And that is about all I have for now. I hope that this is useful to you and do let me know if something in here is off or if you&amp;#8217;re more curious about something. If you are at &lt;span class=&quot;caps&quot;&gt;GDC&lt;/span&gt; in San Francisco next week, you could even do it in person.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.omnigroup.com/omnifocus/&quot;&gt;OmniFocus&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.sublimetext.com&quot;&gt;Sublime Text&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.omnisharp.net&quot;&gt;OmniSharp&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://gist.github.com/AngryAnt/aab9ff86c2595410d165&quot;&gt;Sublime Text and OmniSharp preferences&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://kapeli.com/dash&quot;&gt;Dash&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;https://github.com/farcaller/DashDoc&quot;&gt;DashDoc &amp;#8211; Dash Sublime integration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;






</description>
				<published>2015-02-26 00:00:00 +0100</published>
				<link>http://www.angryant.com/2015/02/26/Trusted-Gear/</link>
			</item>
		
	</channel>
</rss>