This was a project which has been a while in the making. For a long time, I’ve had 2 extra computers sitting under my desk (Top Left Photo). One had a nice GPU, and was my previous main PC (with a couple of VMs on it in hyper-V), the other was a machine I used/abused for playing around with different linux distros. On the other side of the room was an old, sad Dell Workstation with 4GB of ram, and ~18TB of disks (with a beefy PSU and an extra Sata Controller). It was running windows server essentials, and hosting some fileshares off one disk, with a monthly powershell script for updating the other disks from the master copy. It was hot and loud, and slow and not terribly reliable. I’m terrified of losing my precious data. So it’s been retired, and it’s disks have been recovered (Middle Left Photo).

My old main PC gave up its fancy GPU, its solid state storage and windows partitions to become my new Proxmox host. It has a single 500GB disk in it (Top Right Photo). It gained a Hotswap bay, in case it needs easy access to additional storage. It also went from 16GB of ram to 48GB. Proxmox mounts an NFS share from one of the Freenas pools, where the VMs and containers live. The micro case which was the linux distro testbed was converted into a slick Freenas host (Middle Right Photo for the hardware, Bottom Right for the software dashboard). The case didn’t have enough real drive bays, So I got creative. The 6TB disks are snug as bugs, but one of the 3T drives is hanging out, attached to the side panel. The hardware for freenas is as follows (If the SSDs had matched sizes, I would have been able to build a single, massive pool): An old i5 CPU is fast enough

24GB of DDR3 for a fast ZFS cache

My cheap sata controller card was automatically recognized (It’s not some fancy LSI, it’s just a $30 adaptec)

A little 120GB SSD for freenas to live on

Each pool has a large 500-1000GB SSD for cache, on the faster Sata3 ports

Each pool has 2 same-size drives mirrored for storage

The pool using my 6TB drives has no spare, the 3TB pool has a spare Once the combination was stable, it moved to the garage, where The noise of all that spinning rust isn’t a problem (Hitachi Enterprise Drives can be heard from about 30 feet). It’s a big win for the air conditioning to not be fighting against 2 always-on computers, to boot. I backed up my important data (about 1TB) to S3 Glacier, just to be completely secure. I haven’t lost substantial data since 1997, and I plan to keep it that way! 3 months ago

Recent Reading List I’m going to try something new to me. Each changed my point of view: Habits of high-functioning teams - I’ve not read very much about psychological safety or product hygene. This is a very slick primer to both topics, with lots of further reading.

Roll your own frameworks - I’m normally not a huge fan of frameworks (would prefer to see more of them built as libraries), but I find myself suddenly very warm towards micro-frameworks.

Impact Framing - This article caught my attention, and was a well-framed introduction to Impact framing, which sent me off to read a bundle of related work.

10 Reading habits that changed my life - I found this article caught me off guard. I’d previously stopped reading any books for months at a time after getting stuck. I hadn’t considered that I could be finished reading a book without getting to the end. 3 months ago

Spring 2020 Update I’ve finally released a fantasy version of legendary loot. Let’s look at the list from last time: T4 Generators: to provide argument-list-as-a-class method overloads T4 Generators: to get a C#-style-guide enforcer. NO PROGRESS LEGENDARY LOOT: to have a fantasy-themed asset available in the store DONE LEGENDARY LOOT: to have a ‘complete pack’ asset available in the store Looks like my priorities have shifted a bit, so lets put together a new list to evaluate next season: LEGENDARY LOOT: to have inventory management and collection management in all three existing assets LEGENDARY LOOT: to have a ‘complete pack’ asset available in the store T4 Generators: to provide argument-list-as-a-class method overloads. NO PROGRESS T4 Generators: to get a C#-style-guide enforcer. NO PROGRESS 6 months ago

Design ideas for Diablo III, Part 4 I keep playing Diablo III, and I keep seeing opportunities for the game to be improved with what I hope is minimal effort. I’ll go over a couple concepts quickly, and justify why I like it. Ingots: In campaign mode, enemies have a small chance to drop a new crafting material, called Ingots. The act bosses have a great chance to drop Ingots if the player plays through the campaign from start to finish. If you spend 5 Ingots on an item at the Mystic, she can reset the “re-rolled affix” on an item, so that you can reroll again. I think this is concept encourages people who have high-quality items which are nearly-perfect to go play campaign mode to get those last garbage affixes sorted out. Good Rares: I still think that there is a lot of room for Diablo III’s itemization to get better. If we simply adjust rare items, we can add some decision making around them: We need Ancient Rares, which boost STR/DEX/INT/VIT affixes by 30%

Rares in any slot can roll any skill % damage (for your class), up to 20% (Ancient: 25%)

Rares in any slot can roll any element % damage (for your class), up to 25% (Ancient: 30%) The reasoning is simple: If you can find ancient rares, and some of them are good, they’ll fit in a LoN build. I’d also like a legendary gem which discourages using the transformation abilities (Akkarats, Archon, etc). I haven’t figured out the details on that one yet, since it needs to be at a precise power level. 6 months ago

SPRING UPDATE I’ve nailed down some of the bullet points on my published roadmap, having released a free lite version of legendary loot. I’ve been working on building out the fantasy asset. I really want to find a good balance between enough stats for crunchy items and strange enemies, without making the interface unweildy. Let’s look at the list from last time: LEGENDARY LOOT: to have a proper trailer made DONE LEGENDARY LOOT: to have a very simple free edition available in the asset store DONE T4 Generators: to provide argument-list-as-a-class method overloads T4 Generators: to get a C#-style-guide enforcer. ALMOST DONE but this needs to have the legendary-loot-specifics removed from it. LEGENDARY LOOT: to have a fantasy-themed asset available in the store WIP LEGENDARY LOOT: to have a ‘complete pack’ asset available in the store 1 year ago

