<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Andrew Russell</title>
	<atom:link href="https://andrewrussell.net/feed/" rel="self" type="application/rss+xml" />
	<link>https://andrewrussell.net</link>
	<description>The website of independent game developer Andrew Russell</description>
	<lastBuildDate>Fri, 07 Feb 2025 23:55:00 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.1.10</generator>
	<item>
		<title>Dual CV Source Updated, Free Devices</title>
		<link>https://andrewrussell.net/2025/02/dual-cv-source-updated-free-devices/</link>
					<comments>https://andrewrussell.net/2025/02/dual-cv-source-updated-free-devices/#comments</comments>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Fri, 07 Feb 2025 23:54:58 +0000</pubDate>
				<category><![CDATA[Andrew’s Blog]]></category>
		<guid isPermaLink="false">https://andrewrussell.net/?p=1486</guid>

					<description><![CDATA[If you&#8217;re a Reason user, and you&#8217;re just here for some cheap and free stuff, here are the links: This will be the lowest price of Dual CV Source for a while, so be sure to grab it during the discount window! ~ This post is something of a continuation from my previous post, which [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;re a Reason user, and you&#8217;re just here for some cheap and free stuff, here are the links:</p>
<ul>
<li><a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">Double Dry/Wet</a>, <a href="https://www.reasonstudios.com/shop/rack-extension/velocity-curve/">Velocity Curve</a>, and <a href="https://www.reasonstudios.com/shop/rack-extension/denote/">Denote</a> are now <strong>free</strong>!</li>
<li><strong>Version 2.0</strong> of <a href="https://www.reasonstudios.com/shop/rack-extension/dual-cv-source/">Dual CV Source</a> is out now, with a permanent price drop from $45 to $29, and a <strong>half-price</strong> launch discount</li>
</ul>
<p>This will be the lowest price of Dual CV Source for a while, so be sure to grab it during the discount window!</p>
<p class="has-text-align-center">~</p>
<p>This post is something of a continuation from my <a href="https://andrewrussell.net/2024/06/still-alive/">previous post</a>, which talked about where I&#8217;ve been for the last couple of years (working on AAA games). In this post, I&#8217;ll start with some background on Dual CV Source version 2.0, and end by talking about why I&#8217;m releasing my other devices for free.</p>
<figure class="wp-block-image size-large"><img decoding="async" width="853" height="78" src="https://andrewrussell.net/content/2025/02/DemoPanel-scaled-1-853x78.png" alt="" class="wp-image-1488" srcset="https://andrewrussell.net/content/2025/02/DemoPanel-scaled-1-853x78.png 853w, https://andrewrussell.net/content/2025/02/DemoPanel-scaled-1-480x44.png 480w, https://andrewrussell.net/content/2025/02/DemoPanel-scaled-1-256x23.png 256w, https://andrewrussell.net/content/2025/02/DemoPanel-scaled-1-768x70.png 768w, https://andrewrussell.net/content/2025/02/DemoPanel-scaled-1-1536x141.png 1536w, https://andrewrussell.net/content/2025/02/DemoPanel-scaled-1.png 1650w" sizes="(max-width: 853px) 100vw, 853px" /></figure>
<p>Work on Dual CV Source 2.0 started before 1.0 was launched. When I was writing the user manual for 1.0, I found myself writing a section on how to transpose notes. MIDI notes have values from 0 to 127, corresponding to notes C-2 to G8 (with Reason octave numbering). Reason CV maps this range to floating-point values between 0.0 and 1.0.</p>
<p>In order to transpose notes, you need a way to generate the value 1/127. Dual CV Source has a division operation, which is probably a little easier than remembering the number 0.007874. But, either way, you need one Dual CV Source device to generate that value, and a second one to do a multiply and the actual transposition. Not user-friendly.</p>
<p>It would be much easier if Dual CV Source just let you enter semitones directly. I roughly designed the feature before launching 1.0. It was fortunate that I did, because it required expanding the range of the Offset control from [-9, 9] to [-10, 10] — something that would have been impossible to change later, due to Reason&#8217;s backward-compatibility requirements.</p>
<p>(The device needs a way to represent the value of 1.0, so that it can pass through values unchanged for things like visualisation. With 10 octaves (offsets 0 to 9 inclusive), it can only represent values up to 120 semitones, less than the 127 required. I doubt anyone has ever looked at the Offset control and wondered why it had this seemingly unnecessary extra range. But, if you have, well, now you know.)</p>
<p>In version 2.0, when you change the Magnitude control to &#8220;Octave&#8221;, you enter the new semitone mode. In this mode, Offset controls the number of octaves, and the Fine control changes to a stepped Semitone control. The displays will show semitones with the following symbol:</p>
<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" loading="lazy" width="95" height="55" src="https://andrewrussell.net/content/2025/02/SemitonesSymbol.png" alt="" class="wp-image-1489"/></figure>
</div>
<p>This symbol is something that I came up with, reusing the LCD elements that already existed for displaying ♯ and ♭. It looks something like an &#8216;S&#8217;, and something like a stair-step: a reasonable representation of &#8220;semitones&#8221;. This ended up being far more readable than an abbreviation like &#8220;St&#8221; (S is identical to a 5) or &#8220;ht&#8221; (for half-tone), when placed adjacent to the numbers in the digital display.</p>
<p>With that, there is a way to represent semitones in Dual CV Source. Dual CV Source already has a button that adds the value of Channel A to Channel B, allowing transposition, but this means that the result of a transposition ends up on Channel B. In version 1.0, the note-related features — digital note display and Key Snap — were only available on Channel A. Version 2.0 adds those same features to Channel B.</p>
<p>The other major feature added in version 2.0, continuing the theme of note manipulation, is the new &#8220;spread&#8221; Key Snap mode. The original Key Snap mode just snaps to the nearest note in the scale. The new &#8220;spread&#8221; mode puts equal spacing between notes, giving more musical results when sweeping through a range of values.</p>
<p>Also in 2.0 are a number of graphical improvements. The Advanced panel looks a lot nicer, as well as clearer, with its black strips and orange switches.</p>
<p>Old:</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="853" height="78" src="https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-853x78.png" alt="" class="wp-image-1457" srcset="https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-853x78.png 853w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-256x23.png 256w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-480x44.png 480w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-768x70.png 768w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled.png 1508w" sizes="(max-width: 853px) 100vw, 853px" /></figure>
<p>New:</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="853" height="78" src="https://andrewrussell.net/content/2025/02/AdvancedPanel-853x78.png" alt="" class="wp-image-1490" srcset="https://andrewrussell.net/content/2025/02/AdvancedPanel-853x78.png 853w, https://andrewrussell.net/content/2025/02/AdvancedPanel-480x44.png 480w, https://andrewrussell.net/content/2025/02/AdvancedPanel-256x23.png 256w, https://andrewrussell.net/content/2025/02/AdvancedPanel-768x70.png 768w, https://andrewrussell.net/content/2025/02/AdvancedPanel-1536x141.png 1536w, https://andrewrussell.net/content/2025/02/AdvancedPanel-2048x187.png 2048w" sizes="(max-width: 853px) 100vw, 853px" /></figure>
<p>Far more complicated was making some display elements high-resolution. For version 1.0, I had implemented a way to render bitmap graphics in a Reason &#8220;display&#8221; element, in order to fit the functionality I wanted into a 1U-tall device. This stopped working as soon as Reason 12 came out with support for high-resolution graphics. Reason has some strict limitations on how controls and toggleable elements can be layered, and almost the entire device device is already toggleable with the Advanced panel. With some trickery, I was able to get elements like the Scale menu and the Sustain icon to display correctly and in high-resolution, in version 2.0.</p>
<p>Speaking of graphics-related complications, in Reason 11 and earlier on Windows, if you created 37 Dual CV Source devices, Reason <em>itself</em> would crash, by running out of Windows graphical resources. This ended up being caused by the way I was displaying all of the polyphony markers on the back panel. For anyone still on Reason 10 or 11, I found a different technique, and this is now fixed. Sorry it took so long!</p>
<p>(Shout out to <a href="https://www.youtube.com/@PoohBearsReasonChannel/">PoohBear</a> for discovering that one. He&#8217;s the sort of fellow who <em>would</em> create 37 copies of DCVS in earnest. Fortunately for him, we found a registry key that could increase the Windows limit.)</p>
<p>And that&#8217;s about it. I&#8217;m still very proud of <a href="https://www.reasonstudios.com/shop/rack-extension/dual-cv-source/">Dual CV Source</a>, a device that offers an enormous amount of power in just 1U of space, and has features that you won&#8217;t find anywhere else!</p>
<p class="has-text-align-center">~</p>
<p>Let&#8217;s talk about my other devices, which I am now releasing for free.</p>
<p>In my <a href="https://andrewrussell.net/2024/06/still-alive/">previous post</a>, I talked about how Reason 13 came out with a new Gain Tool that looks suspiciously like <a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">Double Dry/Wet</a>.</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="853" height="77" src="https://andrewrussell.net/content/2024/06/Front-Panel-853x77.png" alt="" class="wp-image-1474" srcset="https://andrewrussell.net/content/2024/06/Front-Panel-853x77.png 853w, https://andrewrussell.net/content/2024/06/Front-Panel-480x43.png 480w, https://andrewrussell.net/content/2024/06/Front-Panel-256x23.png 256w, https://andrewrussell.net/content/2024/06/Front-Panel-768x69.png 768w, https://andrewrussell.net/content/2024/06/Front-Panel-1536x139.png 1536w, https://andrewrussell.net/content/2024/06/Front-Panel.png 1650w" sizes="(max-width: 853px) 100vw, 853px" /></figure>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="696" height="136" src="https://andrewrussell.net/content/2025/02/Screenshot-2025-02-02-at-5.26.18 pm.png" alt="" class="wp-image-1492" srcset="https://andrewrussell.net/content/2025/02/Screenshot-2025-02-02-at-5.26.18 pm.png 696w, https://andrewrussell.net/content/2025/02/Screenshot-2025-02-02-at-5.26.18 pm-480x94.png 480w, https://andrewrussell.net/content/2025/02/Screenshot-2025-02-02-at-5.26.18 pm-256x50.png 256w" sizes="(max-width: 696px) 100vw, 696px" /></figure>
<p>I&#8217;ve since had a chance to play with Gain Tool, and what I said in that post holds true: I&#8217;d expect people to use Gain Tool before Double Dry/Wet in most &#8220;I need a quick way to mix this&#8221; scenarios. Gain Tool won&#8217;t do the fancy two-layer Dry/Wet thing that Double Dry/Wet can do, but you can construct that effect using multiple Gain Tool instances.</p>
<p>One big advantage of constructing it using multiple devices is that it forces you to not create loops in your audio chain, which is something that Double Dry/Wet encourages! A loop is when the audio path comes out of one device only to end up going back into that same device. This means that the returning audio ends up delayed by the audio buffer length, relative to the original input. If you don&#8217;t apply a correction for this delay, you end up with an audible comb-filter effect. To solve this problem, Double Dry/Wet has a delay-compensation feature (which I talked about back in <a href="https://andrewrussell.net/2020/06/non-standard-routing-detected/">this post</a>).</p>
<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" loading="lazy" width="104" height="136" src="https://andrewrussell.net/content/2020/06/Delay-Comp-Section.png" alt="" class="wp-image-1436"/></figure>
</div>
<p>But that button is manual and fiddly to use. It can&#8217;t remove the delay, only ensure all audio has the <em>same</em> delay. It also doesn&#8217;t work properly anymore! Reason 11 changed the way audio is buffered, for higher performance, and that feature in Reason must be disabled for Double Dry/Wet&#8217;s delay compensation to apply the correct amount of delay. The latest Double Dry/Wet user manual suggests a multi-device construction to avoid the issue.</p>
<p>I still love the effects you can create with Double Dry/Wet. But, now that Gain Tool is built-in to Reason, the amount of added value Double Dry/Wet provides is much smaller.</p>
<p>Then Reason 13.1 came out, with a new Note Tool&#8230;</p>
<p>First, it was awesome to see Ryan using my <a href="https://www.reasonstudios.com/shop/rack-extension/denote/">Denote</a> device in the official video demonstrating Note Tool (<a href="https://youtu.be/3cqnIMEZohY?t=425">timestamped link</a>).</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="853" height="82" src="https://andrewrussell.net/content/2020/04/FrontPanel-853x82.png" alt="" class="wp-image-1370" srcset="https://andrewrussell.net/content/2020/04/FrontPanel-853x82.png 853w, https://andrewrussell.net/content/2020/04/FrontPanel-256x25.png 256w, https://andrewrussell.net/content/2020/04/FrontPanel-480x46.png 480w, https://andrewrussell.net/content/2020/04/FrontPanel-768x74.png 768w" sizes="(max-width: 853px) 100vw, 853px" /></figure>
<p>Denote was designed exactly for this purpose: a simple, large display for inspecting playing notes — it&#8217;s as large as possible, while being pixel-perfect. As an added bonus, you can click individual notes to mute them.</p>
<p>With Note Tool&#8217;s filter section, Reason now has a built-in way to display and filter notes. That part of Note Tool is not as sophisticated or readable as Denote. But the additional value that Denote provides to Reason users is now just that little bit smaller.</p>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="526" height="340" src="https://andrewrussell.net/content/2025/02/image.png" alt="" class="wp-image-1493" srcset="https://andrewrussell.net/content/2025/02/image.png 526w, https://andrewrussell.net/content/2025/02/image-480x310.png 480w, https://andrewrussell.net/content/2025/02/image-256x165.png 256w" sizes="(max-width: 526px) 100vw, 526px" /></figure>
<p>Given that I&#8217;ve regularly given away Denote for free in sales (hoping to drive traffic to my other devices, I am not sure how successful this has been), I feel like now is the right time to make it free permanently.</p>
<p>Finally,  we come to <a href="https://www.reasonstudios.com/shop/rack-extension/velocity-curve/">Velocity Curve</a>.</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="853" height="82" src="https://andrewrussell.net/content/2020/04/FrontPanel-1-853x82.png" alt="" class="wp-image-1378" srcset="https://andrewrussell.net/content/2020/04/FrontPanel-1-853x82.png 853w, https://andrewrussell.net/content/2020/04/FrontPanel-1-256x25.png 256w, https://andrewrussell.net/content/2020/04/FrontPanel-1-480x46.png 480w, https://andrewrussell.net/content/2020/04/FrontPanel-1-768x74.png 768w" sizes="(max-width: 853px) 100vw, 853px" /><figcaption class="wp-element-caption">(I am just now realising that my main image I use to demonstrate Velocity Curve doesn&#8217;t show a curve in the display. What a miss! I&#8217;ll also post an old, lower-resolution demo image.)</figcaption></figure>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="790" height="177" src="https://andrewrussell.net/content/2025/02/image-2.png" alt="" class="wp-image-1501" srcset="https://andrewrussell.net/content/2025/02/image-2.png 790w, https://andrewrussell.net/content/2025/02/image-2-480x108.png 480w, https://andrewrussell.net/content/2025/02/image-2-256x57.png 256w, https://andrewrussell.net/content/2025/02/image-2-768x172.png 768w" sizes="(max-width: 790px) 100vw, 790px" /><figcaption class="wp-element-caption">(Denote sneaks in again as a great way to demonstrate other player devices.)</figcaption></figure>
<p>Now, Note Tool:</p>
<figure class="wp-block-image size-full"><img decoding="async" loading="lazy" width="252" height="311" src="https://andrewrussell.net/content/2025/02/image-1.png" alt="" class="wp-image-1494" srcset="https://andrewrussell.net/content/2025/02/image-1.png 252w, https://andrewrussell.net/content/2025/02/image-1-207x256.png 207w" sizes="(max-width: 252px) 100vw, 252px" /></figure>
<p>I don&#8217;t know about you, but that looks a lot like a <em>curve</em> to adjust the <em>velocity</em>. A &#8220;Velocity Curve&#8221;, if you will.</p>
<p>Along with its velocity range filter, Note Tool can do the same velocity adjustments that Velocity Curve can do. And it&#8217;s built-in to Reason. Sure, Velocity Curve has a drawing mode, but that is a fiddly-to-use, esoteric feature. So, once again, the additional value that someone would get by buying Velocity Curve is much smaller.</p>
<p>With Reason 13&#8217;s Gain Tool, and 13.1&#8217;s Note Tool, these three useful little devices of mine are no longer as compelling as they once were. I don&#8217;t feel I can justify charging money for them anymore. For me, making Reason Rack Extension devices is a wish-I-had-more-time-for-it hobby, and not a major source of income. So now feels like the right time for me to give them away for free. I hope you enjoy!</p>
<p>It does feel like Reason Studios has taken just a little bit of inspiration from my devices, here. I have no idea if that&#8217;s true or not, but it feels good to think that those propellerheads liked my devices enough to borrow some ideas, so I&#8217;m going to believe it anyway.</p>
<p>If you&#8217;d like to support my work, check out <a href="https://www.reasonstudios.com/shop/browse/?developer=Andrew%20Russell">my devices in the Reason Shop</a>, download the free ones, and buy a copy of Dual CV Source.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://andrewrussell.net/2025/02/dual-cv-source-updated-free-devices/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Still Alive</title>
		<link>https://andrewrussell.net/2024/06/still-alive/</link>
					<comments>https://andrewrussell.net/2024/06/still-alive/#comments</comments>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Sun, 23 Jun 2024 01:29:07 +0000</pubDate>
				<category><![CDATA[Andrew’s Blog]]></category>
		<guid isPermaLink="false">https://andrewrussell.net/?p=1472</guid>

					<description><![CDATA[Hello Internet! Just a quick update to let you know that I&#8217;m still alive. A lot has changed in 4 years. I&#8217;ve been working in AAA game development, mostly working on netcode. I got married, bought a house, lots of life stuff. I also grew a beard. I have the &#8216;ok&#8217; from my employer to [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Hello Internet! Just a quick update to let you know that I&#8217;m still alive.</p>
<p>A lot has changed in 4 years. I&#8217;ve been working in AAA game development, mostly working on netcode. I got married, bought a house, lots of life stuff. I also grew a beard.</p>
<p>I have the &#8216;ok&#8217; from my employer to work on my <a href="https://andrewrussell.net/rack-extensions/">Rack Extensions</a> as side-projects. Maybe I&#8217;ll ask for the &#8216;ok&#8217; to do some tiny game development stuff in the future. It&#8217;s more of a &#8220;spare time&#8221; question for me, than anything else.</p>
<p>I have an update for <a href="https://andrewrussell.net/2020/08/introducing-dual-cv-source/" data-type="URL" data-id="https://andrewrussell.net/2020/08/introducing-dual-cv-source/">Dual CV Source</a> coming soon. It&#8217;s been coming soon for years, but it&#8217;s taken a long time to find space to do the dozens of tiny polish things needed to get it released. I&#8217;ll post an update when it&#8217;s ready.</p>
<p>I also have some plans for a tiny feature update to <a href="https://www.reasonstudios.com/shop/rack-extension/denote/">Denote</a>, but I haven&#8217;t even started that yet.</p>
<p>In the mean time, Reason 13 has come out, with a built-in device called &#8220;Gain Tool&#8221; that looks suspiciously like <a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/" data-type="URL" data-id="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">Double Dry/Wet</a>:</p>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="853" height="288" src="https://andrewrussell.net/content/2024/06/Gain-Tool-853x288.png" alt="" class="wp-image-1473" srcset="https://andrewrussell.net/content/2024/06/Gain-Tool-853x288.png 853w, https://andrewrussell.net/content/2024/06/Gain-Tool-480x162.png 480w, https://andrewrussell.net/content/2024/06/Gain-Tool-256x86.png 256w, https://andrewrussell.net/content/2024/06/Gain-Tool-768x259.png 768w, https://andrewrussell.net/content/2024/06/Gain-Tool.png 912w" sizes="(max-width: 853px) 100vw, 853px" /></figure>
<figure class="wp-block-image size-large"><img decoding="async" loading="lazy" width="853" height="77" src="https://andrewrussell.net/content/2024/06/Front-Panel-1-853x77.png" alt="" class="wp-image-1475" srcset="https://andrewrussell.net/content/2024/06/Front-Panel-1-853x77.png 853w, https://andrewrussell.net/content/2024/06/Front-Panel-1-480x43.png 480w, https://andrewrussell.net/content/2024/06/Front-Panel-1-256x23.png 256w, https://andrewrussell.net/content/2024/06/Front-Panel-1-768x69.png 768w, https://andrewrussell.net/content/2024/06/Front-Panel-1-1536x139.png 1536w, https://andrewrussell.net/content/2024/06/Front-Panel-1.png 1650w" sizes="(max-width: 853px) 100vw, 853px" /><figcaption class="wp-element-caption"><em>Looks similar, right??</em></figcaption></figure>
<p>I haven&#8217;t tried Reason 13 yet, so I am going off some of the pre-release videos. It looks like Double Dry/Wet is still more versatile, with two-level parallel mixing, and an explicit &#8220;dry/wet&#8221; setup (basically: they have 3 knobs, I have 6). But it looks like Gain Tool reduces the utility of some of my &#8220;clever&#8221; design choices, that also let you use Double Dry/Wet as a basic crossfader or mixer tool.</p>
<p>Because of that, I&#8217;ve dropped the price to $9, so now is a great time to <a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/" data-type="URL" data-id="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">get it</a>!</p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://andrewrussell.net/2024/06/still-alive/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Introducing Dual CV Source</title>
		<link>https://andrewrussell.net/2020/08/introducing-dual-cv-source/</link>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Tue, 25 Aug 2020 10:46:19 +0000</pubDate>
				<category><![CDATA[Andrew’s Blog]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1462</guid>

					<description><![CDATA[This is a device that I am incredibly proud of. What started as a simple way to get a precise fixed CV value, evolved into a feature-rich – yet tiny – general-purpose CV utility. You can get it now from the Rack Extension shop. When designing Dual CV Source, I set myself two rules: Rule [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><a href="https://andrewrussell.net/content/2020/08/DemoPanel-scaled.png"><img decoding="async" loading="lazy" class="aligncenter wp-image-1456 size-large" src="https://andrewrussell.net/content/2020/08/DemoPanel-scaled-853x78.png" width="853" height="78" srcset="https://andrewrussell.net/content/2020/08/DemoPanel-scaled-853x78.png 853w, https://andrewrussell.net/content/2020/08/DemoPanel-scaled-256x23.png 256w, https://andrewrussell.net/content/2020/08/DemoPanel-scaled-480x44.png 480w, https://andrewrussell.net/content/2020/08/DemoPanel-scaled-768x70.png 768w, https://andrewrussell.net/content/2020/08/DemoPanel-scaled.png 1508w" sizes="(max-width: 853px) 100vw, 853px" /></a></p>
<p>This is a device that I am incredibly proud of. What started as a simple way to get a precise fixed CV value, evolved into a feature-rich – yet tiny – general-purpose CV utility.</p>
<p><a href="https://www.reasonstudios.com/shop/rack-extension/dual-cv-source/">You can get it now from the Rack Extension shop.</a></p>
<p>When designing Dual CV Source, I set myself two rules:</p>
<p>Rule 1: Keep it 1U in size.</p>
<p>This was a real challenge, given how much functionality I wanted to pack in. But it was important for me to keep the device small, so that it wouldn’t feel like it was hogging rack space when you just want to drop in a quick static value source or attenuverter.</p>
<p>Rule 2: Don’t implement anything time-based.</p>
<p>Knowing what to cut is important. This means: no LFOs and no envelopes. Fortunately Reason’s built-in Pulsar device has those features. And keeping them out of Dual CV Source ensures that the user interface is simple and understandable, and it simplifies the implementation.</p>
<p>Within those two restrictions, my goal was to implement every major utility function you would find in a typical modular setup. So there’s a MIDI-to-CV, a quantizer, a sample-and-hold/track-and-hold. You can offset and multiply signals. And there’s a variety of other maths and logic functions.</p>
<p><a href="https://andrewrussell.net/content/2020/08/DemoBackPanel-scaled.png"><img decoding="async" loading="lazy" class="aligncenter wp-image-1453 size-large" src="https://andrewrussell.net/content/2020/08/DemoBackPanel-scaled-853x78.png" width="853" height="78" srcset="https://andrewrussell.net/content/2020/08/DemoBackPanel-scaled-853x78.png 853w, https://andrewrussell.net/content/2020/08/DemoBackPanel-scaled-256x23.png 256w, https://andrewrussell.net/content/2020/08/DemoBackPanel-scaled-480x44.png 480w, https://andrewrussell.net/content/2020/08/DemoBackPanel-scaled-768x70.png 768w, https://andrewrussell.net/content/2020/08/DemoBackPanel-scaled.png 1508w" sizes="(max-width: 853px) 100vw, 853px" /></a></p>
<p>I did cheat a little bit on Rule 2 by including a latched random number generator. While it would have been simple enough to just generate purely random numbers, I felt it was important that the random numbers were consistent between different playbacks, so the random number generator works from note timing and note values. So the same note in the same place will give you the same random number – no matter how you change the other notes in the song, the BPM or the sample rate.</p>
<p>(I felt that random number generation was such a common use-case that it needed to be a built in function, rather than having the user set up a random LFO and a latch. There’s also a built-in Velocity Hold function for the same reason.)</p>
<p><a href="https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled.png"><img decoding="async" loading="lazy" class="aligncenter wp-image-1457 size-large" src="https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-853x78.png" width="853" height="78" srcset="https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-853x78.png 853w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-256x23.png 256w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-480x44.png 480w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled-768x70.png 768w, https://andrewrussell.net/content/2020/08/AdvancedPanel-scaled.png 1508w" sizes="(max-width: 853px) 100vw, 853px" /></a></p>
<p>To mention a few more features: The whole device supports up to 4-channels of polyphony. The MIDI-to-CV is configurable (choose your note mode, retrigger and sustain options). And there’s support for the full CV range (values up to ±10,000).</p>
<p>Oh, and the displays are fully interactive! So if you need to enter a precise value or note, you can modify each digit individually.</p>
<p>There’s so much in Dual CV Source that I wrote a complete <a href="https://andrewrussell.net/content/2020/08/Dual-CV-Source-User-Manual.pdf">user manual</a>, and it came in at a healthy 20 pages. I hope that the device is intuitive enough without needing the manual, but if you want to know exactly how something works, the details are there.</p>
<p>If you use CV in your songs, then my hope is that Dual CV Source will become an indispensable part of your workflow. And if you don’t use CV yet, then perhaps Dual CV Source – with its ability to digitally and graphically visualise CV signals – will help you get started in this exciting layer of production.</p>
<p><a href="https://www.reasonstudios.com/shop/rack-extension/dual-cv-source/">Get Dual CV Source</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Double Dry/Wet Update</title>
		<link>https://andrewrussell.net/2020/06/double-drywet-update/</link>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Thu, 11 Jun 2020 11:48:22 +0000</pubDate>
				<category><![CDATA[Andrew’s Blog]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1438</guid>

					<description><![CDATA[I’m very pleased to announce an update to my first Rack Extension: Double Dry/Wet. Version 2.0 adds two new features: Delay Compensation and CV control. The latter of which I am incredibly excited about! Delay compensation fixes a design oversight in the original device. I’ve written a more extensive write-up about it here. The short [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I’m very pleased to announce an update to my first Rack Extension: <a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">Double Dry/Wet</a>.</p>
<p>Version 2.0 adds two new features: Delay Compensation and CV control. The latter of which I am incredibly excited about!</p>
<p><a href="https://andrewrussell.net/content/2020/06/FrontPanelFull.png"><img decoding="async" loading="lazy" class="aligncenter wp-image-1439 size-large" src="https://andrewrussell.net/content/2020/06/FrontPanelFull-853x77.png" width="853" height="77" srcset="https://andrewrussell.net/content/2020/06/FrontPanelFull-853x77.png 853w, https://andrewrussell.net/content/2020/06/FrontPanelFull-256x23.png 256w, https://andrewrussell.net/content/2020/06/FrontPanelFull-480x43.png 480w, https://andrewrussell.net/content/2020/06/FrontPanelFull-768x69.png 768w" sizes="(max-width: 853px) 100vw, 853px" /></a></p>
<p>Delay compensation fixes a design oversight in the original device. I’ve written a more extensive write-up about it <a href="https://andrewrussell.net/2020/06/non-standard-routing-detected/">here</a>. The short version is this: if you form a signal loop – which the primary way to use Double Dry/Wet – you introduce a delay between the output and input sides of that loop.</p>
<p>This causes an unwanted comb filter effect. Now you can get rid of it by hitting the “delay compensation” button on the back panel.</p>
<p><a href="https://andrewrussell.net/content/2020/06/BackPanelFull.png"><img decoding="async" loading="lazy" class="aligncenter wp-image-1440 size-large" src="https://andrewrussell.net/content/2020/06/BackPanelFull-853x84.png" width="853" height="84" srcset="https://andrewrussell.net/content/2020/06/BackPanelFull-853x84.png 853w, https://andrewrussell.net/content/2020/06/BackPanelFull-256x25.png 256w, https://andrewrussell.net/content/2020/06/BackPanelFull-480x48.png 480w, https://andrewrussell.net/content/2020/06/BackPanelFull-768x76.png 768w" sizes="(max-width: 853px) 100vw, 853px" /></a></p>
<p>CV control has been sitting in my “todo” list since the initial release, as something I’d add eventually, when the opportunity arose.</p>
<p>Now that I’ve added it: I should never have waited!</p>
<p>Having CV control has been a complete revelation! It takes Double Dry/Wet from an intuitive-yet-static signal mixer, to a <strong>modulation powerhouse</strong>. The sounds you can make, by dynamically switching between two effect chains, are <em>wild! </em>Hook it up to a LFO or an ASDR envelope, and you will not be disappointed.</p>
<p>I am going to be having fun playing with this for a long time, and I really recommend that you <a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">try it out</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Non-Standard Routing Detected</title>
		<link>https://andrewrussell.net/2020/06/non-standard-routing-detected/</link>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Thu, 11 Jun 2020 11:47:15 +0000</pubDate>
				<category><![CDATA[Andrew’s Blog]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1431</guid>

					<description><![CDATA[Today I published version 2.0 of Double Dry/Wet. There’s an announcement post here. The part of this update that I am excited about is the addition of CV control, and you can read more about it there, or try it yourself. But the main purpose of this update, and the reason I had to rewrite [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Today I published version 2.0 of <a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">Double Dry/Wet</a>. There’s an announcement post <a href="https://andrewrussell.net/2020/06/double-drywet-update/">here</a>.</p>
<p>The part of this update that I am excited about is the addition of CV control, and you can read more about it <a href="https://andrewrussell.net/2020/06/double-drywet-update/">there</a>, or <a href="https://www.reasonstudios.com/shop/rack-extension/double-drywet/">try it yourself</a>.</p>
<p>But the main purpose of this update, and the reason I had to rewrite (!) all of the audio code, was adding delay compensation support…</p>
<p><img decoding="async" loading="lazy" class="aligncenter wp-image-1435 size-full" src="https://andrewrussell.net/content/2020/06/Delay-Comp-Section-Off.png" width="104" height="136" /></p>
<p>A device like Double Dry/Wet needs to handle delay compensation because it is a device <em>explicitly</em> about forming audio loopbacks. Devices in Reason evaluate their inputs and outputs in batches, every 64 samples. If you output audio in one batch, and that signal <em>loops back</em> to the same device, you will not receive the result until the next batch.</p>
<p>This adds 64 samples of latency. If you mix together the output (send) and input (return) signal without accounting for this, then you end up with a comb filter. Normal comb filters are made this way: by combining a signal with a delayed copy of itself.</p>
<p>If the signals are only partly correlated, such as with a heavy effects in-between (the normal use case, here), you only get a partial comb filter. But either way this “bonus” comb filter is not what you want.</p>
<p>The solution is really simple: add a matching delay to the dry (output) signal at the mixing stage. Double Dry/Wet makes it easy. Just hit the “Delay Compensation” button for the channel that has a loopback, and your problems are solved!</p>
<p><img decoding="async" loading="lazy" class="aligncenter wp-image-1436 size-full" src="https://andrewrussell.net/content/2020/06/Delay-Comp-Section.png" width="104" height="136" /></p>
<p>Well… sort of.</p>
<p>First of all, a designed use-case of Double Dry/Wet is as a serial effect mixer. This means you can loop through Double Dry/Wet <em>twice</em>. So there’s a second stage to the delay compensation, in case you need an additional 64-samples of compensation.</p>
<p>Double Dry/Wet does all of the maths required to make sure that all of these signals line up internally, for any setting you choose. It also reports any introduced delay to Reason so <em>its</em> delay compensation works properly.</p>
<p>This solves the common use cases. And, if introducing any delay is unacceptable, there’s a new page in the <a href="https://andrewrussell.net/content/2020/06/Double-Dry-Wet.pdf">user manual</a> showing how to connect up a pair of Double Dry/Wet devices in a splitter/merger pattern to achieve the same effect without introducing any delays.</p>
<p>…</p>
<p>But there’s still a problem. You see, Reason’s own delay compensation is quite limited. It can be summed up as follows: delay compensation only happens at the mixer, on a per-channel basis. There is no delay compensation within the rack itself.</p>
<p>This means that if you have any parallel signals, unless they have exactly the same signal path delay, they will arrive out-of-sync to Double Dry/Wet.</p>
<p>It also means that some signal path delay can get “lost”, as far as Reason’s mixer is concerned. If there is a parallel signal, it only ever reads one of the parallel paths – seemingly the first available path in rack-device-position order.</p>
<p><img decoding="async" loading="lazy" class="aligncenter size-full wp-image-1434" src="https://andrewrussell.net/content/2020/06/NSRD.png" alt="" width="167" height="69" /></p>
<p>When this occurs, the dreaded “<strong>Non-Standard Routing Detected</strong>” warning light comes on. It’s somewhat well-hidden in Reason. You’ll find it on the back of a mix channel device with its programmer expanded. (Hot tip: you can manually correct the delay by adding an offset here.)</p>
<p>As far as Double Dry/Wet is concerned, there’s no reasonable way to deal with these up-stream delays. Rack Extensions are sandboxed such that they cannot “see” the rest of the rack, or read the delay of incoming connections.</p>
<p>The only real solution to this would be to have the user to manually enter the delays. This is awful. First of all, it’s wrong to ask the user for information that Reason already <em>knows</em>. Second: it would add massive complication to a UI that is supposed to be simple and easy-to-use. Third: the delay values would have to change whenever the sample rate changes or up-stream devices change. And fourth: I’d already rewritten Double Dry/Wet when I figured all of this out, and I wasn’t about to do it again!</p>
<p>At first I was very cross about this. I’ve solved a very similar <a href="https://andrewrussell.net/2016/06/how-2-5d-sorting-works-in-river-city-ransom-underground/">graph-loop-breaking problem</a> like this for a game before. Why couldn’t Reason? (The reason? Probably because it’s a hard problem, has performance implications, and sometimes you have to arbitrarily choose the “least bad” graph and hope for the best.)</p>
<p>But then, I took a shower, and I came to see this problem as an opportunity. There’s sadly no way to solve this within the confines of Double Dry/Wet. It will require a separate device. And I have figured out a design for a device that <em>can</em> solve this problem (and, importantly, would remain useful even if Reason also eventually fixes it).</p>
<p>(Just so I don’t <a href="https://en.wikipedia.org/wiki/Osborne_effect">Osbourne</a> myself: it won’t be a replacement for Double Dry/Wet, it will be a stand-alone device. Although it will work really well in combination with Double Dry/Wet!)</p>
<p>So, look forward to that one. I’m excited to be working on it. In the meantime: <a href="https://www.reasonstudios.com/shop/browse/?developer=Andrew%20Russell">buy my products</a>! Double Dry/Wet is still an incredibly useful mixing tool, and I hear the CV control on the updated version is particularly awesome <img src="https://s.w.org/images/core/emoji/14.0.0/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Making Rack Extensions for Reason</title>
		<link>https://andrewrussell.net/2020/04/making-rack-extensions-for-reason/</link>
					<comments>https://andrewrussell.net/2020/04/making-rack-extensions-for-reason/#comments</comments>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Mon, 27 Apr 2020 14:42:50 +0000</pubDate>
				<category><![CDATA[Andrew’s Blog]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1423</guid>

					<description><![CDATA[Hello again, friends! It has been a long time. If you want to skip the article, here’s the link to my new software, and I’ve got more currently in the works. As some of you may know from my occasional blather on Twitter, I have been making a transition away from the game development industry. [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>Hello again, friends! It has been a long time. If you want to skip the article, <a href="https://andrewrussell.net/rack-extensions/">here’s the link to my new software</a>, and I’ve got more currently in the works.</p>
<hr />
<p>As some of you may know from my occasional <a href="https://twitter.com/_AndrewRussell">blather on Twitter</a>, I have been making a transition away from the game development industry. The long-story-short is as follows: making indie games at the moment is financial suicide.</p>
<p>To <a href="https://twitter.com/GreyAlien/status/1227557601786912769">quote Jake Birkett</a> (Gray Alien Games): “In 2013 median indie games made approx. $110K and top 25% made $590K.” So far, so good. He continues: “In 2019 median indie games made $1400, and everything below that basically $0. Top 25% made $12K, which is obviously not sustainable. You have to be in the top 5% of indie games these days to make $413K”.</p>
<p>And <a href="https://twitter.com/RaveofRavendale/status/1171427502037725184">here’s Mike Rose</a> (No More Robots) saying much the same thing. And <a href="https://galyonk.in/steam-in-2017-129c0e6be260">here’s Sergey Galyonkin</a> (Steam Spy) from two years ago, with the very salient point: around 30 games are released <em>per day</em> on Steam. Good luck getting noticed in that noise. There are too many games.</p>
<p>It was around two years ago that I started making my (surprisingly long) transition away from games. It was also at that time I started my first of many attempts at this article. I’d just finished work on <a href="https://store.steampowered.com/app/422810/River_City_Ransom_Underground/">River City Ransom: Underground</a>, including spending a year in post-release support work: it was a slog, and financially it did “ok-ish”.</p>
<p><img decoding="async" loading="lazy" class="alignnone wp-image-1424 size-large" src="https://andrewrussell.net/content/2020/04/ss_54d17c46d6c799745a55320cde2f366a5ef73580.1920x1080-853x480.jpg" alt="River City Ransom: Underground" width="853" height="480" srcset="https://andrewrussell.net/content/2020/04/ss_54d17c46d6c799745a55320cde2f366a5ef73580.1920x1080-853x480.jpg 853w, https://andrewrussell.net/content/2020/04/ss_54d17c46d6c799745a55320cde2f366a5ef73580.1920x1080-256x144.jpg 256w, https://andrewrussell.net/content/2020/04/ss_54d17c46d6c799745a55320cde2f366a5ef73580.1920x1080-480x270.jpg 480w, https://andrewrussell.net/content/2020/04/ss_54d17c46d6c799745a55320cde2f366a5ef73580.1920x1080-768x432.jpg 768w, https://andrewrussell.net/content/2020/04/ss_54d17c46d6c799745a55320cde2f366a5ef73580.1920x1080.jpg 1280w" sizes="(max-width: 853px) 100vw, 853px" /></p>
<p>After River City, I tried a few other projects, some game-related and some not, mostly with RCRU Producer <a href="https://twitter.com/danielcrenna">Daniel Crenna</a>. (If RCRU was a technical slog for me, it was an everything-slog for Daniel, for which he deserves a lot of credit.) Unfortunately none of those projects really took off.</p>
<p>One of my terrible secrets from working on RCRU is that, over the course of development, I stopped playing video games. Since then I’ve <em>tried</em>. Steam helpfully tracks play time so I can estimate that, in the last two years, I’ve spent around 30 hours gaming. And those games were… fine.</p>
<p>Original versions of this article had sections dedicated to my disdain for modern games, from exploitative monetisation, to shonky asset-flips, to a demanding community. All true, of course, but all of it a self-unaware digression from the fact that I have personally lost my passion for games.</p>
<p>Losing my love of gaming and game programming has been confusing and a little sad. It’s something I have had with me since I was a child. But accepting it has also been incredibly freeing. It opens me up to pursuing something that I have also loved since childhood: Music.</p>
<p>To that end, I have started making plugins (“Rack Extensions”) for <a href="https://en.wikipedia.org/wiki/Reason_(software)">Reason</a>, an excellent and <em>fun</em> DAW that I have been using since version 1.0. Reason is notable for its joyful virtual rack user-interface metaphor.</p>
<p><img decoding="async" loading="lazy" class="alignnone size-large wp-image-1425" src="https://andrewrussell.net/content/2020/04/reason11-screenshot-853x523.png" alt="Reason 11 Screenshot" width="853" height="523" srcset="https://andrewrussell.net/content/2020/04/reason11-screenshot-853x523.png 853w, https://andrewrussell.net/content/2020/04/reason11-screenshot-256x157.png 256w, https://andrewrussell.net/content/2020/04/reason11-screenshot-480x294.png 480w, https://andrewrussell.net/content/2020/04/reason11-screenshot-768x471.png 768w" sizes="(max-width: 853px) 100vw, 853px" /></p>
<p>Making music software, Rack Extensions in particular, is an excellent match for my skill set. I have always been, at heart, an engine and tool programmer: I love writing tight, high-performance code (of the kind critical for real-time audio). I love making things that other people can use to have fun and create. And there’s something special and game-like about making user interfaces that aren’t <em>just</em> a collection of parameters.</p>
<p>I’m also a somewhat-competent musician. This is something that I am actively working on improving, so stay tuned for that.</p>
<p>In the background I have been working on <a href="https://andrewrussell.net/rack-extensions/">making Rack Extensions</a>. So far I’ve quietly released three onto the Reason Studios Shop – here is the belated fanfare – <a href="https://www.reasonstudios.com/shop/browse/?developer=Andrew%20Russell">You can buy them right now!</a></p>
<p><a href="https://andrewrussell.net/rack-extensions/"><img decoding="async" loading="lazy" class="alignnone size-full wp-image-1426" src="https://andrewrussell.net/content/2020/04/Rack-Extension-Thumbnails.png" alt="Rack Extensions" width="748" height="228" srcset="https://andrewrussell.net/content/2020/04/Rack-Extension-Thumbnails.png 748w, https://andrewrussell.net/content/2020/04/Rack-Extension-Thumbnails-256x78.png 256w, https://andrewrussell.net/content/2020/04/Rack-Extension-Thumbnails-480x146.png 480w" sizes="(max-width: 748px) 100vw, 748px" /></a></p>
<p>I admit that these are fairly simple devices. I wanted to start small. I have several other devices in development that start to dial up the sophistication. And, of course, all of these devices have been lavished with the care and attention that I like to be known for: high quality, fast, robust code, and carefully and cleverly designed user interfaces.</p>
<p>If you’d like to keep track of new devices as I release them, subscribe to my <a href="https://andrewrussell.net/feed/">RSS Feed</a>, or <a href="https://twitter.com/_AndrewRussell/">follow me on Twitter</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://andrewrussell.net/2020/04/making-rack-extensions-for-reason/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>GameDev Coaching and FNA Template</title>
		<link>https://andrewrussell.net/2017/11/gamedev-coaching-and-fna-template/</link>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Sat, 11 Nov 2017 02:36:56 +0000</pubDate>
				<category><![CDATA[Andrew’s Blog]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1351</guid>

					<description><![CDATA[A couple of quick announcements. First of all, I have a second YouTube channel where I do coding things. So far there is a series called &#8220;GameDev Coaching&#8221; where I sit down with Daniel Crenna (producer and fellow programmer on River City Ransom: Underground). Daniel asked me to show him how to do the kind [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>A couple of quick announcements. First of all, I have a second YouTube channel where I do <a href="https://www.youtube.com/channel/UCyJJzPhTpEm84VTn4b5hHGw">coding things</a>. So far there is a series called &#8220;<a href="https://www.youtube.com/playlist?list=PLEhl4Cw9Zvp7najoHJ8ywrRehVcj2frmX">GameDev Coaching</a>&#8221; where I sit down with Daniel Crenna (producer and fellow programmer on <a href="http://store.steampowered.com/app/422810/River_City_Ransom_Underground/">River City Ransom: Underground</a>).</p>
<p><iframe loading="lazy" width="500" height="281" src="https://www.youtube.com/embed/Q5uv-lGROG8?feature=oembed" frameborder="0" gesture="media" allowfullscreen></iframe></p>
<p>Daniel asked me to show him how to do the kind of game-engine programming that I did on RCRU, and has been kind enough to allow those sessions to be shared on YouTube so other people can also benefit from them.</p>
<p>The second announcement is that I have my first open source project up on GitHub: <a href="https://github.com/AndrewRussellNet/FNA-Template">FNA Template</a>.</p>
<p>It&#8217;s a simple, cross-platform template for making <a href="http://fna-xna.github.io/">FNA</a> games (FNA is an excellent XNA reimplementation). It is the same codebase that we&#8217;re using in the GameDev Coaching series, if you want to follow along.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>RCRU:U #16 &#8211; Combat AI (Series Finale)</title>
		<link>https://andrewrussell.net/2017/06/rcruu-16-combat-ai-series-finale/</link>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Sat, 10 Jun 2017 13:31:05 +0000</pubDate>
				<category><![CDATA[River City Ransom]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1323</guid>

					<description><![CDATA[In this final episode of River City Ransom: Underground: Underground, I explain how the combat AI works out what areas are in danger of being hit, and how it lines up its attacks, as well as one last look at the move test tool. Get River City Ransom: Underground now from Steam or Humble.]]></description>
										<content:encoded><![CDATA[<div class="wide"><p class="bigLink"><a href="https://andrewrussell.net/2017/06/rcruu-16-combat-ai-series-finale/#Embed-1">Watch Video</a></p></div>
<p>In this final episode of River City Ransom: Underground: Underground, I explain how the combat AI works out what areas are in danger of being hit, and how it lines up its attacks, as well as one last look at the move test tool.</p>
<p>Get <em>River City Ransom: Underground</em> now from <a href="http://store.steampowered.com/app/422810/River_City_Ransom_Underground/">Steam</a> or <a href="https://www.humblebundle.com/store/river-city-ransom-underground">Humble</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>More is Less</title>
		<link>https://andrewrussell.net/2017/03/more-is-less/</link>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Tue, 14 Mar 2017 08:10:41 +0000</pubDate>
				<category><![CDATA[River City Ransom]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1313</guid>

					<description><![CDATA[The launch of River City Ransom: Underground (Now available on Steam for $19.99!) went pretty well, all things considered. (This isn’t a full post-mortem, but could perhaps be considered a narrow sliver of one.) We had a few nasty bugs crop up on day 1, and we fixed the worst of them right away. It’s [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>The launch of <em>River City Ransom: Underground</em> (<a href="http://store.steampowered.com/app/422810">Now available on Steam for $19.99!</a>) went pretty well, all things considered. (This isn’t a full post-mortem, but could perhaps be considered a narrow sliver of one.)</p>
<p>We had a few nasty bugs crop up on day 1, and we fixed the worst of them right away. It’s now been two weeks, and we’ve just rolled out the much larger fix for the infamous “<strong>multiplayer save bug</strong>”.</p>
<p>If you follow me (<a href="https://twitter.com/_AndrewRussell">@_AndrewRussell</a>) or the game (<a href="https://twitter.com/rivercityransom">@rivercityransom</a>) on Twitter, you’ll <a href="https://twitter.com/_AndrewRussell/status/840572846690656256">know</a> that the change set for this clocked in at around 3.5 thousand lines of code. This represents about 1% of our total source code (and close to 2 weeks of my time). It really is a massive change.</p>
<p><strong>This post is to explain how such a difficult-to-fix bug ended up being shipped in the first place.</strong></p>
<p>First we need to start with a small piece of technical information: In a networked game, the amount of data we can add to the game state with a joining player is <em>tiny</em>. Maybe a few hundred bytes at most. When I wrote that part of the netcode, I inserted a warning when the size exceeded 64 bytes.</p>
<p>(Details: Our game is P2P and supports drop-in-drop-out at any time, including support for host-migration. This means that player join data can be buffered, replayed, and re-transmitted almost arbitrarily. This starts to become an issue if multiple join and leave events happen in quick succession, particularly across a host-migration.)</p>
<p>The reason this “player-join-data” feature was added to the netcode was specifically so we could allow players to bring their list of unlocked characters into network games, play as them, upgrade their stats, and unlock new characters. The further intention was that players could keep those changes across different network games, as well as carry them into single player.</p>
<p>Unfortunately, the amount of data required by the unlock list was significantly more than was safe to transmit when joining (kilobytes). And, even with substantial data packing work, impossible to fit inside the 64-byte warning limit I had set much earlier in development.</p>
<p>(Additionally, there is a limit on the total size of the “live” game state. And having four full unlock lists in game would have exceeded it.)</p>
<p>This left two other options: Simply use the unlock list of the host (the same as couch play); or allow the joining player to bring <em>one</em> of their characters into the game with them. For the vast majority of development, we went with the first option – as it required zero extra implementation effort. But we did keep the second option in the back of our minds, to perhaps implement when development time became available.</p>
<p>Then, about 4 days before we shipped, Daniel decided that this feature – in the form of the second option – was important enough for us to add at the last minute. (Meanwhile I was coming down with an extremely bad cold, made worse due to the stress and crunch time of launch.)</p>
<p>This was obviously too close to launch to do sufficient testing, or even to properly consider the ramifications of this change. This was further exacerbated by the fact that the change was purposely left out of patch notes (there were 3 more beta releases after the feature was added), explicitly because there were some unfixed bugs in the initial implementation. I am hazy as to whether the bugs were actually fixed before launch, but suffice to say the change never ended up being included in any beta patch notes.</p>
<p>Which brings me to the central thesis of this post: <strong>More is Less</strong>. By adding this feature, the menu flow when joining an online game was changed from this:</p>
<p><div id="attachment_1314" class="wp-caption aligncenter" style="width: 480px"><a href="https://andrewrussell.net/content/2017/03/Join-Game-Old.png"><img decoding="async" loading="lazy" class="wp-image-1314 size-medium" src="https://andrewrussell.net/content/2017/03/Join-Game-Old-480x72.png" alt="Join Game Old" width="480" height="72" srcset="https://andrewrussell.net/content/2017/03/Join-Game-Old-480x72.png 480w, https://andrewrussell.net/content/2017/03/Join-Game-Old-256x38.png 256w, https://andrewrussell.net/content/2017/03/Join-Game-Old-768x115.png 768w, https://andrewrussell.net/content/2017/03/Join-Game-Old-853x127.png 853w" sizes="(max-width: 480px) 100vw, 480px" /></a><p class="wp-caption-text">[Select game type] → [Select game to join]</p></div>To this:</p>
<p><div id="attachment_1315" class="wp-caption aligncenter" style="width: 480px"><a href="https://andrewrussell.net/content/2017/03/Join-Game-New.png"><img decoding="async" loading="lazy" class="wp-image-1315 size-medium" src="https://andrewrussell.net/content/2017/03/Join-Game-New-480x72.png" alt="Join Game New" width="480" height="72" srcset="https://andrewrussell.net/content/2017/03/Join-Game-New-480x72.png 480w, https://andrewrussell.net/content/2017/03/Join-Game-New-256x38.png 256w, https://andrewrussell.net/content/2017/03/Join-Game-New-768x115.png 768w, https://andrewrussell.net/content/2017/03/Join-Game-New-853x127.png 853w" sizes="(max-width: 480px) 100vw, 480px" /></a><p class="wp-caption-text">[Select game type] → [Select a save] → [Select a character] → [Select game to join]</p></div>Now players were selecting a save file when entering an online game. So their expectation was that any progress they made in the online game would be <em>saved</em> to that save file.</p>
<p>So, despite the fact we had <em>added</em> a feature to the game (the ability to play online as a character from your save), it was rightly perceived by players as a critical data-loss bug!</p>
<p>During the beta, where we did not present the save screen, no one batted an eye at the fact that we didn’t save characters in online play. But, after launch, with hundreds of players encountering the new menu flow, it immediately became our number one user complaint. (Even more than any of our <em>actual</em> data-loss bugs.)</p>
<p>So I have spent the last two weeks doing little else besides rewriting the game’s unlock system: Each character can now have their own unlock list, local multiplayer characters will share a list, that <em>entire</em> list comes with you into an online multiplayer game, and it is <em>always</em> saved back into the save file that it came from, even online.</p>
<p>Most of the work involved fixing the many systems that were written with the assumption that there was only a single game-wide unlock list. But there was also a great deal of work packing the data, so that the unlock list could be sent across the network at a reasonable size (238 bytes with all unlocks and no inventory). Plus I’ve fixed all of the bugs around unlocks and save games that I could find in the process.</p>
<p><em>River City Ransom: Underground</em> just got significantly better. Especially for multiplayer. <a href="http://store.steampowered.com/app/422810">Now would be a great time to go and play it!</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>RCRU:U #15: Navigation &#8211; Local Obstacle Avoidance</title>
		<link>https://andrewrussell.net/2016/12/rcruu-15-navigation-local-obstacle-avoidance/</link>
		
		<dc:creator><![CDATA[Andrew Russell]]></dc:creator>
		<pubDate>Sat, 10 Dec 2016 15:38:38 +0000</pubDate>
				<category><![CDATA[River City Ransom]]></category>
		<guid isPermaLink="false">http://andrewrussell.net/?p=1308</guid>

					<description><![CDATA[In this video I talk about how we handle local obstacle avoidance &#8211; that is, we make sure the AI doesn&#8217;t get stuck on crates and other dynamic objects. Some minor corrections: A typical, modern x86 CPU L1 Cache is 64kB. But that is split into 32kB for data and 32kB for instructions. The local [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class="wide"><p class="bigLink"><a href="https://andrewrussell.net/2016/12/rcruu-15-navigation-local-obstacle-avoidance/#Embed-1">Watch Video</a></p></div>
<p>In this video I talk about how we handle local obstacle avoidance &#8211; that is, we make sure the AI doesn&#8217;t get stuck on crates and other dynamic objects.</p>
<p>Some minor corrections:</p>
<ul>
<li>A typical, modern x86 CPU L1 Cache is 64kB. But that is split into 32kB for data and 32kB for instructions.</li>
<li>The local dynamic heightmap used by LOA is actually dynamically sized to be as small as possible. The 64&#215;32 one is only used for debug display.</li>
<li>This is the last in a 5-episode recording session, but episodes 3 and 4 (that is: #13 and #14) got re-recorded.</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