I’ve long loved the idea of having computer-synthesized speech in my projects. For the trailer for Legendary Loot, I’m doing that using Amazon Polly. My process will make up the rest of this post. First, I wrote out what I wanted the computer to say, then i marked it up using just a few tags in SSML, in an effort to produce more natural, more radio-announcer-like speech. the code follows. <speak> <prosody pitch="high" amazon:max-duration="60s"> You want <prosody pitch="medium" volume="soft">to build a</prosody> game <prosody pitch="medium" volume="soft">with</prosody> interesting <emphasis>items</emphasis> <prosody pitch="medium" volume="soft">and</prosody> <emphasis>enemies</emphasis>. You want <prosody pitch="medium" volume="soft">to get</prosody> <prosody rate="fast">up and running</prosody> without spending <emphasis>months</emphasis> designing and programming <prosody pitch="medium" volume="soft">a</prosody> <emphasis>stat, engine</emphasis>. That's why you need <emphasis>Legendary Loot</emphasis>. <emphasis>Legendary loot</emphasis> <prosody pitch="medium" volume="soft">is a</prosody> collection of out-of-the-box <emphasis>stat, engines</emphasis> along with supporting <emphasis>factories</emphasis> <prosody pitch="medium" volume="soft">for</prosody> generating random <emphasis>enemies</emphasis> <prosody pitch="medium" volume="soft">or</prosody> <emphasis>items</emphasis>. <prosody pitch="medium" volume="soft">And lots of </prosody> handy glue code <prosody pitch="medium" volume="soft">for</prosody> tying <prosody pitch="medium" volume="soft">the</prosody> <emphasis>stat, engine</emphasis> <prosody pitch="medium" volume="soft">into</prosody> your game. Lets <prosody rate="fast">dive right in</prosody> <prosody pitch="medium" volume="soft">by</prosody> making some <emphasis>random items</emphasis> <prosody pitch="medium" volume="soft">in the</prosody> next minute. </prosody> </speak> After switching Polly over to a british voice, I downloaded the OGG. Next up was Audacity. First, we normalize the waveform, then I used the compressor to tweak it slightly. I made a copy of that track, and then put just the “wet” component of reverb there, so that I could adjust it’s volume. In the background of the trailer there will be some pink noise to help the voice sound more normal as well. The trailer follows. 1 year ago

ROADMAP Readers who have been following me for some time will note that my posting has slowed down of late, and there are a number of causes (one of which is my ever-curious daughter, pictured above today, and a year ago). I won’t go into any other causes. I am also not going to be specific about dates in this post, only about deliverables. I have a number of personal projects in various states, includng a small public collection of T4 generators, this blog, and my Unity3d Asset, LEGENDARY LOOT, in adition to my full-time work. The following is a list of upcoming deliverables, in the order I plan to deliver them. LEGENDARY LOOT: to have a proper trailer made LEGENDARY LOOT: to have a very simple free edition available in the asset store T4 Generators: to provide argument-list-as-a-class method overloads T4 Generators: to get a C#-style-guide enforcer. LEGENDARY LOOT: to have a fantasy-themed asset available in the store LEGENDARY LOOT: to have a ‘complete pack’ asset available in the store Thats all for now. I hope to do this sort of post again. 1 year ago

I’ve opened up two generators written for work (both have been stripped down). They generate code in a C# codebase in response to attributes. The SnippetInserter.tt can insert generated code into any file, removing all the ‘snippet’ code beforehand, to ensure that it runs cleanly. It’s great for registering with IC frameworks and you could make a helper class for wrapping up all the arguments to a method (especially useful if you have a lot of primitive arguments, where the compiler is going to write a class anyways). The Wrapper.tt is for aggregating methods from all over into 2 core interfaces: one for commands, and one for queries. It’s a good way to declutter, by just showing a few methods in one namespace. Eventually, I want to have a personal template-driven system for writing C# quickly. Code lives here: https://gitlab.com/ANVILSOFTWORKS/T4-dump 1 year ago

I’ve been working on a previewer for the factories. It shows the output of your factory system in a massive, always-updating grid. 2 years ago

Recording code without typos This little snippet of code is for autohotkey. It takes the text from your clipboard, and slowly ‘types’ it, which is great for recording tutorial videos, especially talking though a piece of code while appearing to 'type’ it in real time. I’ve got a little tutorial below where I’m using an earlier version of it (without Brad’s fixed newlines nor the more realistic key rates). And below that is the ahk script itself. Sleep 2500 Loop, parse, clipboard { MyVar := A_LoopField StringReplace, MyVar, MyVar, `n, , All SendRaw %MyVar% random, rand, 100, 450 random, rand, 70, rand Sleep rand } Esc::ExitApp 2 years ago

Launch I’ve finally launched my asset, LEGENDARY LOOT SCI-FI PACK. It’s a tool for constructing stat-heavy games. An object with stats can be composed from easy-to-work-with asset components representing every aspect of it, from parts of the name, race, class, background, modifiers for quality, rarity, or level. In-scene factories describe how to build them on-the-fly. 2 years ago

I’ve found this utility to be an effective tool for delaying work in C#. public class Later: IDisposable { Action ToDo; public Later(Action toDo){ToDo = toDo;} void Dispose() { ToDo.Invoke(); } } Usage: using(var q = new Later(() => { //this runs last } )) { //this runs first } 2 years ago