<?xml version="1.0" encoding="utf-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>space &amp; times</title><link>https://spaceandtim.es</link><description>francis tseng&apos;s blog</description><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 27: Good progress</title><link>projects/fugue/27</link><description><![CDATA[I’m still working on Fugue. Funnily I had a draft update post exactly a year ago that I never finished, but this post is almost 2 years aft…]]></description><category>projects/fugue</category><pubDate>Wed, 27 Aug 2025 17:54:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>I’m still working on <em>Fugue</em>. Funnily I had a draft update post exactly a year ago that I never finished, but this post is almost 2 years after the last one. A lot of preparatory progress has been made: characters and major plot points are starting to come together, and the whole production tooling/process is much further along.</p>
<h2>Verses: Rust to C#</h2>
<p>I’m trying to keep the core game logic outside of Unity/C# and move as much as possible into Rust, a language I’m more comfortable with. So I rewrote the Verses/Garland system, which is the scripting system (as in dialogue scripts) that manages most of the game state, into Rust and generated an FFI for it using <a href="https://github.com/mozilla/uniffi-rs"><code>uniffi</code></a> (and its <a href="https://github.com/NordSecurity/uniffi-bindgen-cs">C# bindings generator</a>). It’s just a lot easier for me to maintain and make changes. A few notes:</p>
<ul>
<li>I am a <em>bit</em> concerned about possible issues building Rust code for console platforms, but I’ll worry about that later.</li>
<li>There’s a bit of plumbing required to wire up the library to Unity, but it’s not too bad.</li>
<li>One minor annoyance is that Unity requires a full restart to load any changes to the library, though as the library stabilizes this should be less of a problem.</li>
<li>Debugging is more complicated, and as far as I know there’s no way to hook into Unity’s logging system, so I log to a file instead.</li>
<li>The generated code is for C# 12, while Unity supports only C# 9, so some unsightly post-processing is required to make the generated bindings Unity-compatible, but again it’s not too bad.</li>
<li>There’s additional overhead calling over an FFI boundary, but I expect it to be negligible here.</li>
</ul>
<p>So far this approach has been fine in terms of trade-offs. There’s also something nice about having a strict boundary between the “game environment” code and logic and a much more strongly enforced “single source of truth” in terms of the game state. But more complications could easily come up as I get more into writing the game’s scripts, so we’ll see.</p>
<h2>Stagecraft: Blender to Unity</h2>
<p>Similar to the Rust/C# divide I’m also trying to keep as much scene-building outside of Unity as possible. I find Blender a lot nicer to work with and it’s of course much more powerful for modeling, texturing, and so on. But it doesn’t have analogues to Unity’s components/<code>MonoBehaviour</code>s, so there’s no clear way to represent the dynamic behavior necessary for a game. And many of Blender’s powerful features, like procedural textures, aren’t directly exportable to Unity.</p>
<p>To solve these issues I wrote a custom Blender add-on, <code>Stagecraft</code>. Where possible this add-on uses existing functionality, e.g. Blender’s baking system can be used for procedural textures. But what about game component behaviors? In my case I have a relatively small set of fixed behaviors that just require their data/configuration to be specified. For example, one behavior I have is <code>ItemCarrier</code>, which defines if the object has items the player can pick up. This only requires that the item IDs and quantities are specified, which are easy to attach to objects in Blender as custom properties. Unity built-ins like colliders can also be configured.</p>
<p><code>Stagecraft</code> then exports the scene as its individual models (as GLTFs) and then a separate scene hierarchy that has all this additional data like <code>ItemCarrier</code> items. In Unity I have a custom importer which imports this scene hierarchy and creates all the appropriate game objects with the correct <code>MonoBehaviour</code>s attached. It creates the correct lights and bakes the lightmap as well. The goal is that the scene is entirely specified in Blender and no edits should be made to the scene in Unity. We’ll see where the limits to this approach are, but so far it seems to work well.</p>
<p><figure>
            <a href="/assets/uploads/fugue/blender-stagecraft.webp" title="">
            <img src="/assets/uploads/fugue/blender-stagecraft.webp" title="">
            </a>
            <figcaption></figcaption>
            </figure></p>
<p>There is one major improvement I’m figuring out, which is handling animation state machines and blend trees. I’d like to be able to bring in an asset with some animations (actions) and be able to define the equivalent of a Unity Animator from within Blender, with conditions and triggers that are handled by Verses/Garland.</p>
<h2>Loom</h2>
<p>I also have a new version of my world-building and content authoring tool, <code>loom</code>, which makes it easier to edit scripts, write quest outlines, and organize characters, factions, and locations.</p>
<p><figure>
            <a href="/assets/uploads/fugue/loom-new.webp" title="">
            <img src="/assets/uploads/fugue/loom-new.webp" title="">
            </a>
            <figcaption></figcaption>
            </figure></p>
<h2>Next steps</h2>
<p>I’m still working on mechanics, but I need to have a playable prototype before I can really move further, hence the focus on getting the content production system further along. The next big tasks for this workflow are putting characters in scenes and having complex animation state machines, and then thoroughly testing the Verses/Garland script integrations in Unity. Hopefully soon I’ll have the whole skeleton of the game engine and production system finished and it’ll be easier to iterate on it and polish it. The hardest part is getting the foundation in place.</p>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 26: More tool building and 3d nightmares.</title><link>projects/fugue/26</link><description><![CDATA[It’s been a while since the last update; I was away at a language immersion program and then very busy with our move to Paris but managed t…]]></description><category>projects/fugue</category><pubDate>Sat, 20 Jan 2024 17:37:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>It’s been a while since the last update; I was away at a language immersion program and then very busy with our move to Paris but managed to find some time here and there to continue work on the <em>Fugue</em>. Though it’s probably more accurate to say the “pre-work” on the game, as I’m still deep in setting up all the tooling and infrastructure that will hopefully make the actual game development feel more like building with Legos.</p>
<p>The biggest development is that I re-wrote the GUI tools from <code>tauri</code>/<code>typescript</code> to <code>egui</code>/<code>rust</code>. Having a web-based UI is just too heavy and if I’m going to be using something frequently I’d want it to be quick and snappy. That in itself was challenging because the UI tooling is so much better for the web (makes sense, given that it’s the dominant type of UI these days) and the Rust ecosystem in general is still in its infancy. But ultimately it was worth it.</p>
<p>Two completely new tools are <code>crane</code> and <code>depot</code>. On the point of wanting to avoid clunky UIs, Unity is so sluggish on Linux (not sure if the same is true for Windows) and just adds so much mental overhead to assembling scenes within it. <code>crane</code> is instead a very simple scene editor with modal controls (à la <code>vi</code>/<code>vim</code>; I’m a zealot) which is capable of parsing and exporting Unity scenes. So the bulk of scene editing/creation can happen in there, with some parts (<code>MonoBehaviour</code> scripts, etc) that might still need to be done from within Unity, but are far less common tasks.</p>
<h2>Depot &amp; 3d overload</h2>
<p><code>depot</code> manages all the non-character 3d assets, tracking licensing and attribution where needed (e.g. <code>CC-BY</code> licensed assets), and common 3d processing tasks built-in. Primarily this is generating model variations with different textures and mesh simplification (way more on this below). It’ll eventually integrated with <code>crane</code> so <code>crane</code> can directly pull models from <code>depot</code> to add to a scene.</p>
<p>As I alluded to a long time ago, the 3d model aspect is probably the most difficult part of the technical aspect of the game’s development (writing, character development, etc are harder–and more fun–but leaving those aside for now) and I’ve decided the best approach is to set aside some budget to purchase pre-existing assets and hand-create only the simplest things. The amount of time saved will be well worth the cost.</p>
<p>The downside of using pre-made assets, however, is a lot of variability. Meshes can vary tremendously in poly counts, textures, etc; not to mention model formats (<code>obj</code>, <code>fbx</code>, <code>gltf</code>/<code>glb</code>, etc) which is a massive challenge itself. So I basically need a processing pipeline that can take a pre-made asset in any format (or at least the major ones) and turn it into something optimized and visually consistent with everything else with as little input from me as possible. Buying pre-made assets is moot if I have to spend just as much time adjusting the model to fit my particular needs.</p>
<p>This led me down a dizzying rabbit hole to the world of 3d software-stuff (? not sure what to call it) and so far I’ve come away with the following learnings:</p>
<ul>
<li>There are too many 3d formats! And no reliable means of converting between all of them, or even just the major formats. There’s <a href="https://github.com/assimp/assimp"><code>assimp</code></a> which seems ill-maintained, and you can use Blender too but it’s frankly heavy for the job. The best tool I’ve found so far is <a href="github.com/mikedh/trimesh"><code>trimesh</code></a> but afaik they don’t provide a command line tool or anything, so you need to have Python setup to use it. It’d be so nice to have something like <code>ffmpeg</code> but for 3d models. Instead I’ve found that specific conversion software, like <a href="https://github.com/CesiumGS/obj2gltf"><code>obj2gltf</code></a> or <a href="https://github.com/facebookincubator/FBX2glTF"><code>fbx2gltf</code></a> are the most reliable.</li>
<li>Formats aside, there’s so much variability already in meshes (welded vs unwelded, tris vs quads, messed up normals, bad UV mappings, water-tightness, etc) and thus so many opportunities for malformed meshes that will just gunk up any automated processing you have set up. Again, <code>trimesh</code> has so far seemed good at standardizing models to some degree such that they’ll then work for other mesh simplification programs.</li>
<li>In terms of pre-made programs and libraries you often see just two extremes: extraordinarily expensive but good &amp; robust (I’m guessing, I can’t afford to try them) geared towards big money-making studios (where licenses are generally in the tens of thousands per year) and 5 to 10 year old code for a random SIGGRAPH paper that seems so promising but isn’t written for general use and/or is an absolute nightmare to compile. There are things in between but they’re relatively rare. In contrast, for data science, for example, there is a massive wealth of libraries/software of different scales out there to use.</li>
<li>Related to the previous point, I’ve found that where native Rust libraries exist for some of these they’re often unexpectedly lopsided. For example, the <code>tobj</code> crate can load <code>.obj</code>s but it can’t save them. I don’t know enough about the format to say more–I’m sure there’s a good reason, but it just seems strange to me.</li>
<li>The ecosystem is still very Windows-focused, given that Windows is still the dominant computer gaming platform. <code>wine</code> is a godsend here, at least for running <code>.exe</code>s; so far I haven’t had much luck compiling Windows C++ programs (using <code>msbuild</code> or <code>msvc</code> or <code>clang</code> or whatever).</li>
</ul>
<p><figure>
            <a href="/assets/uploads/fugue/burger-high-poly.png" title="High-poly burger (20,276 faces)">
            <img src="/assets/uploads/fugue/burger-high-poly.png" title="High-poly burger (20,276 faces)">
            </a>
            <figcaption>testing</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/burger-low-poly.png" title="">
            <img src="/assets/uploads/fugue/burger-low-poly.png" title="">
            </a>
            <figcaption>Low-poly burger (200 faces; ~1%)</figcaption>
            </figure>
<h2>Reducing polys</h2>
<p>There are a lot of different 3d model processing tasks but fortunately for me the only one I’m concerned with is “mesh simplification”, i.e. taking a high-poly mesh and turning it into a low-poly one that still resembles the original. Generally you will bake some of the high-poly mesh information as textures (e.g. a normal map) to help with this.</p>
<p>There’s a related task of creating an “imposter”, where we don’t modify the mesh itself but instead create a simple proxy polygon, e.g. an octahedron. You then pre-render the object from various perspectives and those are then projected onto the polygon. The idea here is if an object is going to be static and only viewed from a few angles, we don’t need to store/render all the geometry as we’re essentially looking at a 2d image.</p>
<p>Imposters are probably the right approach for set-piece elements and the like. They’re much easier for me conceptually and because of their simplicity are probably going to be more robust than actually mutating the mesh. There are plenty of Unity plugins that do this; I haven’t tried them yet but they’re all well-reviewed.</p>
<p>But for anything more complicated, especially things that need to move, imposters won’t be enough. We have to actually change the geometry to reduce the poly count.</p>
<p>I’ve seen a few different terms for this task; I’m not sure what the distinctions are between them, if any: simplification, decimation, remeshing, retopology, reduction, LOD generation, and probably more.</p>
<p>Reflecting the pattern above there are a few “pro” options for this task, namely <a href="https://simplygon.com/">Simplygon</a> which seems to be the industry standard (and if I’m not mistaken is integrated into the Unreal Engine’s mesh simplification routines), evident in its whopping cost of $35,000 per year. They do have a free version but it’s very limited. There’s also <a href="https://instalod.com">InstaLOD</a> which has a more generous free option, but I haven’t been able to download it and I think it excludes the use of the C++ API. When there are free offerings direct API access is usually behind the paywall or, when no free offering exist, behind the more expensive plan. For example, with <a href="https://unity.com/products/pixyz">Pixyz</a> it’s $1,350/year for just the plugin and $2,450/year for the Python API.</p>
<p>So I haven’t tried any of these products but I wonder how much better they are in terms of raw mesh simplification quality. They probably have a bunch of other features important to giant studios like build system integration or support for more esoteric workflows/needs; that might be more of the selling point than how good their mesh simplification algorithm is. I wonder this partly because after looking through the free or cheaper options they mostly use the same approach: some variation of quadric mesh simplification. As I understand this basically involves computing a metric (the quadric metric) for each edge in the mesh, essentially ranking the edges according to how important they are (I’m waving my hands) and then deleting the least important edge. Rinse and repeat until you hit your target face/vert count.</p>
<p>Some examples that I believe use this approach are <a href="https://github.com/songrun/SeamAwareDecimater">SeamAwareDecimater</a>, <a href="https://github.com/sp4cerat/Fast-Quadric-Mesh-Simplification">FastQuadricMeshSimplification</a>, <a href="https://www.meshlab.net/">MeshLab</a>, and <a href="github.com/nanolabo/nanomesh">nanomesh</a>. On my test meshes they all give similar results. It feels like this approach is better suited to preserving as much detail as possible when simplifying, which is great for going from high-poly to mid-poly, but when you start to get to the very low poly ranges (&lt;3000 faces or so) the mesh just starts to degrade, have holes, etc.</p>
<p><a href="https://www.gamedev.net/forums/topic/710951-mesh-simplification-algorithms-with-silhouette-protection/?page=1">This thread</a> discusses some of the other shortcomings of this approach and is where I first encountered the term “silhouette protection”. With the quadric approach you eventually get to the point where you start deleting faces and start to lose essential elements of the model, until it becomes unrecognizable. Silhouette protection is meant to stop the algorithm before it reaches this point; or it may be a totally different simplification approach, I don’t really know.</p>
<p>One approach I thought might work is to take the convex hull of the mesh and iteratively introduce edges, essentially “shrink-wrapping” the hull around the original mesh until you reach the desired number of faces or some minimum error between the mesh and the hull. The downside with this approach is that I don’t think it’d work for meshes that have holes because a convex hull doesn’t take those into account (afaik).</p>
<p>I wasn’t able to find much pre-existing software that does this, just <a href="https://www.cvlibs.net/software/semi_convex_hull/">Semi Convex Hull for Mesh Simplification</a> and <a href="https://github.com/gaschler/bounding-mesh">Boundingmesh</a> which uses “bounding convex decomposition”. I wasn’t able to get them to finish simplifying my heavier test meshes, they ran without terminating. However, I believe this approach is kind of how collider meshes are computed, but looking at <a href="https://assetstore.unity.com/packages/tools/physics/collision-mesh-generator-convex-decomposition-154904">this collider mesh generation plugin</a> it seems like the approach (for at least the VHACD algorithm; <a href="https://assetstore.unity.com/packages/tools/physics/convexify-245029">see also</a> and <a href="https://github.com/Unity-Technologies/VHACD">here</a>) is to break down the mesh into different parts and then build the collider mesh from the convex hulls of those individual parts, thus the mesh is no longer contiguous. But this does get around the hole problem I mentioned, and I guess you could re-join the individual parts though.</p>
<p>So unfortunately no clear resolution yet, but there’s still more to try.</p>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 25: More generic player handling, inventory UI, and more.</title><link>projects/fugue/25</link><description><![CDATA[Hard to believe it’s been less than three weeks since the last update. I’ve managed to finish a lot even though I feel like I haven’t had m…]]></description><category>projects/fugue</category><pubDate>Fri, 02 Jun 2023 13:53:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>Hard to believe it’s been less than three weeks since the last update. I’ve managed to finish a lot even though I feel like I haven’t had much time to work on things (especially with <em>Tears of the Kingdom</em> out now).</p>
<h2>Better character movement</h2>
<p>I mainly was procrastinating because I needed to fix some issues with the AI/<code>NavMeshAgent</code> character movement and I had no idea where to start. <code>NavMeshAgent</code> is Unity’s built-in character pathfinding system, and it’s not bad. I’m using it with root motion (i.e. the animation drives movement rather than direct modification of the character’s world position), which makes working with a bit more complicated.</p>
<p>The problem was that when the character was running they would never be able to turn fast enough to match their computed path. So they would overshoot things and run into walls while making large turns. There is an <code>angularSpeed</code> setting but it didn’t seem to have any effect. I toyed with having root motion drive the rotation too, but it ended up being too complicated; and even so, the direct rotation looks fine.</p>
<p>What I ended up doing was manually controlling the character’s rotation, rather than letting <code>NavMeshAgent</code> do it:</p>
<pre><span class="variable">_agent</span><span class="punctuation delimiter">.</span><span class="variable">updateRotation</span> <span class="operator">=</span> <span class="constant builtin">false</span><span class="punctuation delimiter">;</span>

<span class="comment">&#x2f;&#x2f; ...</span>

<span class="comment">&#x2f;&#x2f; Called in Update</span>
<span class="keyword">private</span> <span class="type builtin">void</span> <span class="function">SyncAnimatorAndAgent</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span> <span class="punctuation bracket">{</span>
    <span class="comment">&#x2f;&#x2f; ...</span>

    <span class="comment">&#x2f;&#x2f; Handle turning ourselves, rather than</span>
    <span class="comment">&#x2f;&#x2f; delegating it to the NavMeshAgent;</span>
    <span class="comment">&#x2f;&#x2f; this allows us to have more control.</span>
    <span class="comment">&#x2f;&#x2f; Turn faster if running.</span>
    <span class="keyword">var</span> <span class="variable">step</span> <span class="operator">=</span> <span class="variable">maxTurnSpeed</span> <span class="operator">*</span> <span class="variable">Time</span><span class="punctuation delimiter">.</span><span class="variable">deltaTime</span> <span class="operator">*</span> <span class="punctuation bracket">(</span><span class="variable">shouldRun</span> <span class="operator">?</span> 2 <span class="operator">:</span> 1<span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    <span class="type">Vector3</span> <span class="variable">direction</span> <span class="operator">=</span> <span class="variable">_agent</span><span class="punctuation delimiter">.</span><span class="variable">steeringTarget</span> <span class="operator">-</span> <span class="variable">transform</span><span class="punctuation delimiter">.</span><span class="variable">position</span><span class="punctuation delimiter">;</span>
    <span class="variable">direction</span><span class="punctuation delimiter">.</span><span class="variable">y</span> <span class="operator">=</span> 0<span class="punctuation delimiter">;</span> <span class="comment">&#x2f;&#x2f; Ignore up&#x2f;down</span>
    <span class="keyword">var</span> <span class="variable">targetRotation</span> <span class="operator">=</span> <span class="variable">Quaternion</span><span class="punctuation delimiter">.</span><span class="function">LookRotation</span><span class="punctuation bracket">(</span><span class="variable">direction</span><span class="punctuation delimiter">,</span> <span class="variable">Vector3</span><span class="punctuation delimiter">.</span><span class="variable">up</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    <span class="variable">transform</span><span class="punctuation delimiter">.</span><span class="variable">rotation</span> <span class="operator">=</span> <span class="variable">Quaternion</span><span class="punctuation delimiter">.</span><span class="function">RotateTowards</span><span class="punctuation bracket">(</span><span class="variable">transform</span><span class="punctuation delimiter">.</span><span class="variable">rotation</span><span class="punctuation delimiter">,</span> <span class="variable">targetRotation</span><span class="punctuation delimiter">,</span> <span class="variable">step</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>

    <span class="comment">&#x2f;&#x2f; ...</span>
<span class="punctuation bracket">}</span>
</pre>
<p>This lets me change the rotation speed based on how fast the character is moving (i.e. running or walking). It also lets me have conditional behaviors based on the magnitude of required rotation. For example, if the character needs to turn 180deg, then I can have them turn <em>before</em> starting to move, which also looks a bit more natural.</p>
<p>There’s definitely a lot more tweaking to be done, but I’m happy with the results for now.</p>
<h2>Changing the player character</h2>
<p>One feature I wanted to have was for the player to swap out what character they’re controlling. Like all JRPGs I want party composition to be an important element of gameplay. This fortunately wasn’t too complicated, in part because of the character generation workflow I set up earlier (always nice when that work pays off!). Because all characters share essentially the same skeleton, I just need to swap to the new character’s skeleton (and model) and update a couple other parameters (how tall they are, etc).</p>
<p>The one tricky bit was rebinding the new skeleton to <a href="https://assetstore.unity.com/packages/tools/animation/look-animator-122249">a plugin</a> I’m using that controls where the character is looking. There’s no built-in way to do this rebinding. Fortunately after digging through the source code I managed to find a solution:</p>
<pre><span class="keyword">public</span> <span class="type builtin">void</span> <span class="function">RefreshLooker</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span> <span class="punctuation bracket">{</span>
    <span class="comment">&#x2f;&#x2f; NOTE this assumes the path is always the same,</span>
    <span class="comment">&#x2f;&#x2f; which it might be due to `clay`</span>
    <span class="variable">_looker</span><span class="punctuation delimiter">.</span><span class="variable">LeadBone</span> <span class="operator">=</span> <span class="variable">transform</span><span class="punctuation delimiter">.</span><span class="function">Find</span><span class="punctuation bracket">(</span><span class="string">&quot;Model&#x2f;Armature&#x2f;Root&#x2f;pelvis&#x2f;spine_01&#x2f;spine_02&#x2f;spine_03&#x2f;neck_01&#x2f;head&quot;</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    <span class="variable">_looker</span><span class="punctuation delimiter">.</span><span class="function">RefreshLookBones</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    <span class="variable">_looker</span><span class="punctuation delimiter">.</span><span class="function">InitializeBaseVariables</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
<span class="punctuation bracket">}</span>
</pre>
<p>I did have to change <code>RefreshLookBones</code> from an <code>internal</code> to a <code>public</code> method though, so it’s not ideal.</p>
<h2>Inventory UI</h2>
<p>The biggest feature is the inventory UI, which is an RE-style spatial inventory system. I like it better than other inventory constraints, like a weight limit, though it can still be tedious to manage (need to find some good C# bin packing libraries to implement an auto-sort).</p>
<p>This was my first time making a substantial UI in Unity, using their <code>UIElements</code> system. It felt very weird to use what are essentially HTML and CSS (UXML and USS, respectively), and it took me some time to figure out how exactly I should structure things. The system needs some React or Solid-like framework to round it out.</p>
<p>My current approach is to avoid the UXML as much as possible and build the UI in C# instead (essentially creating “components” by inheriting <code>VisualElement</code>). Hopefully the UI demands remain simple enough that this remains viable.</p>
<p>The C# approach made it easier to design the inventory UI as a modal interface, i.e. different inputs change the UI’s mode, which makes it easier to ensure that there are less invalid states. The normal mode is just moving the inventory cursor around and entering other modes. For example, pressing the “move” button over an item in normal mode changes the mode to <code>Moving</code>, which then remaps inputs for that particular context (e.g. what was once the “use item” button is now the “place item” button). This feels like the cleanest, most extensible approach, but goodness does UI always take way more code than I anticipate.</p>
<p>I’m not going to include a screenshot of the inventory UI because it looks terrible, but it is passing all its tests!</p>
<h2>Dice System</h2>
<p>I played <a href="https://www.fellowtraveller.games/citizen-sleeper"><em>Citizen Sleeper</em></a> and enjoyed it. The dice system there is great, and makes much more sense for the type of game I’m working on than the ones I mentioned in the <a href="/projects/fugue/24/">last update</a>. I’m definitely going to riff off of it for <em>Fugue</em>’s skill check system.</p>
<h2>Other bits</h2>
<ul>
<li>I also implemented a proper scene manager, which handles changing scenes and loading in the player character. Took longer than I expected, but seems to work well enough.</li>
<li>I changed the <code>verses</code> script deserialization from JSON to YAML. The JSON deserialization code was a mess, and possibly kind of slow? I found <a href="https://github.com/hadashiA/VYaml">a fast YAML library</a> that vastly simplifies the script importer. YAML’s more pleasant to look at too.</li>
</ul>
<h2>Next steps</h2>
<p>Two main things are on my mind:</p>
<p>I want to start implementing the dice/skill check system so I can finally test it. It’s the game’s core mechanic, so I need to make sure it makes sense before running too far ahead.</p>
<p>I want to use the Unity editor as little as possible. It’s kind of janky and just slow for me to work in. I don’t want to learn all of its shortcuts and wait for it to respond. The way I see it there are three primary activities I need the editor for:</p>
<ol>
<li>Compiling C# and running tests</li>
<li>Building scenes</li>
<li>Building/testing the game</li>
</ol>
<p>There may be a way around 1) but I have a feeling it would be very painful to set up, and perhaps not much of an improvement in terms of speeding up the development loop. There’s no way around 3), but it’s a relatively infrequent activity at this stage so I’m not worried about it.</p>
<p>I expect 2) will be where most of my Unity editor time will be after I’ve implemented the game’s core features. It’s unpleasant, especially in contrast to 1) where I’m mostly writing in my comfortable text editor and hopping to the editor only to compile and run tests. I would love to have something equivalent to my text editor but for building Unity scenes.</p>
<p>Fortunately this might actually be possible. Unity’s scenes are really just specialized YAML files, and I’ve already built part of a Rust parser for them in <code>verses</code>. In theory you could set up an external program to edit those YAML files. I’d need to be careful in scoping the tool, however. I don’t want to end up re-implementing a huge part of Unity’s editor.</p>
<p>For version 1 of <code>umarell</code>, which is <a href="https://en.wikipedia.org/wiki/Umarell">what I’d call this tool</a>, I’d probably just want to modify transform information (position, rotation, scale). I’d still have to import objects into the scene in Unity first (which is a relatively infrequent activity), to ensure that they’re properly initialized with all the right properties and what not. Then I’d pop over into <code>umarell</code> and position things.</p>
<p>I imagine the scene building workflow would be something like:</p>
<ol>
<li>Build the static set elements in Blender.</li>
<li>Create a new scene in Unity and drop in all the objects that should be in the scene, and perhaps also attach any scripts/components they need.</li>
<li>Open the scene in <code>umarell</code> and start setting all the objects up.</li>
</ol>
<p>I looked a bit into what the Rust ecosystem for something like is like, and this might be possible with <a href="https://rend3.rs/"><code>rend3</code></a> and <a href="https://github.com/emilk/egui"><code>egui</code></a>. It’s not a high priority at the moment–I need to finish getting all the systems down–but could be a fun project later.</p>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 24: Puttering Along</title><link>projects/fugue/24</link><description><![CDATA[I’ve been slowly chipping away at porting things to Unity, sketching out new game systems, and tweaking the  script syntax.
 UpdatesFor  I’…]]></description><category>projects/fugue</category><pubDate>Fri, 12 May 2023 10:56:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>I’ve been slowly chipping away at porting things to Unity, sketching out new game systems, and tweaking the <code>verses</code> script syntax.</p>
<h2><code>verses</code> Updates</h2>
<p>For <code>verses</code> I’m constantly changing things to try and get the most concise syntax I can, without it becoming too hard to skim.</p>
<p>Two of the biggest changes are:</p>
<ul>
<li>Multiline remarks, which make it easier to write consecutive lines that are said by the same actor.</li>
<li>Allowing conditionals to be inlined into a verse. Previously any conditional behavior had to be defined as a branching action, which would have to connect to a different verse entirely.</li>
</ul>
<p>For the second change, the way it worked before was clunky. Say I want to have a character say something if <code>foo==bar</code> and then return back to the normal dialogue.</p>
<pre>@root
Branch:
  - @next_verse
    If: foo==bar
  - @default_verse

@next_verse
[Character] Foo equals bar!?
Branch:
  - @default_verse

@default_verse
[Character] Continuing the convo...
</pre>
<p>This is a lot for what is essentially just a minor aside. The changed syntax introduces a new action, <code>Aside</code>, which groups actions under a condition, and then resumes the normal flow. So that script above would now be written:</p>
<pre>@root
If: foo==bar
  [Character] Foo equals bar!?
[Character] Continuing the convo...
</pre>
<p>There are some other more minor improvements, like immediately specifying dialogue choice consequences/outcomes. Previously this would also be clunky, involving some variable being set by the script runner and then checking for this variable later on. Really roundabout and relies on things happening that aren’t defined in the script itself. Now it’s just a matter of:</p>
<pre>[Character] Make a choice
  - A choice
    Outcomes:
      AddItem: SomeItem
</pre>
<p>The other change is better variable namespacing. Previously there was just “local” (local to the script) and “global” (set across the entire game). The scopes are now “script” (local to the script), “story” (local to the story the script is a part of, e.g. within the context of a mission), and “global”. This will hopefully make managing script variables easier and cleaner.</p>
<p>The last major <code>verses</code> update is that I actually got Unity scene parsing working well in Rust, and ended up stripping out Godot scene parsing entirely (not worth maintaining both).</p>
<p>Semi-related, I also switched entirely from <code>vim</code> to <code>nvim</code>/neovim and set up custom highlighting and in-editor parsing/validation for the game scripts:</p>
<p><figure>
            <a href="/assets/uploads/fugue/verses-nvim.png" title="">
            <img src="/assets/uploads/fugue/verses-nvim.png" title="">
            </a>
            <figcaption></figcaption>
            </figure><code>nvim</code></p>
<h2>Unity Updates</h2>
<p>The Unity version of the game is more or less at parity with the Godot version now. I’ve also implemented a very rough first draft for several other game systems (time, missions, inventory, etc). For inventory I’m tentatively using an RE-style spatial inventory, since it feels like a better way to limit inventory than weight/encumbrance, and is visually more interesting to manage. Still need to build out the UI for it though.</p>
<p>Because I’m expecting development to take a long time I switched over away from the LTS version of Unity to the 2022 version. So far it’s been a better editor experience–less laggy, though the compilation loop still sucks.</p>
<p>In general my experience with Unity has been very positive. I’ve been able to structure my code in a better and more reliable way than with Godot. The renowned <a href="https://www.youtube.com/watch?v=raQ3iHhE_Kk">Scriptable Object talk</a> was extremely helpful in designing an architecture that feels easy to build on. Unity’s component-based system is much nicer for decoupling, and having access to a more mature programming language is worth a lot (C# features like interfaces are very handy).</p>
<p>I’m still getting used to how Unity does things, like addressables and what not. There is a lot that’s clearly meant for very advanced, high-end games, and it’s hard for me to discern what’s overkill for me to adopt now and what I’ll regret not using further in the development process. But that’s just how these things go.</p>
<p>In general my focus now is on lowish-level framework stuff (currently trying to get character movement to work correctly). There are still many undetermined mechanics that will require playing around with, so trying to design things to flexibly accommodate different possibilities, or at least get a good foundation to experiment on. At some point soon I’ll cross over into actual gameplay and eventually writing (I hope).</p>
<p>For now the current near-term roadmap is:</p>
<ul>
<li>Get character movement working well</li>
<li>Start building out more UI</li>
</ul>
<h2>Dice mechanics</h2>
<p>I haven’t thought much on mechanics as I’ve been in implementation-mode for the past several weeks, but I have some more thoughts on missions, the energy mechanic (a stand-in for some kind of resource management mechanic). I find myself coming back to the Mario Party character-dice system and the system from <a href="https://store.steampowered.com/app/861540/Dicey_Dungeons/">Dicey Dungeons</a> where you assign dice to slots. I like these better than regular D&amp;D-style dice rolls because there’s <em>some</em> randomness but enough room to strategize so that you have more agency over outcomes.</p>
<p><figure>
            <a href="/assets/uploads/fugue/dicey-dungeons.png" title="">
            <img src="/assets/uploads/fugue/dicey-dungeons.png" title="">
            </a>
            <figcaption>Dicey Dungeons</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/mario-party-dice.jpg" title="">
            <img src="/assets/uploads/fugue/mario-party-dice.jpg" title="">
            </a>
            <figcaption>Super Mario Party character dice blocks (</figcaption>
            </figure></a>)</p>
<p>While searching for the images above I came across <a href="https://adventurerules.blog/2022/12/07/exploring-the-game-modes-of-slice-dice/">a game called Slice &amp; Dice</a> where you construct the dice yourself!</p>
<p><figure>
            <a href="/assets/uploads/fugue/slice-and-dice.png" title="">
            <img src="/assets/uploads/fugue/slice-and-dice.png" title="">
            </a>
            <figcaption>Slice & Dice</figcaption>
            </figure>]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 23: Migrating to Unity &amp;amp; Clay</title><link>projects/fugue/23</link><description><![CDATA[Migrating to UnitySo the last post was about migrating to Godot 4 and now I’ve gone and started migrating to Unity. At the start of this pr…]]></description><category>projects/fugue</category><pubDate>Fri, 14 Apr 2023 18:44:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p><figure>
            <a href="/assets/uploads/fugue/unity.png" title="">
            <img src="/assets/uploads/fugue/unity.png" title="">
            </a>
            <figcaption>Unity screenshot</figcaption>
            </figure>
<h2>Migrating to Unity</h2>
<p>So the last post was about migrating to Godot 4 and now I’ve gone and started migrating to Unity. At the start of this project I was deciding between Unity and Godot and ended up going with Godot for a few reasons, a big one being that I had used Unity maybe 8 or so years ago (I was originally developing <a href="http://thefounder.biz/">The Founder</a> in Unity) and hated it. At the time I believe Unity’s UI support was basically non-existent and the game was rather UI-heavy, so it was a frustrating experience. I think the Unity Editor for Linux was also in beta, though I was probably using OSX at that point.</p>
<p>But recently I figured Unity was worth another look, since this is a 3D game and less UI-heavy, and surely things have improved in the interim years. And they have. The Unity Editor for Linux works (more on this below) and the Unity ecosystem is of course more mature and battle-tested.</p>
<p>Some other considerations:</p>
<ul>
<li><em>Console/closed-platform support</em>. A big downside with open-source game engines like Godot and Bevy is that they can’t yet build for consoles, in part because these platforms require their integrations be closed-source (or something along those lines).</li>
<li><em>Built-in animation retargeting</em>. It’s been a struggle to figure out how to retarget animations for my generated characters. I was using the <a href="https://blendermarket.com/products/auto-rig-pro">Auto-Rig Pro</a> addon for Blender, which works great but wasn’t giving me the right root motion results in Godot. It seemed very complicated to debug. Unity, on the other hand, has a built-in animation retargeting for humanoid rigs that works great.</li>
<li><em>C# is a more mature and strongly-typed language</em>. Godot 4 improved a lot with GDScript but ultimately it still feels too in-development. It has typing support but many important types are lacking and it just doesn’t feel as solid as a proper strongly-typed language. C# isn’t the prettiest language to work with, but it feels like a good, stable foundation for a game.</li>
</ul>
<p>And a couple other bonuses:</p>
<ul>
<li>I haven’t done much UI work just yet but Unity’s new UI Toolkit system is interesting…the styling and layout is basically CSS.</li>
<li>Package management is also nice with <a href="https://openupm.com/"><code>openupm</code></a>.</li>
</ul>
<p>So far I don’t have much bad to say about my new Unity experience. The biggest issue is that the Editor still feels kind of janky in Linux; it’s rather slow and a bit buggy. It might still technically be in beta. I can’t, for example, drag and dock tabs into panels, which is annoying (see below for a workaround). Not sure if this is a limitation with my window manager or what. Godot’s Linux support on the other hand is amazing; their editor feels responsive and stable.</p>
<p><a href="/code/nvim_unity_setup/">Setting up my text editor was tricky</a> but it’s working alright now, except that I have to restart <code>nvim</code> to properly process new files (<a href="https://github.com/OmniSharp/omnisharp-roslyn/issues/2250">see this issue</a>) and that the language server takes a long time to start.</p>
<p>In general the development loop feels slower than Godot, largely due to the increased compilation times. There are some ways to improve these times (mainly by essentially bundling your code into sub-packages with assembly definition files), but so far I haven’t noticed a major improvement (though it’s probably not apparent until your project gets quite big). It’s not the worst thing but it does make development drag a bit.</p>
<p>And a very minor gripe is the number of artifacts that Unity produces. Tons of <code>.csproj</code> files and other folders. Godot was really lean in this regard; I believe all these generated artifacts were confined to a hidden <code>.import</code> folder.</p>
<p>(I’m also stubbornly not doing the C# new-line curly brace thing)</p>
<p>I’m still getting familiar with most of Unity’s core concepts–how input handling works, how unit testing works, etc–and so far haven’t encountered any major road blocks. The documentation is ok, but I’ve still had to do a bunch of forum digging to figure out exact approaches to some problems.</p>
<p>I suppose one bit of weirdness is that there are two different UI systems available; one seems more appropriate for more static/simpler UIs (this is the CSS-like UI Toolkit system) and the other (soon-to-be legacy? idk) is a canvas-based UI system (closer to how UI works in Godot). The latter seems more appropriate for more dynamic interface elements–I’m using them for dialogue boxes primarily because they can use TextMeshPro which gives fine-grained control over text meshes. I think TextMeshPro is supposed to be integrated into the UI Toolkit? Maybe it is already? I don’t know.</p>
<p>I am a little sad to stop using Godot…it’s great and I’m excited to see where it goes in the next several years. It’s already amazing how full-featured it is–perhaps it could become a Blender equivalent for game development. If Unity and Godot were at closer feature parity (especially with the three benefits listed above) I’d prefer Godot. But for now Unity makes more sense.</p>
<h2><code>clay</code></h2>
<p>I ported the character generation system from <code>hundun</code> into its own Rust package, <code>clay</code>, so I can generate characters independently of <code>hundun</code> and via, for example, a script in bulk.</p>
<p>Not much interesting to say here, except maybe on how I bundled static assets into the Rust binary. The character generation part relies on several Blender Python scripts that I need to know the paths for (so I can call <code>blender /path/to/the/python/script.py</code>). The trouble is these files could be anywhere, and I don’t want to hardcode or constantly pass in the paths to these scripts.</p>
<p>What I do is package them (and other static assets needed, like brush images) with the compiled application using the <a href="https://crates.io/crates/include_dir"><code>include_dir</code></a> crate. Then they can be extracted to a known location when needed:</p>
<pre><span class="comment">&#x2f;&#x2f;&#x2f; An interface to run scripts with Blender.
</span><span class="comment">&#x2f;&#x2f;&#x2f; Most of the character generation actually happens
</span><span class="comment">&#x2f;&#x2f;&#x2f; in Blender with Python scripts. These Python scripts
</span><span class="comment">&#x2f;&#x2f;&#x2f; are included in a kind of hacky way (see below).
</span><span class="comment">&#x2f;&#x2f;&#x2f; This method means that if the Python scripts are edited
</span><span class="comment">&#x2f;&#x2f;&#x2f; the Rust program needs to be re-compiled to include the
</span><span class="comment">&#x2f;&#x2f;&#x2f; latest script versions.
</span>
<span class="keyword">use</span> include_dir<span class="punctuation delimiter">::</span><span class="punctuation bracket">{</span>include_dir<span class="punctuation delimiter">,</span> <span class="constructor">Dir</span><span class="punctuation bracket">}</span><span class="punctuation delimiter">;</span>
<span class="keyword">use</span> std<span class="punctuation delimiter">::</span><span class="punctuation bracket">{</span>
    io<span class="punctuation delimiter">::</span><span class="constructor">Error</span><span class="punctuation delimiter">,</span>
    path<span class="punctuation delimiter">::</span><span class="punctuation bracket">{</span><span class="constructor">Path</span><span class="punctuation delimiter">,</span> <span class="constructor">PathBuf</span><span class="punctuation bracket">}</span><span class="punctuation delimiter">,</span>
    fs<span class="punctuation delimiter">::</span><span class="punctuation bracket">{</span>create_dir<span class="punctuation delimiter">,</span> remove_dir_all<span class="punctuation bracket">}</span><span class="punctuation delimiter">,</span>
    process<span class="punctuation delimiter">::</span><span class="punctuation bracket">{</span><span class="constructor">Command</span><span class="punctuation delimiter">,</span> <span class="constructor">Stdio</span><span class="punctuation delimiter">,</span> <span class="constructor">ExitStatus</span><span class="punctuation bracket">}</span>
<span class="punctuation bracket">}</span><span class="punctuation delimiter">;</span>

<span class="keyword">const</span> <span class="constructor">BLENDER_PATH</span><span class="punctuation delimiter">:</span> <span class="operator">&amp;</span><span class="type builtin">str</span> = <span class="string">&quot;&#x2f;usr&#x2f;local&#x2f;bin&#x2f;blender&quot;</span><span class="punctuation delimiter">;</span>

<span class="comment">&#x2f;&#x2f; Where to extract the included Blender scripts when calling</span>
<span class="comment">&#x2f;&#x2f; the `blender` command.</span>
<span class="keyword">const</span> <span class="constructor">EXTRACT_SCRIPTS_PATH</span><span class="punctuation delimiter">:</span> <span class="operator">&amp;</span><span class="type builtin">str</span> = <span class="string">&quot;&#x2f;tmp&#x2f;clay-blender&quot;</span><span class="punctuation delimiter">;</span>

<span class="comment">&#x2f;&#x2f; Bundle the Blender scripts with the Rust binary.</span>
<span class="comment">&#x2f;&#x2f; When needed we&#x27;ll extract the scripts somewhere we can point to.</span>
<span class="comment">&#x2f;&#x2f; This is a kind of hacky way to avoid juggling filepaths if this</span>
<span class="comment">&#x2f;&#x2f; library is used elsewhere.</span>
<span class="keyword">static</span> <span class="constructor">BLENDER_SCRIPTS_DIR</span><span class="punctuation delimiter">:</span> <span class="type">Dir</span><span class="punctuation bracket">&lt;</span><span class="operator">&#x27;</span><span class="label">_</span><span class="punctuation bracket">&gt;</span> = <span class="function macro">include_dir</span><span class="function macro">!</span><span class="punctuation bracket">(</span><span class="string">&quot;$CARGO_MANIFEST_DIR&#x2f;assets&#x2f;blender&quot;</span><span class="punctuation bracket">)</span><span class="punctuation delimiter"></span><span class="punctuation delimiter">;</span>

<span class="comment">&#x2f;&#x2f;&#x2f; Path to a file included in `BLENDER_SCRIPTS_DIR`.
</span><span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function">bundled_file</span><span class="punctuation bracket">(</span><span class="variable parameter">path</span><span class="punctuation delimiter">:</span> <span class="operator">&amp;</span><span class="type builtin">str</span><span class="punctuation bracket">)</span> -&gt; <span class="type">PathBuf</span> <span class="punctuation bracket">{</span>
    <span class="function macro">format</span><span class="function macro">!</span><span class="punctuation bracket">(</span><span class="string">&quot;{}&#x2f;{}&quot;</span><span class="punctuation delimiter">,</span> <span class="constructor">EXTRACT_SCRIPTS_PATH</span><span class="punctuation delimiter">,</span> path<span class="punctuation bracket">)</span><span class="punctuation delimiter"></span><span class="punctuation delimiter">.</span><span class="function method">into</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
<span class="punctuation bracket">}</span>

<span class="comment">&#x2f;&#x2f;&#x2f; Note: this assumes that `script` is bundled as parst of `BLENDER_SCRIPTS_DIR`.
</span><span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function">blender</span><span class="punctuation bracket">(</span><span class="variable parameter">blendfile_path</span><span class="punctuation delimiter">:</span> <span class="operator">&amp;</span><span class="type">PathBuf</span><span class="punctuation delimiter">,</span> <span class="variable parameter">script</span><span class="punctuation delimiter">:</span> <span class="operator">&amp;</span><span class="type builtin">str</span><span class="punctuation delimiter">,</span> <span class="variable parameter">env_vars</span><span class="punctuation delimiter">:</span> <span class="type">Vec</span><span class="punctuation bracket">&lt;</span><span class="punctuation bracket">(</span><span class="operator">&amp;</span><span class="type builtin">str</span><span class="punctuation delimiter">,</span> <span class="operator">&amp;</span><span class="type builtin">str</span><span class="punctuation bracket">)</span><span class="punctuation bracket">&gt;</span><span class="punctuation bracket">)</span>
    -&gt; <span class="type">Result</span><span class="punctuation bracket">&lt;</span><span class="type">ExitStatus</span><span class="punctuation delimiter">,</span> <span class="type">Error</span><span class="punctuation bracket">&gt;</span> <span class="punctuation bracket">{</span>
    <span class="comment">&#x2f;&#x2f; Extract the Blender scripts</span>
    <span class="keyword">if</span> <span class="type">Path</span><span class="punctuation delimiter">::</span><span class="function">new</span><span class="punctuation bracket">(</span><span class="constructor">EXTRACT_SCRIPTS_PATH</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">.</span><span class="function method">is_dir</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span> <span class="punctuation bracket">{</span>
        <span class="keyword">let</span> _ = <span class="function">remove_dir_all</span><span class="punctuation bracket">(</span><span class="constructor">EXTRACT_SCRIPTS_PATH</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    <span class="punctuation bracket">}</span>
    <span class="function">create_dir</span><span class="punctuation bracket">(</span><span class="constructor">EXTRACT_SCRIPTS_PATH</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">.</span><span class="function method">unwrap</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    <span class="constructor">BLENDER_SCRIPTS_DIR</span><span class="punctuation delimiter">.</span><span class="function method">extract</span><span class="punctuation bracket">(</span><span class="constructor">EXTRACT_SCRIPTS_PATH</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">.</span><span class="function method">unwrap</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>

    <span class="keyword">let</span> <span class="keyword">mut</span> cmd = <span class="type">Command</span><span class="punctuation delimiter">::</span><span class="function">new</span><span class="punctuation bracket">(</span><span class="constructor">BLENDER_PATH</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    cmd<span class="punctuation delimiter">.</span><span class="function method">args</span><span class="punctuation bracket">(</span><span class="punctuation bracket">[</span>
             <span class="string">&quot;-b&quot;</span><span class="punctuation delimiter">,</span> <span class="operator">&amp;</span>blendfile_path<span class="punctuation delimiter">.</span><span class="function method">to_string_lossy</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">,</span>
             <span class="string">&quot;--python&quot;</span><span class="punctuation delimiter">,</span> <span class="operator">&amp;</span><span class="function">bundled_file</span><span class="punctuation bracket">(</span>script<span class="punctuation bracket">)</span><span class="punctuation delimiter">.</span><span class="function method">to_string_lossy</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
    <span class="punctuation bracket">]</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>

    <span class="keyword">for</span> <span class="punctuation bracket">(</span>key<span class="punctuation delimiter">,</span> val<span class="punctuation bracket">)</span> <span class="keyword">in</span> env_vars <span class="punctuation bracket">{</span>
        cmd<span class="punctuation delimiter">.</span><span class="function method">env</span><span class="punctuation bracket">(</span>key<span class="punctuation delimiter">,</span> val<span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>
    <span class="punctuation bracket">}</span>
    <span class="keyword">let</span> <span class="keyword">mut</span> proc = cmd<span class="punctuation delimiter">.</span><span class="function method">stdout</span><span class="punctuation bracket">(</span><span class="type">Stdio</span><span class="punctuation delimiter">::</span><span class="function">inherit</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>
        <span class="punctuation delimiter">.</span><span class="function method">stderr</span><span class="punctuation bracket">(</span><span class="type">Stdio</span><span class="punctuation delimiter">::</span><span class="function">inherit</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>
        <span class="punctuation delimiter">.</span><span class="function method">spawn</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
        <span class="punctuation delimiter">.</span><span class="function method">expect</span><span class="punctuation bracket">(</span><span class="string">&quot;blender command failed to start&quot;</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>

    <span class="keyword">let</span> res = proc<span class="punctuation delimiter">.</span><span class="function method">wait</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>

    <span class="comment">&#x2f;&#x2f; Clean up extracted files</span>
    <span class="keyword">let</span> _ = <span class="function">remove_dir_all</span><span class="punctuation bracket">(</span><span class="constructor">EXTRACT_SCRIPTS_PATH</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">;</span>

    res
<span class="punctuation bracket">}</span>
</pre>
<h2>A very hacky way of setting the editor layout in Linux</h2>
<p>I did manage to figure out a very hacky way of docking tabs in the end. You can export the current editor layout to a <code>.wlt</code> file, which is essentially just a YAML file (as far as I can tell, it’s the exact same format that Unity game scenes use). So say for example I want to dock the Test Runner to be in the same dock as the Inspector. I’d open the Test Runner–which opens in a new window by default–and then save the layout. Then I’d edit the <code>.wlt</code> file. The YAML file consists of individual subdocuments, separated like so:</p>
<pre><span class="punctuation special">---</span> <span class="type">!u!114</span> <span class="punctuation special">&amp;</span><span class="type">1</span>
<span class="string">(some yaml)</span>
<span class="punctuation special">---</span> <span class="type">!u!114</span> <span class="punctuation special">&amp;</span><span class="type">2</span>
<span class="string">(some more yaml)</span>
<span class="punctuation special">---</span> <span class="type">!u!114</span> <span class="punctuation special">&amp;</span><span class="type">3</span>
<span class="string">(etc)</span>
</pre>
<p>The key here is these dividers preceded by <code>---</code>. The number after <code>&amp;</code> is the id (specifically, the <code>fileID</code>) of that component. Some of these represent entire windows (so in my case I’d have a main editor window and the smaller window spawned for the Test Runner), others represent docks (which I identify by their <code>m_Panes</code> property), and others represent the tabs themselves.</p>
<p>The gist is to look for the Test Runner tab (by searching for <code>m_Text: Test Runner</code>) and then getting the id of that component (say it’s <code>15</code>). Then I look for the Inspector tab (searching for <code>m_Text: Inspector</code>) and get that id (say it’s <code>20</code>). Then I look for a subdocument where <code>{fileID: 20}</code> is an item under <code>m_Panes</code>. That will be where the Inspector tab is currently docked. I just add another entry below it: <code>{fileID: 15}</code>.</p>
<p>I search for the document to other references of <code>{fileID: 15}</code> and then clear anything that references <em>those</em> parent ids, recursively, just to ensure that there aren’t multiple elements referring to the same component (i.e. deleting the dock that used to contain the Test Runner, and deleting the window that used to contain that dock).</p>
<p>Then save and load the layout in the editor.</p>
]]></content:encoded></item><item><title>Setting up NVIM for Unity development</title><link>code/nvim_unity_setup</link><description><![CDATA[Specifically for Linux. I’m using Ubuntu 22.04 and Unity 2021.3.22f1, with .
This was a pretty heinous setup process, so I’m documenting th…]]></description><category>code</category><pubDate>Fri, 07 Apr 2023 10:43:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>Specifically for Linux. I’m using Ubuntu 22.04 and Unity 2021.3.22f1, with <a href="https://github.com/neovim/nvim-lspconfig"><code>nvim-lspconfig</code></a>.</p>
<p>This was a pretty heinous setup process, so I’m documenting this here to help others who want something similar. The actual setup process isn’t too bad, but figuring out all the individual steps was difficult. I came across a few guides but some were out of date, or were geared towards Windows, or just didn’t work for me.</p>
<p>I should also caveat that I’m writing this shortly after I got this setup working, so I may run into other issues with it once I start developing with it more. For example, there might be <a href="https://github.com/OmniSharp/omnisharp-roslyn/issues/2250">issues with new files</a>. If I run into those problems and manage to solve them I’ll update this post.</p>
<p>Requirements:</p>
<ul>
<li><a href="https://github.com/OmniSharp/omnisharp-roslyn/releases"><code>omnisharp-roslyn</code></a>, I’m using <a href="https://github.com/OmniSharp/omnisharp-roslyn/releases/tag/v1.39.6"><code>v1.39.6</code></a>.</li>
<li><code>mono</code>; but crucially <em>not</em> the one from the default package repos. You need to use <a href="https://www.mono-project.com/download/stable/">their official repo</a>; then install: <code>apt install mono-devel mono-complete</code>.
<ul>
<li>The default Ubuntu package repo version doesn’t include <code>MSBuild</code> so unless you use the official mono repo you’ll get errors like “Could not locate MSBuild instance to register with OmniSharp.” when running <code>omnisharp-roslyn</code>.</li>
</ul>
</li>
</ul>
<p>The process:</p>
<ol>
<li>Download a release of <code>omnisharp-roslyn</code> (as mentioned above, I’m using <code>v1.39.6</code>). Extract it somewhere–for me, this was <code>/opt/omnisharp-roslyn</code>. The <code>run</code> file in that directory is what will start the LSP server.</li>
<li>Configure <code>nvim</code>. For me this all goes in <code>~/.vim/plugin/nvim-lsp.vim</code>, but you can change that to match your own preference. I’m including the whole file but the key parts are what follows <code>-- Omnisharp/C#/Unity</code>. You must specify the path to the <code>omnisharp-roslyn</code> <code>run</code> script.</li>
</ol>
<pre><span class="variable">lua</span><span class="operator"> &lt;&lt;</span> EOF<span class="keyword">
local</span> <span class="variable">nvim_lsp</span><span class="operator"> =</span> <span class="function">require</span><span class="function">(</span><span class="string">&#x27;lspconfig&#x27;</span><span class="function">)</span><span class="comment">

-- Use an on_attach function to only map the following keys</span><span class="comment">
-- after the language server attaches to the current buffer</span><span class="keyword">
local</span> <span class="variable">on_attach</span><span class="operator"> =</span> <span class="keyword function">function</span>(<span class="variable">client</span>, <span class="variable">bufnr</span>)
  <span class="keyword">local</span> <span class="keyword function">function</span> <span class="variable">buf_set_keymap</span>(<span class="constant">...</span>) <span class="variable">vim</span><span class="punctuation delimiter">.</span><span class="variable">api</span><span class="punctuation delimiter">.</span><span class="variable">nvim_buf_set_keymap</span><span class="function">(</span><span class="variable">bufnr</span><span class="punctuation delimiter">,</span> <span class="constant">...</span><span class="function">)</span> <span class="keyword function">end</span>
  <span class="keyword">local</span> <span class="keyword function">function</span> <span class="variable">buf_set_option</span>(<span class="constant">...</span>) <span class="variable">vim</span><span class="punctuation delimiter">.</span><span class="variable">api</span><span class="punctuation delimiter">.</span><span class="variable">nvim_buf_set_option</span><span class="function">(</span><span class="variable">bufnr</span><span class="punctuation delimiter">,</span> <span class="constant">...</span><span class="function">)</span> <span class="keyword function">end</span>

  <span class="comment">-- Omnicompletion</span>
  <span class="function">buf_set_option</span><span class="function">(</span><span class="string">&#x27;omnifunc&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;v:lua.vim.lsp.omnifunc&#x27;</span><span class="function">)</span>

  <span class="keyword">local</span> <span class="variable">opts</span> <span class="operator">=</span> <span class="punctuation bracket">{</span> <span class="variable">noremap</span><span class="operator">=</span>true<span class="punctuation delimiter">,</span> <span class="variable">silent</span><span class="operator">=</span>true <span class="punctuation bracket">}</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;gD&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.lsp.buf.declaration()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;gd&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.lsp.buf.definition()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;gi&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.lsp.buf.implementation()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;K&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.lsp.buf.hover()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;C-k&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.lsp.buf.signature_help()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;[d&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.diagnostic.goto_prev()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;]d&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.diagnostic.goto_next()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
  <span class="function">buf_set_keymap</span><span class="function">(</span><span class="string">&#x27;n&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;gR&#x27;</span><span class="punctuation delimiter">,</span> <span class="string">&#x27;&lt;cmd&gt;lua vim.lsp.buf.references()&lt;CR&gt;&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">opts</span><span class="function">)</span>
<span class="keyword function">end</span><span class="comment">

-- Omnisharp&#x2f;C#&#x2f;Unity</span><span class="keyword">
local</span> <span class="variable">pid</span><span class="operator"> =</span> <span class="variable">vim</span><span class="punctuation delimiter">.</span><span class="variable">fn</span><span class="punctuation delimiter">.</span><span class="variable">getpid</span><span class="function">(</span><span class="function">)</span><span class="keyword">
local</span> <span class="variable">omnisharp_bin</span><span class="operator"> =</span> <span class="string">&quot;&#x2f;opt&#x2f;omnisharp-roslyn&#x2f;run&quot;</span><span class="function">
require</span><span class="string">&#x27;lspconfig&#x27;</span><span class="punctuation delimiter">.</span><span class="variable">omnisharp</span><span class="punctuation delimiter">.</span><span class="variable">setup</span><span class="punctuation bracket">{</span>
    <span class="variable">on_attach</span> <span class="operator">=</span> <span class="variable">on_attach</span><span class="punctuation delimiter">,</span>
    <span class="variable">flags</span> <span class="operator">=</span> <span class="punctuation bracket">{</span>
      <span class="variable">debounce_text_changes</span> <span class="operator">=</span> 150<span class="punctuation delimiter">,</span>
    <span class="punctuation bracket">}</span><span class="punctuation delimiter">,</span>
    <span class="variable">cmd</span> <span class="operator">=</span> <span class="punctuation bracket">{</span> <span class="variable">omnisharp_bin</span><span class="punctuation delimiter">,</span> <span class="string">&quot;--languageserver&quot;</span> <span class="punctuation delimiter">,</span> <span class="string">&quot;--hostPID&quot;</span><span class="punctuation delimiter">,</span> <span class="function">tostring</span><span class="function">(</span><span class="variable">pid</span><span class="function">)</span> <span class="punctuation bracket">}</span>;
<span class="punctuation bracket">}</span><span class="variable">
EOF</span>
</pre>
<ol start="3">
<li>
<p>Then we need to generate the <code>.sln</code> and <code>.csproj</code> files for our Unity project. There are two ways to do this:</p>
<ul>
<li>Almost every other guide to this setup says you need to install <a href="https://code.visualstudio.com/docs/setup/linux">Visual Studio Code</a> to do this. This then requires that you go into your Unity project, go to <code>Edit &gt; Preferences &gt; External Tools</code>, then set <code>Visual Studio Code</code> to be your <code>External Script Editor</code>. Finally, check all the boxes for <code>Generate .csproj files for:</code>, then press <code>Regenerate project files</code>. This will work, and it’s what I tried first.</li>
<li>The alternative, which I found <a href="https://forum.unity.com/threads/any-way-to-tell-unity-to-generate-the-sln-file-via-script-or-command-line.392314/#post-5329122">here</a>, is to run <code>/opt/Unity/2021.3.22f1/Editor/Unity -batchmode -nographics -logFile - -executeMethod UnityEditor.SyncVS.SyncSolution -projectPath . -quit</code> in your project root folder (note that <code>/opt/Unity/2021.3.22f1/Editor/Unity</code> is just where I installed the Unity Editor, so change that to point to your location). This will also work, and appears to work without installing VSCode. The only annoying bit is that a project can only be opened by one instance of the editor at a time, so this won’t work if you already have your project open. Perhaps there’s a way to call it from within Unity?</li>
</ul>
</li>
<li>
<p>Finally, one issue I had was that for some reason <code>Assembly-CSharp.csproj</code> wasn’t generated. This led to the Unity framework not being picked up by <code>omnisharp</code>, with errors like “The type or namespace name ‘UnityEngine’ could not be found”. This solved itself by creating a new C# file, e.g. <code>Assets/Foo.cs</code> and then refreshing the project files in the Unity Editor (which I guess causes Unity to compile the scripts and then generate this missing file). No idea if this is necessary though.</p>
</li>
</ol>
<p>Lastly, the LSP server is slow to start up on my machine. Something like 30 seconds. For Rust and TypeScript development I use <a href="https://github.com/j-hui/fidget.nvim">this plugin</a>, which gives me progress on those LSP servers’ startups, but <a href="https://github.com/j-hui/fidget.nvim/issues/17">unfortunately it doesn’t yet work for <code>omnisharp</code></a>.</p>
<p>NB: Just a couple debugging tips if this doesn’t totally work for you: <code>:LspInfo</code> and <code>:LspLog</code> from within <code>nvim</code> can help you figure out what might be going wrong.</p>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 22: Migrating to Godot 4, Tooling Changes, and the Skill Check System</title><link>projects/fugue/22</link><description><![CDATA[Gliss, and Migrating to Godot 4Godot 4 was recently released and brings with it many improvements to GDScript (thankfully addressing most o…]]></description><category>projects/fugue</category><pubDate>Fri, 31 Mar 2023 11:11:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<h2><em>Gliss</em>, and Migrating to Godot 4</h2>
<p><a href="https://godotengine.org/article/godot-4-0-sets-sail/">Godot 4 was recently released</a> and brings with it many improvements to GDScript (thankfully addressing most of my pain points with the language), better performance, and several other changes that I can’t yet appreciate. Because the game code is still pretty basic I figured it’d be worthwhile to just migrate to Godot 4 now. It ended up being a good opportunity to refactor some things now that I have a clearer idea of what systems need to be included.</p>
<p>Semi-related to this refactor: I’ve decided to first work on a smaller demo/prototype called <em>Gliss</em> (for <em>glissando</em>) to test out mechanic ideas and the overall development process. The hope is to flesh out all the game designs and systems and then <em>Fugue</em> will just a bigger version with few, if any, new systems &amp; mechanics. My ideal outcome is that <em>Gliss</em> establishes the framework, and the expanding it into <em>Fugue</em> is mostly a matter of authoring more content–characters, locations, etc.</p>
<h2>Overhauling the Sequence Editor (<code>verses</code>)</h2>
<p>As I was starting to write out more sequence scripts I found the existing editor (below) to be clunky. And when I need to define new script actions (such as skill checks, more on that below), it requires a lot of lift to define the new frontend components and inputs. Just super unwieldy.</p>
<p><figure>
            <a href="/assets/uploads/fugue/hundun_03.jpg" title="">
            <img src="/assets/uploads/fugue/hundun_03.jpg" title="">
            </a>
            <figcaption>The now old sequence editor</figcaption>
            </figure>
<p>I revisited an idea which was to define a special plain-text format for sequence scripts. I never pursued it because I was daunted by the prospect of writing my own custom parser…but I had to do that anyway to parse Godot’s <code>.tscn</code> files, so what’s one more parser?</p>
<p>The process of writing the parser with <a href="https://github.com/rust-bakery/nom"><code>nom</code></a> actually wasn’t too bad. The trickiest/most frustrating bits were dealing with error handling (just haven’t fully grokked error handling in Rust in general) and handling recursive parsing (couldn’t figure out a good approach for that and ended up just putting a fixed limit on recursion depth). But otherwise once you get a handle on the combinators (especially with <a href="https://github.com/rust-bakery/nom/blob/main/doc/choosing_a_combinator.md">their indispensable guide</a>) the whole effort becomes intuitive.</p>
<p>I also implemented script validation which checks for common issues like requesting nodes or entities that don’t exist in a given scene, or referencing files that don’t exist, or bad sequence script structure (orphaned nodes, invalid branching, etc), and even typos. The goal is to have some assurance that there will be minimal runtime sequence errors.</p>
<p>The end result is <code>verses</code>, a custom Rust crate/program for parsing and validating gliss/fugue sequence script files. This program can be used to parse scripts to JSON (to import them into Godot as custom resources), and the previous <code>hundun</code> sequence editor (pictured above) is now a relatively thin UI on top of it:</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/new_sequence_editor.png" title="">
            <img src="/assets/uploads/fugue/tools/new_sequence_editor.png" title="">
            </a>
            <figcaption>The new sequence editor</figcaption>
            </figure>
<p>Now the script is just written in the editor on the left and the parsed sequence graph is displayed on the right. Validation happens live. Now the process of writing sequence scripts is less stop-and-go, more fluid than before. It also means that if I need to quickly edit a script file I can do it easily with a text editor.</p>
<p>The text editor itself is made with <a href="https://codemirror.net/">CodeMirror</a>, which is an intimidatingly powerful editor library. Here I’ve set it up to have custom syntax highlighting and custom autocomplete, which lets me autocomplete, for example, actor names.</p>
<h2>The Skill Check System</h2>
<p>I began working out the skill check system–the raw skill check mechanic itself is very straightforward, just compare the skill level and difficulty and roll to see if you succeed. I designed the actual rolling algorithm to be visualizable, so you’re not just seeing your odds and then the result. Instead, a rough summary is that the skill difficulty sets a number of successful flips you have to achieve, and your skill level determines how many tries you have. So for a skill level of 3 you get 3 tries. Each try lasts until it fails, so it is possible to succeed at a challenge of difficulty 4, even with just a skill level of 3. The probability of a successful flip is tuned to produce the following overall skill check success probabilities (i.e. each flip is not 50/50):</p>
<p><figure>
            <a href="/assets/uploads/fugue/skill_checks_probabilities.png" title="">
            <img src="/assets/uploads/fugue/skill_checks_probabilities.png" title="">
            </a>
            <figcaption>Skill check probabilities</figcaption>
            </figure>
<p>This chart is kind of confusing, but each line represents a different skill level. For example, say the skill is “Lockpicking”. Say your skill level at that is 3 (<code>s=3</code>). You have about a 100% chance of succeeding at any skill check with a difficulty less than 3. You have a very good chance for difficulty of 3 and about a 60% chance for a difficulty of 4.</p>
<p>I’m hoping that the modifiers will be where this system gets more interesting. The modifiers themselves are just straightforward increases/decreases to skill levels, but I want them to be organized in a way that 1) requires interesting character build decisions (through skill progression) and 2) reflects a character’s beliefs about and experiences in the world (that is, characters don’t just mindlessly/mechanically get better at lockpicking; rather, as they get better it changes how they see the world; and how they see the world affects their proficiencies in certain skills).</p>
<p>I need to think more on 1), but the general idea is that each skill has one or two underlying “proficiencies” that are shared with other skills. For example the two proficiencies for “Lockpicking” might be “Hand-Eye Coordination” (which also underlies the “Medical” skill) and “Puzzle-Breaking” (which also underlies the “Digital Evasion” skill). At the 3rd and 5th skill levels you can pick which of the two proficiencies to take a bonus in (a more expansive build), or you can pick a perk (e.g. you get one free lockpicking attempt without using a lockpick, for a more specialized build). This isn’t all that different from typical skill systems.</p>
<p>Whereas 1) are intentional decisions the player makes, 2) reflects playstyle patterns, and so is more indirect. If a character frequently uses intimidation actions, or frequently witnesses them, they may pick up an “insight” of “Violence is the Answer”, which gives bonuses to violence-related skill checks and penalizes non-violent ones. If they are constantly lockpicking and hacking, they may pick up the “Security is a Fiction” insight, which buffs these skills, but the anxiety of this realization means they stress more easily (which connects to the Energy mechanic, which I’m still working out).</p>
<h2>Refactoring <code>chargen</code> into <code>clay</code></h2>
<p>What I’m working on now is refactoring the character generation system (formerly <code>chargen</code>) into a separate crate called <code>clay</code>. This is to also streamline some things as with <code>verses</code>, e.g. make it easier to quickly edit characters and bulk generate large amounts of them. <code>hundun</code> will again be mostly just the UI on top and not handle the actual character generation logic.</p>
<h2>Next steps</h2>
<ul>
<li>Finish porting <code>clay</code></li>
<li>Figure out the character export/import into Godot workflow (running into some root motion issues here)</li>
<li>Re-implement sequence script importing using <code>verses</code></li>
<li>Implement skill check mechanic for testing</li>
<li>Continue developing the core mechanics (e.g. the Energy mechanic)</li>
<li>Probably some other stuff I’m not remembering</li>
</ul>
]]></content:encoded></item><item><title>Log: 1/25/2023</title><link>log/2023_01_27</link><description><![CDATA[Food in Mexico, Junji Ito’s new show, apocalyptic 90’s violence, and radioactive whetstones.
Food in MexicoKira and I just returned from Me…]]></description><category>log</category><pubDate>Fri, 27 Jan 2023 19:16:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p><em>Food in Mexico, Junji Ito’s new show, apocalyptic 90’s violence, and radioactive whetstones.</em></p>
<h2>Food in Mexico</h2>
<p>Kira and I just returned from Mexico (Oaxaca and Mexico City) for a wedding (which was wonderful) and I got to try many foods I’ve never had before. Some of the highlights:</p>
<p><figure>
            <a href="/assets/uploads/mexico/nanche.jpg" title="">
            <img src="/assets/uploads/mexico/nanche.jpg" title="">
            </a>
            <figcaption>Nanche</figcaption>
            </figure>
<p><a href="https://en.wikipedia.org/wiki/Byrsonima_crassifolia"><em>Nanche</em></a>
but only in raspados (a kind of shaved ice) form, where the fruits themselves were suspended in a kind of syrup. The syrup tasted overwhelmingly like butterscotch candies, not so much like Werthers but like the kinds that would come in unlabeled gold reflective foil and be more of a translucent yellow than a solid creamy brown. The fruit itself had some of that butterscotch taste but also tasted a bit like an Asian pear mixed with <a href="https://en.wikipedia.org/wiki/Crataegus_pinnatifida">haw</a>.</p>
<p><figure>
            <a href="/assets/uploads/mexico/tepache.jpg" title="">
            <img src="/assets/uploads/mexico/tepache.jpg" title="">
            </a>
            <figcaption>Tepache</figcaption>
            </figure>
<p><a href="https://en.wikipedia.org/wiki/Tepache"><em>Tepache</em></a> is now fairly common as a canned beverage throughout bodegas throughout New York. I’ve only ever had it from a can. This version here had a much stronger molasses taste, and more of a pungent fermented flavor. It might have been a little alcoholic, which is probably absent in the canned versions.</p>
<p><figure>
            <a href="/assets/uploads/mexico/tejate.jpg" title="">
            <img src="/assets/uploads/mexico/tejate.jpg" title="">
            </a>
            <figcaption>Tejate</figcaption>
            </figure>
<p><a href="https://en.m.wikipedia.org/wiki/Tejate"><em>Tejate</em></a>, which is a maize-cacao concoction that also includes <a href="https://en.m.wikipedia.org/wiki/Pouteria_sapota"><em>pixtle</em></a>, which I’d never heard of before. Had a nice foamy top and was very easy to drink.</p>
<p><figure>
            <a href="/assets/uploads/mexico/unknown.jpg" title="">
            <img src="/assets/uploads/mexico/unknown.jpg" title="">
            </a>
            <figcaption>Unknown herb</figcaption>
            </figure>
<p>I have no idea what this herb is, but it was a garnish on top of a lime soda I’d ordered. It was bitter and tasted like a combination of artificial chocolate scent (scratch-and-sniff chocolate), artificial peach (like the Haribo gummies), and bubble gum (but like those small Bazooka bubble gums when the flavor is almost all gone and it’s getting difficult to chew). It was interesting at first but quickly became too overwhelming.</p>
<p>Another herb was <a href="https://en.m.wikipedia.org/wiki/Porophyllum_ruderale"><em>pápalo</em></a>, which came on top of a <a href="https://en.wikipedia.org/wiki/Cemita"><em>cemita</em></a> we had. I don’t remember much about how it tasted except that it was kind of like cilantro, but stronger. Separately I also had <a href="https://en.m.wikipedia.org/wiki/Porophyllum_linaria"><em>chepiche</em></a> as a garnish for a <a href="https://en.wikipedia.org/wiki/Tlayuda"><em>tlayuda</em></a>, which tasted like an <em>even stronger</em> version of cilantro.</p>
<p><figure>
            <a href="/assets/uploads/mexico/mexican_yam.jpg" title="">
            <img src="/assets/uploads/mexico/mexican_yam.jpg" title="">
            </a>
            <figcaption>Mexican yam</figcaption>
            </figure>
<p>I didn’t get to try “Mexican yam” but they are unique-looking plants. This one kind of looks like a katamari. It’s hard to discern its silhouette against the backdrop of rocks so I outlined it.</p>
<p><figure>
            <a href="/assets/uploads/mexico/mole.jpg" title="">
            <img src="/assets/uploads/mexico/mole.jpg" title="">
            </a>
            <figcaption>Homemade mole coloradito</figcaption>
            </figure>
<p>Lastly, Kira signed us up for an amazing cooking class where we learned to make this delicious <em>mole coloradito</em> (among other things).</p>
<h2><em>Junji Ito Maniac: Tales of the Macabre</em></h2>
<p><figure>
            <a href="/assets/uploads/junji_ito_maniac.jpg" title="">
            <img src="/assets/uploads/junji_ito_maniac.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>I love Junji Ito’s work but this <a href="https://www.imdb.com/title/tt21856734/">new anthology series</a> missed the mark. Part of the horror of his work is his grievously detailed illustrations and how he frames the key moment of climactic terror. You’re drawn to linger on the page and absorb each stroke of his line work. But you can’t really linger in an anime, and so the impact of each horrific turn is totally dampened. And the stories often end very abruptly. I didn’t end up finishing it.</p>
<p>The only adaptation of Junji Ito’s that I’ve liked is <a href="https://store.steampowered.com/app/913740/WORLD_OF_HORROR/"><em>World of Horror</em></a>, which I talked about <a href="https://spaceandtim.es/log/2021_04_02/#world-of-horror">back in 2021</a>. Considering this show, it might be because that game more closely emulates Ito’s style.</p>
<h2>Apocalyptic Violence in the 90’s</h2>
<p><figure>
            <a href="/assets/uploads/waco.jpg" title="">
            <img src="/assets/uploads/waco.jpg" title="">
            </a>
            <figcaption>Waco</figcaption>
            </figure>
<p>Listening to <a href="https://crooked.com/podcast-series/mother-country-radicals/">Mother Country Radicals</a> made me curious about the similar patchwork of radical activity in the 90s. I vaguely remember hearing about the Oklahoma City Bombing and references to Waco growing up but not really learning much about it. This 1999 masters thesis, <a href="https://scholarworks.wmich.edu/cgi/viewcontent.cgi?article=6054&amp;context=masters_theses">“Political Violence in the United States: Apocalyptic Typologies of Left and Right Wing Political Groups and Their Violence through the Period 1990-1997”</a> (by Gordon Daniel Green), gives an overview of the period from the framework of “apocalyptic” (aka millenarian) movements–i.e. movements that foresaw an impending major shift around which urgent action needed to happen. In particular the imminence of the shift called for violent action (as opposed to e.g. mass political campaigns), and these actions were carried out in small groups. On the left this typology includes animal rights groups (the Animal Liberation Front), environmental groups (Earth Liberation Front, Earth First!), and anti-industrial/technology groups (Deep Ecology, the Unabomber); on the right this includes militia/patriot groups, the Rescue Movement (anti-abortion activism, the Army of God), and end-times religious groups (the Branch Davidians).</p>
<p>These groups tend to see the world as Manichean (good vs evil) and zero-sum (any win for the other side is necessary a loss for their side; i.e. there can be no mutual gains or victories or compromise), and motivated not by personal gain but by “a higher cause”.</p>
<p>The author leaves out groups focused on racism and/or anti-Semitism because they “differ from the above groups in the desired outcomes of their actions…although believing in a coming apocalyptic Race War…[they] do not seek to change the beliefs, ideology, or actions of the rest of society. They seek only to change those of white or ‘Aryan’ members of society. … A racist cannot change a black man to white, nor change a Jew into a Gentile”, though of course there’s overlap between the beliefs of these groups and the ones analyzed here.</p>
<p>I was struck by how these movements reflect some of the movements of the present: conspiracies around “internationalists” (“globalists” being the preferred term today), panic around “federal tyranny” and gun restrictions, paranoia around secret world governments trying to bring in the antichrist (QAnon-like), false flags (belief that the Oklahoma City Bombing was “the equivalent of the Reichstag fire that brought Hitler to power. The government is often seen as either having prior knowledge of the bombing…or direct involvement”), and so on. And of course many if not all of the same environmental and animal welfare concerns remain. Though I can’t remember seeing any major millenarian cults with apocalyptic predictions lately. And the way these groups are organized probably have changed a lot, but it reading this it feels like those changes are of a degree than of a kind (e.g. how quickly and far-reaching something like QAnon can be with social media). One major difference may be the increase in violence motivated not by a higher cause but by feeling personally slighted (male lone-wolf shooters)…though they are connected in a way, and maybe this is the extreme end of the “small group” organizational form (with a group size of one).</p>
<h2>Graphical/node-based programming prototype</h2>
<p>I sketched out <a href="https://github.com/frnsys/draft">a node-based programming tool</a> (not the <a href="https://github.com/frnsys/system_designer_ui">first time I’ve tried this</a>…), in part to implement a feature I always felt was lacking in other visual programming tools. This feature is inspired by the various Firefox Vim addons (can’t remember exactly where I first encountered the feature, it was either <a href="http://bug.5digits.org/pentadactyl/index">Pentadactyl</a>, <a href="http://vimperator.org/">Vimperator</a>, or <a href="https://addons.mozilla.org/en-US/firefox/addon/vimium-ff/">Vimium</a>).</p>
<p><figure>
            <a href="/assets/uploads/draft_jump.png" title="">
            <img src="/assets/uploads/draft_jump.png" title="">
            </a>
            <figcaption>Quick-connect ports</figcaption>
            </figure>
<p>In the screenshot above I have a port selected (“International navigation (memo item)”, highlighted in yellow). When a port is selected, candidate input ports are assigned a sequence of keystrokes to immediately connect the two ports. The keys are limited to <code>asdf</code> so you don’t have to move your hand from the home row to specify the target. Saves a lot of time of dragging your mouse and trying to target the correct port.</p>
<h2>Radioactive whetstones</h2>
<p>I was looking to pick up a new whetstone and found a couple reviewers notice that they were radioactive??</p>
<p><figure>
            <a href="/assets/uploads/radioactive_whetstones.png" title="">
            <img src="/assets/uploads/radioactive_whetstones.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>It sounds like it’s not something to worry about (and normal):</p>
<ul>
<li><a href="https://www.reddit.com/r/sharpening/comments/jhwpzn/danger_of_radiation_from_whetstones/">Danger of Radiation from Whetstones</a></li>
<li><a href="https://www.reddit.com/r/sharpening/comments/ji06ei/comparing_whetstones_when_i_stumbled_across_this/">Comparing whetstone’s when I stumbled across this</a></li>
</ul>
<p>but I can’t find any more authoritative sources.</p>
<hr />
<p><figure>
            <a href="/assets/uploads/endnotes/bf_climate.jpg" title="">
            <img src="/assets/uploads/endnotes/bf_climate.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 21: More Character Generation Work</title><link>projects/fugue/21</link><description><![CDATA[Chargen fixes and improvementsI’ve had to fix a few more issues with the character generation system, but also added some improvements.
One…]]></description><category>projects/fugue</category><pubDate>Fri, 16 Dec 2022 18:18:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<h2>Chargen fixes and improvements</h2>
<p>I’ve had to fix a few more issues with the character generation system, but also added some improvements.</p>
<p>One of the main problems was with the poly reduction (the <code>Decimate</code> modifier), which can make some interactions between clothing and the character body unpredictable. Basically when clothes is close to the body and you have the character in different animations/poses, sometimes the underlying body can clip through the clothes. If the clothes conform to the body’s geometry this is less of an issue because you won’t, for example, have pointy geometry that can poke through more rounded geometry.</p>
<p>The way <code>MakeClothes</code> handles this is with its delete groups, where you basically flag specific vertices to be deleted when wearing a particular clothing item. The underlying vertices are redundant because they’re covered by the clothes, and no vertices there means no clipping.</p>
<p>The <code>Decimate</code> modifier complicates this in two ways:</p>
<ol>
<li>It may modify the body and clothing geometry in different ways, such that two surfaces that conformed are now shaped differently, so now the surface underneath may poke out through the surface above (consider that a smooth rounded surface has a higher poly count than a pointy pyramid-like surface; decimate converts these rounded surfaces into pointier ones.</li>
<li>It may modify the geometry such that delete groups end up deleting too much of the mesh.</li>
</ol>
<p>So far these haven’t caused major problems; I’ve been able to solve them by adjusting delete groups or by slightly scaling up clothing/hair so there’s margin for pointy surfaces to stay concealed.</p>
<p>Aside from this I made a few minor quality-of-life improvements. I added a “Quick Preview” option which only converts the first frame of each character animation, cutting down character generation time by 30 seconds or so (really useful when tweaking things). I also added a way to generate clothing previews from within Blender and see them from within the character generator:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/clothes_picker.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/clothes_picker.jpg" title="">
            </a>
            <figcaption>Clothes preview generation and picker</figcaption>
            </figure>
<p>I also added a way to colorize clothing. Solid-colored clothes are made using a base forest green texture, (<code>#1e3b2f</code>), generated using the texture painting algorithm I described <a href="/projects/fugue/19/">a few posts back</a>:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/SolidColor.png" title="">
            <img src="/assets/uploads/fugue/chargen/SolidColor.png" title="">
            </a>
            <figcaption>Base solid color texture</figcaption>
            </figure>
<p>In the UI you can pick a color and then that forest green is replaced in that texture:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/colorize_clothes.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/colorize_clothes.jpg" title="">
            </a>
            <figcaption>Picking the color of clothes</figcaption>
            </figure>
<p>This lets me squeeze a bit more mileage out of clothes meshes without needing to make different textures for every solid color I might want to use. The system is flexible enough that I can create more complicated textures that also use this system to re-colorize them, so long as they’re based around that same forest green.</p>
<p>And I <em>finally</em> figured out why my <code>webpack</code> builds were taking so long. They took anywhere from 5-10min for the initial build, now it’s just a few seconds<sup class="footnote-reference"><a href="#typescript">1</a></sup>.</p>
<h2>Screen shader tweaking</h2>
<p>I’m trying to settle on screen shader settings for the game. There is already some downsampling happening here (well, the max resolution is set to 720p, so pixel cruchiness is more visible when rendering to higher resolutions than that), and I also had the color depth reduced to 4 for awhile. It’s a nice visual effect but might get fatiguing, so I played around with some other settings.</p>
<p>Common settings across these renders: <code>resolution=1, saturation=1.1, dithering=false, brightness=1</code>.</p>
<p>(I did do some comparisons with <code>dithering=true</code> but this didn’t make much of a difference except introducing some artifacts at lower resolutions.)</p>
<div id="effect-comparison">
    <div id="effect-comparison-tabs"></div>
    <div>
        <img alt="no effect" src="/assets/uploads/fugue/screen_effect_comparison/no_effect.png">
        <img alt="d=4,c=1.1" src="/assets/uploads/fugue/screen_effect_comparison/depth=4_contrast=1.1.png">
        <img alt="d=6,c=1.1" src="/assets/uploads/fugue/screen_effect_comparison/depth=6_contrast=1.1.png">
        <img alt="d=6,c=1.2" src="/assets/uploads/fugue/screen_effect_comparison/depth=6_contrast=1.2.png">
        <img alt="d=8,c=1.1" src="/assets/uploads/fugue/screen_effect_comparison/depth=8_contrast=1.1.png">
        <img alt="d=8,c=1.2" src="/assets/uploads/fugue/screen_effect_comparison/depth=8_contrast=1.2.png">
    </div>
</div>
<style>
#effect-comparison img {
    display: none;
}
#effect-comparison-tabs {
    display: flex;
    background: #131313;
}
#effect-comparison-tabs div {
    flex: 1;
    text-align: center;
    border-top: 1px solid #fff;
    border-bottom: 1px solid #fff;
    border-right: 1px solid #fff;
    cursor: pointer;
    margin-bottom: 2px;
    font-family: monospace;
}
#effect-comparison-tabs div:first-child {
    border-radius: 2px 0 0 2px;
    border-left: 1px solid #fff;
}
#effect-comparison-tabs div:last-child {
    border-radius: 0 2px 2px 0;
}
#effect-comparison-tabs div:hover {
    background: #222;
}
</style>
<script>
const tabsEl = document.querySelector('#effect-comparison-tabs');
const imgs = [...document.querySelectorAll('#effect-comparison img')];
let selected = imgs[0];
function select(img) {
    selected.style.display = 'none';
    img.style.display = 'block';
    selected = img;
}
select(selected);
imgs.forEach((img, i) => {
    const tab = document.createElement('div');
    tab.innerText = img.alt;
    tabsEl.appendChild(tab);
    tab.addEventListener('click', () => {
        select(imgs[i]);
    });
});
</script>
<p>I think I’ll probably stick to <code>depth=6</code> (since it still introduces some interesting banding on the wall, but not too aggressive like it is with a color depth of 4) and <code>contrast=1.2</code> for now. It may change as more environments and characters are created.</p>
<h2>Test characters</h2>
<p>I started making more use out of the character generation system to see if anything else needs improving. Part of this trial run required creating more clothing and hairstyles to try out. These characters are all randomly generated (except for the clothing/hair, which are added afterwards):</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/big_bro.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/big_bro.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/buur_bajj.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/buur_bajj.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/clothes_clipping.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/clothes_clipping.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/feyin.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/feyin.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/juun_joupp.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/juun_joupp.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/persa.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/persa.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/seam_test.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/seam_test.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/sira_sora.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/sira_sora.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/characters/yaba_daba_doo.cropped.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/characters/yaba_daba_doo.cropped.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<h2>Next steps</h2>
<p>I’ll likely leave the character generation system here for now, though I’ll need to make a lot more clothes and hairstyles eventually. The priority now is to figure out the story and game mechanics since those influence everything else moving forward.</p>
<hr />
<div class="footnote-definition" id="typescript"><sup class="footnote-definition-label">1</sup>
<p>The main change was that the <code>typescript-loader</code> is very slow unless it’s set to <code>transpileOnly: true</code>, I don’t fully understand why.</p>
</div>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 20: Merging Textures in Blender</title><link>projects/fugue/20</link><description><![CDATA[At the end of the last post I mentioned some optimization considerations for Fugue’s character models. I managed to reduce the poly count o…]]></description><category>projects/fugue</category><pubDate>Fri, 09 Dec 2022 13:03:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>At the end of <a href="/projects/fugue/19/">the last post</a> I mentioned some optimization considerations for <em>Fugue</em>’s character models. I managed to reduce the poly count of the human model a bit, but my quick-and-dirty approach (using Blender’s <code>Decimate</code>) messed up the mesh’s structure too much and caused some issues, so I’ll have to try a more manual method [<em>Update</em>: see the end of this post].</p>
<p>The other bit of optimization I started working on was reducing draw calls. A fully dressed character model has several different materials: one for the human (the skin texture) and then one for each item of clothing. I couldn’t find any clear information about how Godot handles draw calls and materials but generally more materials means more draw calls. So if I can merge the skin and clothes materials I should be able to reduce draw calls to as low as one per character.</p>
<p>I thought there’d be a Blender addon that does this but I surprisingly couldn’t find any. There are texture atlas baking addons which isn’t quite what I’m looking for–they assume that your UV maps neatly laid out, without overlaps, and they’re usually for baking environmental influence (e.g. lighting/shadows) into the texture (I just need to cut and rearrange the original texture data). Merging materials in the way I have in mind is tricky because each mesh has its own UV map and when you merge the meshes these UV maps all overlap:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/merged_uv_layouts.png" title="">
            <img src="/assets/uploads/fugue/chargen/merged_uv_layouts.png" title="">
            </a>
            <figcaption>Merging objects and the resulting UV layout issue</figcaption>
            </figure>
<p>(You can also see that there are some scaling issues, where the pants UV layout is now stretched–the original pants texture has a non-square aspect ratio.)</p>
<p>To solve this you need to scale/move the UV maps so they each have their own space, which then requires you to also move the underlying parts of their original textures to where their UV map regions were moved to so that the correct image data is still mapped to the correct faces.</p>
<p>In theory this isn’t too difficult–there are some tricky parts like placing the UV map regions (a concave bin packing problem) but everything else is straightforward if you have the UV map geometry. But actually implementing this was really rough–probably my most frustrating development experience in recent memory. I’m not even finished yet, so crossing my fingers that nothing else comes up. This is one of those problems that required many different approaches, and it’s possible that I’ll need to pull ideas from old abandoned ideas if I run into new obstacles…so I’ll try to document my thinking and attempts here.</p>
<p>The biggest struggle was with Blender itself. Blender is an amazing tool and its scripting capabilites are awesome, but they feel like an afterthought, especially for background mode/headless scripting. It has so many puzzling design decisions, many useful functions don’t have a Python API, and an inconsistent dependency on the UI. There are functions that behave differently depending on what the active window/area is or if you’re in <code>EDIT</code> mode vs <code>OBJECT</code> mode, and if you aren’t running the UI (i.e. running Blender in background mode) some of these functions don’t work at all. So of course the entire script I developed within the UI environment didn’t end up working when I switched to the background mode 🙃.</p>
<p>There are also some strange instabilities and limitations of headless Blender, like I can’t export UV layouts because “the GPU can’t be used in background mode”, but I’m able to render 3d scenes without any problem. I’m sure there’s a good reason. Similarly, for some reason loading JPGs and converting them to RGBA with <code>Pillow</code> segfaults from within the Blender environment but works just fine using Blender’s Python when not running Blender. Fortunately these problems always had a hacky workaround.</p>
<p>There also just isn’t a lot of information about scripting for headless Blender so it was difficult to find answers or discussion when I did run into problems.</p>
<p>The other difficult part was getting the UV map data I needed–in particular the geometry of each individual UV map region. What I’m calling a “UV map region” here isn’t quite the same as a “UV island”. Islands are sets of connected UVs and they can overlap. In the maps below the islands are outlined in blue:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/merged_faces_vs_uv_layouts.png" title="">
            <img src="/assets/uploads/fugue/chargen/merged_faces_vs_uv_layouts.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>In my case I care about contiguous regions of UV map, whether or not they are connected. So the UV map on the right with all the overlapping islands would be considered a single UV map region, and each island in the UV map on the left is also its own UV map region.</p>
<p>To identify these regions I needed two bits of information:</p>
<ol>
<li>The polygon boundaries of each island</li>
<li>A mapping of UVs to the island they belong to</li>
</ol>
<p>Surprisingly there is no built-in Python function to access UVs by island. There is a way to hack it though:</p>
<pre><span class="comment"># Make sure the correct object is selected</span>
<span class="comment"># and that you&#x27;re in edit mode</span>
<span class="variable">obj</span> <span class="operator">=</span> <span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">data</span><span class="punctuation delimiter">.</span><span class="variable">objects</span><span class="punctuation bracket">[</span><span class="string">&#x27;your-object-name&#x27;</span><span class="punctuation bracket">]</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">context</span><span class="punctuation delimiter">.</span><span class="variable">view_layer</span><span class="punctuation delimiter">.</span><span class="variable">objects</span><span class="punctuation delimiter">.</span><span class="variable">active</span> <span class="operator">=</span> <span class="variable">obj</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">object</span><span class="punctuation delimiter">.</span><span class="variable">mode_set</span><span class="punctuation bracket">(</span><span class="variable">mode</span> <span class="operator">=</span> <span class="string">&#x27;EDIT&#x27;</span><span class="punctuation bracket">)</span>
<span class="variable">bm</span> <span class="operator">=</span> <span class="variable">bmesh</span><span class="punctuation delimiter">.</span><span class="variable">from_edit_mesh</span><span class="punctuation bracket">(</span><span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">context</span><span class="punctuation delimiter">.</span><span class="variable">active_object</span><span class="punctuation delimiter">.</span><span class="variable">data</span><span class="punctuation bracket">)</span>
<span class="variable">uv_layers</span> <span class="operator">=</span> <span class="variable">bm</span><span class="punctuation delimiter">.</span><span class="variable">loops</span><span class="punctuation delimiter">.</span><span class="variable">layers</span><span class="punctuation delimiter">.</span><span class="variable">uv</span><span class="punctuation delimiter">.</span><span class="variable">verify</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>

<span class="comment"># Select all UVs</span>
<span class="comment"># then generate seams from UV islands</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">uv</span><span class="punctuation delimiter">.</span><span class="variable">select_all</span><span class="punctuation bracket">(</span><span class="variable">action</span><span class="operator">=</span><span class="string">&#x27;SELECT&#x27;</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">uv</span><span class="punctuation delimiter">.</span><span class="variable">seams_from_islands</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>

<span class="comment"># Collect the island boundary edges here</span>
<span class="variable">edges</span> <span class="operator">=</span> <span class="punctuation bracket">[</span><span class="punctuation bracket">]</span>
<span class="keyword control repeat">for</span> <span class="variable">f</span> <span class="keyword operator">in</span> <span class="variable">bm</span><span class="punctuation delimiter">.</span><span class="variable">faces</span><span class="punctuation delimiter">:</span>
    <span class="keyword control repeat">for</span> <span class="variable">l</span> <span class="keyword operator">in</span> <span class="variable">f</span><span class="punctuation delimiter">.</span><span class="variable">loops</span><span class="punctuation delimiter">:</span>
        <span class="keyword control conditional">if</span> <span class="variable">l</span><span class="punctuation delimiter">.</span><span class="variable">edge</span><span class="punctuation delimiter">.</span><span class="variable">seam</span> <span class="keyword operator">or</span> <span class="variable">l</span><span class="punctuation delimiter">.</span><span class="variable">edge</span><span class="punctuation delimiter">.</span><span class="variable">is_boundary</span><span class="punctuation delimiter">:</span>
            <span class="variable">a</span> <span class="operator">=</span> <span class="variable">l</span><span class="punctuation bracket">[</span><span class="variable">uv_layers</span><span class="punctuation bracket">]</span><span class="punctuation delimiter">.</span><span class="variable">uv</span>
            <span class="variable">b</span> <span class="operator">=</span> <span class="variable">l</span><span class="punctuation delimiter">.</span><span class="variable">link_loop_next</span><span class="punctuation bracket">[</span><span class="variable">uv_layers</span><span class="punctuation bracket">]</span><span class="punctuation delimiter">.</span><span class="variable">uv</span>

            <span class="comment"># Blender&#x27;s texture coordinates are flipped</span>
            <span class="comment"># than most image processing;</span>
            <span class="comment"># i.e. top-left is (0, 1) rather than (0, 0).</span>
            <span class="comment"># So we reflect everything over y=0.5 (i.e. flip vertically)</span>
            <span class="comment"># to compensate.</span>
            <span class="variable">edges</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="punctuation bracket">(</span><span class="punctuation bracket">(</span><span class="variable">a</span><span class="punctuation delimiter">.</span><span class="variable">x</span><span class="punctuation delimiter">,</span> <span class="constant numeric integer">1</span> <span class="operator">-</span> <span class="variable">a</span><span class="punctuation delimiter">.</span><span class="variable">y</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">,</span> <span class="punctuation bracket">(</span><span class="variable">b</span><span class="punctuation delimiter">.</span><span class="variable">x</span><span class="punctuation delimiter">,</span> <span class="constant numeric integer">1</span> <span class="operator">-</span> <span class="variable">b</span><span class="punctuation delimiter">.</span><span class="variable">y</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>
</pre>
<p>This method relies on Blender’s built in “Seams from Islands” function, which marks the border edges of UV islands as a “seam”. Then we can iterate all edges of the mesh to find those that are marked as a seam.</p>
<p>This actually worked fine until I tried it on a UV map where the seams produced by this function didn’t actually match the island’s borders:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/pants_islands.png" title="">
            <img src="/assets/uploads/fugue/chargen/pants_islands.png" title="">
            </a>
            <figcaption>Seams/islands extracted from the pants</figcaption>
            </figure>
<p>Here the islands, outlined in red, are just the openings of the pants. The rest of the island border isn’t selected.</p>
<p>I didn’t really understand why until I read more on how mesh geometry works in Blender. Meshes are composed of faces, and each face is composed of “loops”. A loop is a vertex and an edge (which connects to another vertex), though I use “edge” and “loop” interchangeably here. Each face has its own loops, <em>even if those edges are shared with other faces</em>. In the example below there are two faces joined by an edge. That edge is actually two edges, one for each face.</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/blender_loops.png" title="">
            <img src="/assets/uploads/fugue/chargen/blender_loops.png" title="">
            </a>
            <figcaption>Blender loops</figcaption>
            </figure>
<p>From looking at Blender’s source code (at <code>uv_seams_from_islands_exec</code>) I believe the way “Seams from Islands” works is that the UVs for each shared edges/loops are compared; if the UVs aren’t in the same locations then we know that those edges are separate in the UV map, and thus we have the border edge of an island. In the pants example above the parts that aren’t selected aren’t actually separated edges. It’s hard to tell from the image, but they are edges of joined faces that are folded over:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/folded_faces.png" title="">
            <img src="/assets/uploads/fugue/chargen/folded_faces.png" title="">
            </a>
            <figcaption>Seam edge vs non-seam edge</figcaption>
            </figure>
<p>This can also be illustrated by using a graph-based approach for detecting seams:</p>
<pre><span class="keyword control import">import</span> <span class="variable">networkx</span> <span class="keyword control">as</span> <span class="variable">nx</span>

<span class="comment"># Same prep as above</span>
<span class="variable">bm</span> <span class="operator">=</span> <span class="variable">bmesh</span><span class="punctuation delimiter">.</span><span class="variable">from_edit_mesh</span><span class="punctuation bracket">(</span><span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">context</span><span class="punctuation delimiter">.</span><span class="variable">active_object</span><span class="punctuation delimiter">.</span><span class="variable">data</span><span class="punctuation bracket">)</span>
<span class="variable">uv_layers</span> <span class="operator">=</span> <span class="variable">bm</span><span class="punctuation delimiter">.</span><span class="variable">loops</span><span class="punctuation delimiter">.</span><span class="variable">layers</span><span class="punctuation delimiter">.</span><span class="variable">uv</span><span class="punctuation delimiter">.</span><span class="variable">verify</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>

<span class="comment"># Collect all edges here</span>
<span class="variable">edges</span> <span class="operator">=</span> <span class="punctuation bracket">[</span><span class="punctuation bracket">]</span>
<span class="keyword control repeat">for</span> <span class="variable">f</span> <span class="keyword operator">in</span> <span class="variable">bm</span><span class="punctuation delimiter">.</span><span class="variable">faces</span><span class="punctuation delimiter">:</span>
    <span class="keyword control repeat">for</span> <span class="variable">l</span> <span class="keyword operator">in</span> <span class="variable">f</span><span class="punctuation delimiter">.</span><span class="variable">loops</span><span class="punctuation delimiter">:</span>
        <span class="variable">a</span> <span class="operator">=</span> <span class="variable">l</span><span class="punctuation bracket">[</span><span class="variable">uv_layers</span><span class="punctuation bracket">]</span><span class="punctuation delimiter">.</span><span class="variable">uv</span>
        <span class="variable">b</span> <span class="operator">=</span> <span class="variable">l</span><span class="punctuation delimiter">.</span><span class="variable">link_loop_next</span><span class="punctuation bracket">[</span><span class="variable">uv_layers</span><span class="punctuation bracket">]</span><span class="punctuation delimiter">.</span><span class="variable">uv</span>
        <span class="variable">edges</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="punctuation bracket">(</span><span class="punctuation bracket">(</span><span class="variable">a</span><span class="punctuation delimiter">.</span><span class="variable">x</span><span class="punctuation delimiter">,</span> <span class="constant numeric integer">1</span> <span class="operator">-</span> <span class="variable">a</span><span class="punctuation delimiter">.</span><span class="variable">y</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">,</span> <span class="punctuation bracket">(</span><span class="variable">b</span><span class="punctuation delimiter">.</span><span class="variable">x</span><span class="punctuation delimiter">,</span> <span class="constant numeric integer">1</span> <span class="operator">-</span> <span class="variable">b</span><span class="punctuation delimiter">.</span><span class="variable">y</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>

<span class="comment"># UVs don&#x27;t have any ids;</span>
<span class="comment"># we need to know when two UVs are actually the same UV.</span>
<span class="comment"># We do this by seeing if two UVs are within some small range;</span>
<span class="comment"># if so we consider them to be the same UV.</span>
<span class="variable">eps</span> <span class="operator">=</span> <span class="constant numeric float">1e-6</span>
<span class="variable">uv_idx</span> <span class="operator">=</span> <span class="punctuation bracket">[</span><span class="punctuation bracket">]</span>
<span class="keyword function">def</span> <span class="variable">find_closest</span><span class="punctuation bracket">(</span><span class="variable">uv</span><span class="punctuation delimiter">:</span> <span class="variable">tuple</span><span class="punctuation bracket">[</span><span class="variable">float</span><span class="punctuation delimiter">,</span> <span class="variable">float</span><span class="punctuation bracket">]</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">:</span>
    <span class="variable">x</span><span class="punctuation delimiter">,</span> <span class="variable">y</span> <span class="operator">=</span> <span class="variable">uv</span>
    <span class="keyword control repeat">for</span> <span class="variable">i</span><span class="punctuation delimiter">,</span> <span class="punctuation bracket">(</span><span class="variable">x_</span><span class="punctuation delimiter">,</span> <span class="variable">y_</span><span class="punctuation bracket">)</span> <span class="keyword operator">in</span> <span class="variable">enumerate</span><span class="punctuation bracket">(</span><span class="variable">uv_idx</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">:</span>
        <span class="variable">x_diff</span> <span class="operator">=</span> <span class="variable">abs</span><span class="punctuation bracket">(</span><span class="variable">x</span> <span class="operator">-</span> <span class="variable">x_</span><span class="punctuation bracket">)</span>
        <span class="variable">y_diff</span> <span class="operator">=</span> <span class="variable">abs</span><span class="punctuation bracket">(</span><span class="variable">y</span> <span class="operator">-</span> <span class="variable">y_</span><span class="punctuation bracket">)</span>
        <span class="keyword control conditional">if</span> <span class="variable">x_diff</span> <span class="operator">&lt;</span> <span class="variable">eps</span> <span class="keyword operator">and</span> <span class="variable">y_diff</span> <span class="operator">&lt;</span><span class="variable">eps</span><span class="punctuation delimiter">:</span>
            <span class="keyword control return">return</span> <span class="variable">i</span>
    <span class="keyword control conditional">else</span><span class="punctuation delimiter">:</span>
        <span class="variable">uv_idx</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="variable">uv</span><span class="punctuation bracket">)</span>
        <span class="keyword control return">return</span> <span class="variable">len</span><span class="punctuation bracket">(</span><span class="variable">uv_idx</span><span class="punctuation bracket">)</span> <span class="operator">-</span> <span class="constant numeric integer">1</span>

<span class="comment"># Reconstruct the UV map geometry</span>
<span class="comment"># as a graph.</span>
<span class="variable">g</span> <span class="operator">=</span> <span class="variable">nx</span><span class="punctuation delimiter">.</span><span class="variable">Graph</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
<span class="keyword control repeat">for</span> <span class="variable">a</span><span class="punctuation delimiter">,</span> <span class="variable">b</span> <span class="keyword operator">in</span> <span class="variable">edges</span><span class="punctuation delimiter">:</span>
    <span class="variable">a_id</span> <span class="operator">=</span> <span class="variable">find_closest</span><span class="punctuation bracket">(</span><span class="variable">a</span><span class="punctuation bracket">)</span>
    <span class="variable">b_id</span> <span class="operator">=</span> <span class="variable">find_closest</span><span class="punctuation bracket">(</span><span class="variable">b</span><span class="punctuation bracket">)</span>

    <span class="comment"># Count how many edges connect</span>
    <span class="comment"># these two UVs</span>
    <span class="keyword control conditional">if</span> <span class="variable">g</span><span class="punctuation delimiter">.</span><span class="variable">has_edge</span><span class="punctuation bracket">(</span><span class="variable">a_id</span><span class="punctuation delimiter">,</span> <span class="variable">b_id</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">:</span>
        <span class="variable">edge</span> <span class="operator">=</span> <span class="variable">g</span><span class="punctuation delimiter">.</span><span class="variable">edges</span><span class="punctuation bracket">[</span><span class="variable">a_id</span><span class="punctuation delimiter">,</span> <span class="variable">b_id</span><span class="punctuation bracket">]</span>
        <span class="variable">edge</span><span class="punctuation bracket">[</span><span class="string">&#x27;count&#x27;</span><span class="punctuation bracket">]</span> <span class="operator">+=</span> <span class="constant numeric integer">1</span>
    <span class="keyword control conditional">else</span><span class="punctuation delimiter">:</span>
        <span class="variable">g</span><span class="punctuation delimiter">.</span><span class="variable">add_edge</span><span class="punctuation bracket">(</span><span class="variable">a_id</span><span class="punctuation delimiter">,</span> <span class="variable">b_id</span><span class="punctuation delimiter">,</span> <span class="variable">count</span><span class="operator">=</span><span class="constant numeric integer">1</span><span class="punctuation bracket">)</span>

<span class="comment"># UVs that are connected by only one edge</span>
<span class="comment"># are island borders</span>
<span class="variable">borders</span> <span class="operator">=</span> <span class="punctuation bracket">[</span><span class="punctuation bracket">]</span>
<span class="keyword control repeat">for</span> <span class="variable">a_id</span><span class="punctuation delimiter">,</span> <span class="variable">b_id</span><span class="punctuation delimiter">,</span> <span class="variable">data</span> <span class="keyword operator">in</span> <span class="variable">g</span><span class="punctuation delimiter">.</span><span class="variable">edges</span><span class="punctuation bracket">(</span><span class="variable">data</span><span class="operator">=</span><span class="constant builtin boolean">True</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">:</span>
    <span class="keyword control conditional">if</span> <span class="variable">data</span><span class="punctuation bracket">[</span><span class="string">&#x27;count&#x27;</span><span class="punctuation bracket">]</span> <span class="operator">==</span> <span class="constant numeric integer">1</span><span class="punctuation delimiter">:</span>
        <span class="variable">borders</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="punctuation bracket">(</span><span class="variable">a_id</span><span class="punctuation delimiter">,</span> <span class="variable">b_id</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>
</pre>
<p>This approach also works on the fact that island borders are separated edges. The general idea is this:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/uv_network.png" title="">
            <img src="/assets/uploads/fugue/chargen/uv_network.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>The connection between UVs <code>C</code> and <code>D</code> is <em>not</em> a border because two edges connect them–edge <code>3</code> and <code>5</code>, belong to the left and right faces respectively. The other connections on the other hand have only one edge, and thus they form the island border.</p>
<p>This nice thing about this approach is it’s easy to identify which UVs belong to which islands. With the “Seams from Islands” approach I had a very crude method: just checking which UVs fall within which island polygons. This unfortunately doesn’t work with overlapping islands because the UVs could be assigned to any of the overlapping islands. With this graph-based approach islands are just the connected components of the graph:</p>
<pre><span class="variable">uv_ids_to_islands</span> <span class="operator">=</span> <span class="punctuation bracket">{</span><span class="punctuation bracket">}</span>
<span class="keyword control repeat">for</span> <span class="variable">island_id</span><span class="punctuation delimiter">,</span> <span class="variable">comp</span> <span class="keyword operator">in</span> <span class="variable">enumerate</span><span class="punctuation bracket">(</span><span class="variable">nx</span><span class="punctuation delimiter">.</span><span class="variable">connected_components</span><span class="punctuation bracket">(</span><span class="variable">g</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">:</span>
    <span class="keyword control repeat">for</span> <span class="variable">id</span> <span class="keyword operator">in</span> <span class="variable">comp</span><span class="punctuation delimiter">:</span>
        <span class="variable">uv_ids_to_islands</span><span class="punctuation bracket">[</span><span class="variable">id</span><span class="punctuation bracket">]</span> <span class="operator">=</span> <span class="variable">island_id</span>
</pre>
<p>However because this is basically the same idea as “Seams from Islands” it suffers from the same issues. The pants UV map would fail in the same way.</p>
<p>The approach I’m using now is less elegant (using graph structures just feels neat) but should work better (I hope):</p>
<pre><span class="keyword control">from</span> <span class="variable">collections</span> <span class="keyword control import">import</span> <span class="variable">defaultdict</span>
<span class="keyword control">from</span> <span class="variable">shapely</span><span class="punctuation delimiter">.</span><span class="variable">ops</span> <span class="keyword control import">import</span> <span class="variable">unary_union</span>
<span class="keyword control">from</span> <span class="variable">shapely</span><span class="punctuation delimiter">.</span><span class="variable">geometry</span> <span class="keyword control import">import</span> <span class="variable">Polygon</span>
<span class="keyword control">from</span> <span class="variable">shapely</span><span class="punctuation delimiter">.</span><span class="variable">validation</span> <span class="keyword control import">import</span> <span class="variable">make_valid</span>

<span class="comment"># Same setup as above</span>
<span class="variable">bm</span> <span class="operator">=</span> <span class="variable">bmesh</span><span class="punctuation delimiter">.</span><span class="variable">from_edit_mesh</span><span class="punctuation bracket">(</span><span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">context</span><span class="punctuation delimiter">.</span><span class="variable">active_object</span><span class="punctuation delimiter">.</span><span class="variable">data</span><span class="punctuation bracket">)</span>
<span class="variable">uv_layers</span> <span class="operator">=</span> <span class="variable">bm</span><span class="punctuation delimiter">.</span><span class="variable">loops</span><span class="punctuation delimiter">.</span><span class="variable">layers</span><span class="punctuation delimiter">.</span><span class="variable">uv</span><span class="punctuation delimiter">.</span><span class="variable">verify</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>

<span class="comment"># Here we collect all edges,</span>
<span class="comment"># but grouped into their parent faces</span>
<span class="variable">faces</span> <span class="operator">=</span> <span class="punctuation bracket">[</span><span class="punctuation bracket">]</span>
<span class="keyword control repeat">for</span> <span class="variable">f</span> <span class="keyword operator">in</span> <span class="variable">bm</span><span class="punctuation delimiter">.</span><span class="variable">faces</span><span class="punctuation delimiter">:</span>
    <span class="variable">face</span> <span class="operator">=</span> <span class="punctuation bracket">[</span><span class="punctuation bracket">]</span>
    <span class="keyword control repeat">for</span> <span class="variable">l</span> <span class="keyword operator">in</span> <span class="variable">f</span><span class="punctuation delimiter">.</span><span class="variable">loops</span><span class="punctuation delimiter">:</span>
        <span class="variable">a</span> <span class="operator">=</span> <span class="variable">l</span><span class="punctuation bracket">[</span><span class="variable">uv_layers</span><span class="punctuation bracket">]</span><span class="punctuation delimiter">.</span><span class="variable">uv</span>
        <span class="variable">b</span> <span class="operator">=</span> <span class="variable">l</span><span class="punctuation delimiter">.</span><span class="variable">link_loop_next</span><span class="punctuation bracket">[</span><span class="variable">uv_layers</span><span class="punctuation bracket">]</span><span class="punctuation delimiter">.</span><span class="variable">uv</span>
        <span class="keyword control conditional">if</span> <span class="keyword operator">not</span> <span class="variable">face</span><span class="punctuation delimiter">:</span>
            <span class="variable">face</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="punctuation bracket">(</span><span class="variable">a</span><span class="punctuation delimiter">.</span><span class="variable">x</span><span class="punctuation delimiter">,</span> <span class="constant numeric integer">1</span> <span class="operator">-</span> <span class="variable">a</span><span class="punctuation delimiter">.</span><span class="variable">y</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>
        <span class="variable">face</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="punctuation bracket">(</span><span class="variable">b</span><span class="punctuation delimiter">.</span><span class="variable">x</span><span class="punctuation delimiter">,</span> <span class="constant numeric integer">1</span> <span class="operator">-</span> <span class="variable">b</span><span class="punctuation delimiter">.</span><span class="variable">y</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>
    <span class="variable">faces</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="variable">Polygon</span><span class="punctuation bracket">(</span><span class="variable">face</span><span class="punctuation bracket">)</span><span class="punctuation bracket">)</span>

<span class="comment"># Group faces into their parent islands</span>
<span class="variable">island_faces</span> <span class="operator">=</span> <span class="variable">defaultdict</span><span class="punctuation bracket">(</span><span class="variable">list</span><span class="punctuation bracket">)</span>
<span class="keyword control repeat">for</span> <span class="variable">face</span> <span class="keyword operator">in</span> <span class="variable">faces</span><span class="punctuation delimiter">:</span>
    <span class="comment"># Since the UVs are all connected,</span>
    <span class="comment"># we can use any UV from the face to identify its parent island</span>
    <span class="variable">uv</span> <span class="operator">=</span> <span class="variable">face</span><span class="punctuation delimiter">.</span><span class="variable">exterior</span><span class="punctuation delimiter">.</span><span class="variable">coords</span><span class="punctuation bracket">[</span><span class="constant numeric integer">0</span><span class="punctuation bracket">]</span>

    <span class="comment"># `find_closest` has same definition as above</span>
    <span class="comment"># and we still use the graph-based approach</span>
    <span class="comment"># for mapping UVs to islands</span>
    <span class="variable">uv_id</span> <span class="operator">=</span> <span class="variable">find_closest</span><span class="punctuation bracket">(</span><span class="variable">uv</span><span class="punctuation bracket">)</span>
    <span class="variable">island_id</span> <span class="operator">=</span> <span class="variable">uv_ids_to_islands</span><span class="punctuation bracket">[</span><span class="variable">uv_id</span><span class="punctuation bracket">]</span>

    <span class="comment"># Fix face geometry as needed</span>
    <span class="keyword control conditional">if</span> <span class="keyword operator">not</span> <span class="variable">face</span><span class="punctuation delimiter">.</span><span class="variable">is_valid</span><span class="punctuation delimiter">:</span>
        <span class="variable">face</span> <span class="operator">=</span> <span class="variable">make_valid</span><span class="punctuation bracket">(</span><span class="variable">face</span><span class="punctuation bracket">)</span>
    <span class="variable">island_faces</span><span class="punctuation bracket">[</span><span class="variable">island_id</span><span class="punctuation bracket">]</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="variable">face</span><span class="punctuation bracket">)</span>

<span class="comment"># Then merge the faces of each island to get</span>
<span class="comment"># the island borders&#x2f;silhouette</span>
<span class="variable">island_shapes</span> <span class="operator">=</span> <span class="punctuation bracket">[</span><span class="punctuation bracket">]</span>
<span class="keyword control repeat">for</span> <span class="variable">island_id</span><span class="punctuation delimiter">,</span> <span class="variable">valid_faces</span> <span class="keyword operator">in</span> <span class="variable">island_faces</span><span class="punctuation delimiter">.</span><span class="variable">items</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span><span class="punctuation delimiter">:</span>
    <span class="variable">merged</span> <span class="operator">=</span> <span class="variable">unary_union</span><span class="punctuation bracket">(</span><span class="variable">valid_faces</span><span class="punctuation bracket">)</span>
    <span class="variable">island_shapes</span><span class="punctuation delimiter">.</span><span class="variable">append</span><span class="punctuation bracket">(</span><span class="variable">merged</span><span class="punctuation bracket">)</span>
</pre>
<p>Here I extract the geometry of every face of the mesh, rather than working with just the edges. I still use the graph-based approach to map faces to islands. Then each island’s faces are merged using <code>shapely</code> and the island’s borders are the exterior of this merged shape.</p>
<p>Here are the results of this approach, with the extracted borders in blue:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/island_extract_result.png" title="">
            <img src="/assets/uploads/fugue/chargen/island_extract_result.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>With the island borders extracted the subsequent steps are a bit easier, which is mainly identifying overlapping islands and merging them into one shape (what I was calling “UV map regions”) and cutting out the matching texture regions.</p>
<p>The other important piece is packing these UV map regions. I’m using <a href="https://github.com/markfink/nest2D"><code>nest2d</code></a>, which is a Python interface to <a href="https://github.com/tamasmeszaros/libnest2d"><code>libnest2d</code></a>, for bin packing. There were a couple challenges here too. I’m actually using <a href="https://github.com/frnsys/nest2D">a fork</a> because the original version bizarrely leaves out a Python API to access the important packing information (translations and rotations of the packed polygons). I also had to expand the Python interface to support some additional <code>libnest2d</code> parameters <a href="https://github.com/tamasmeszaros/libnest2d/issues/49">to avoid packing overlaps</a>. A final adjustment: <code>libnest2d</code> doesn’t support concave shapes so instead of directly using the UV map region polygons I use their convex hulls instead. So the resulting packs won’t be the most space-efficient, but that’s ok.</p>
<p>Here are a couple example results from the script:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/atlas_result.png" title="">
            <img src="/assets/uploads/fugue/chargen/atlas_result.png" title="">
            </a>
            <figcaption>An example result. Original UV map and texture on the left, with the detected islands (blue) and convex hulls (red).</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/brown_shoes.png" title="">
            <img src="/assets/uploads/fugue/chargen/brown_shoes.png" title="">
            </a>
            <figcaption>Another example result. Original UV map and texture on the left.</figcaption>
            </figure>
<p><a href="https://gist.github.com/frnsys/cda159e439e93ab4597ab4569a206479">The full code is available here.</a></p>
<p>The other component of this system is what handles the actual merging of the Blender objects and materials (<a href="https://gist.github.com/frnsys/cda159e439e93ab4597ab4569a206479#file-merge-py"><code>merge.py</code></a> in the code). This was more straightforward: grab the textures for each object’s material (assuming one main material), bin pack them into a single image, and update the UV maps accordingly. Then the packing system described here is applied to the merged object/texture to remove unnecessary image data and the final output is trimmed and/or scaled to be a square texture with dimensions that are powers of 2 (e.g. 512x512, 1024x1024, etc).</p>
<p>The resulting texture for the character I’m working with here:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/chargen_merged_texture.png" title="">
            <img src="/assets/uploads/fugue/chargen/chargen_merged_texture.png" title="">
            </a>
            <figcaption>Resulting texture</figcaption>
            </figure>
<p>There is some weird artifacting going on; notice the noisy speckled texture on parts of the face and one of the hands. I’m not really sure why that’s occurring, but it’s not especially noticeable, so I won’t worry about it for now.</p>
<p>Here we see the draw calls for this character reduced from 4 to 1:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/draw_call_comparison.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/draw_call_comparison.jpg" title="">
            </a>
            <figcaption>Draw call reduction</figcaption>
            </figure>
<p>Of course after all of this effort there had to be more problems🙃. The first was a lot of white/blank texture areas showing up in the character. I had thought that this might be an issue–basically extracted textures have no bleed, so if the UV maps aren’t exactly precise then they might cut into empty parts of the texture. The solution to this was to add a <code>padding</code> parameter that provides a few pixels of buffer around each texture clipping.</p>
<p>Yet even after that there was still one other problem. Though the Blender renders and in-browser GLTF preview look fine there is a weird seam that shows up in Godot:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/godot_texture_problem.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/godot_texture_problem.jpg" title="">
            </a>
            <figcaption>Texture issue in Godot. Note the white seam at the top of his head.</figcaption>
            </figure>
<p>Fortunately this wasn’t too difficult to solve. It was unlikely to be an issue with the exported GLTF itself because the in-browser GLTF preview didn’t have this issue. So it had to be something with Godot. For completeness I’ll go into the details.</p>
<p>When you import an asset into Godot it may process it in some way. For textures this can mean manipulating the images in ways to improve game performance. One such manipulation is the generation of “<a href="https://en.wikipedia.org/wiki/Mipmap">mipmaps</a>”, which are scaled down versions of the texture to run when the object is at a smaller scale. The problem is that these mipmaps mean that the scaled down textures might not quite line up with the object’s UV maps, which causes texturing bleeding (thus the white line in the render above).</p>
<p>The actual modifications to the imported texture are controlled by default import settings you can define for your project:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/godot_import_settings.png" title="">
            <img src="/assets/uploads/fugue/chargen/godot_import_settings.png" title="">
            </a>
            <figcaption>Godot’s default import settings</figcaption>
            </figure>
<p>That’s how it’s supposed to work, at least. <a href="https://github.com/godotengine/godot/issues/45206">These import settings aren’t respected</a> when importing GLTFs, so I do it manually in my preview script:</p>
<pre># Ensure that mipmaps and filter are disabled
# for each material texture.
# This is because mipmaps can cause issues with bleed,
# i.e. blank parts of the texture bleed through to the UV map.
# For flag values see: &lt;https:&#x2f;&#x2f;docs.godotengine.org&#x2f;en&#x2f;stable&#x2f;classes&#x2f;class_texture.html#enum-texture-flags&gt;
for child in Util.find_children_of_type(instance, MeshInstance):
    for i in range(child.mesh.get_surface_count()):
        var mat = child.mesh.surface_get_material(i)
        mat.albedo_texture.flags = 0
</pre>
<p>This works, but then I lose the advantage of mipmaps. There is a clear visual difference between enabling/disabling mipmaps. When turned off the original resolution texture is displayed which can mean showing more detail (I suggest clicking the image to see the full resolution version):</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/mipmaps_compared.png" title="">
            <img src="/assets/uploads/fugue/chargen/mipmaps_compared.png" title="">
            </a>
            <figcaption>Mipmaps on/off compared, with different original texture sizes</figcaption>
            </figure>
<p>Maybe it’s because I’m used to it now, but the mipmaps version looks better to me. It’s a bit softer and the eyes look better (though I think that’s because I maybe have too bright of a white for the eyeballs). I figured if the lower-res mipmaps version looks better I should just use a lower-res texture to begin with. So I tried downscaling the original 512x512 texture to 256x256 and 128x128 and they both look good. The 128x128 one looks the closest to the mipsmap version, but isn’t <em>exactly</em> the same (Godot may use a different downscaling algorithm; I used <a href="http://www.pixeluvo.com/">Pixeluvo</a> to resize and they don’t say what algorithm they use). Most importantly this manually downscaled version doesn’t have the seam/bleed problem that Godot’s version does. One further issue here is that the 128x128 version does lose some detail–the earrings are much, much harder to see there, so that might be an argument for the 256x256 texture.</p>
<hr />
<p>This is all a good example of the unexpected and massive diversions that happen with a project like this. I spent so much time and energy on this that could have been spent on more interesting parts of the game. And it’s totally possible that this all just premature optimization. I haven’t developed a game like this so I don’t have any intuition about what I should be focused on for performance. But I really want to avoid the scenario where I’ve generated all this content for the game and then I have to go back and redo everything because of some bad performance decision I made early on (like ignoring draw calls, poly counts, texture sizes, etc).</p>
<p>I don’t think this level of detail is interesting to anyone except me lol. I mostly chronicled this so I have some documentation to refer to when in 3 months I’ve completely forgotten everything and find another edge case that requires me to re-think the whole system (I hope that doesn’t happen, but you never know), but also because maybe there’s some really simple industry standard approach that I completely missed (though I tried to look for one!).</p>
<p>In the end this was one of those things where you’re dealing with two challenges at once: figuring out the high-level algorithm to solve the abstract problem you’re dealing with and figuring out how to implement it in unfamiliar and at times un-/underdocumented or baffingly-designed APIs/libraries. Never a pleasant experience, but I hope it’s worth it!</p>
<hr />
<p><em>Update @ 12/9/22 14:30</em>: Right after publishing this I realized that I don’t need to simplify the base human geometry, but only the <em>final</em> geometry that will be exported. Simplifying the base human geometry was hard because of the reasons I mentioned <a href="/projects/fugue/19/">in the last post</a>: meeting the constraints of MakeClothes (quads or tris, minimizing poles) and because simplifying the geometry gives MakeHumans fewer vertices to manipulate the human form with, leading to wonky results. What I’m doing now is throwing a <code>Decimate</code> modifier on as the very last step before exporting the model. This not only simplifies the base human but also any clothes that are attached. At this stage MakeHuman has already done its work, so the constraints of quads/tris and poles no longer apply.</p>
<p>For now I’m using <code>Decimate</code> with a ratio of 0.5, cutting about half of the polys:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/reduced_tri_count.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/reduced_tri_count.jpg" title="">
            </a>
            <figcaption>Reduced the poly count for this character from ~3k to ~1.5k.</figcaption>
            </figure>
<p><em>Update @ 12/9/22 22:02</em>: So there was another padding-related bug that was causing textures to overlap after packing them. Basically it came down to the fact that there are three different space systems that are used during the packing process: the UV space (where <code>x</code> and <code>y</code> are both in <code>[0, 1]</code>), the texture space (measured in pixels), and the packing space (which is just a scaled up version of the UV space so that coordinates can be integers). The padding is specified as pixels but I wasn’t properly converting them to the packing space, so I just had to implement the correct conversion.</p>
<p>Here are some images from the debugging process (I thought they looked nice):</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/debug_regions.png" title="">
            <img src="/assets/uploads/fugue/chargen/debug_regions.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/debug_padded_hulls.png" title="">
            <img src="/assets/uploads/fugue/chargen/debug_padded_hulls.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/debug_packed_hulls.png" title="">
            <img src="/assets/uploads/fugue/chargen/debug_packed_hulls.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/debug_uvs.png" title="">
            <img src="/assets/uploads/fugue/chargen/debug_uvs.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 19: Character Generation (Part 2)</title><link>projects/fugue/19</link><description><![CDATA[After much chipping away the character generation system (“”) is mostly complete!
As mentioned in the previous post the character generatio…]]></description><category>projects/fugue</category><pubDate>Fri, 02 Dec 2022 13:09:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>After much chipping away the character generation system (“<code>chargen</code>”) is mostly complete!</p>
<p>As mentioned in <a href="/projects/fugue/18/">the previous post</a> the character generation system is driven by <a href="http://www.makehumancommunity.org/">MakeHuman</a> for the model generation, along with a custom texturing system for generating skin-level details.</p>
<p>This more or less reduces character creation to three distinct production tasks:</p>
<ol>
<li>Creating clothes (and hair)</li>
<li>Creating new texture layers (e.g. tattoos, eyebrows, etc)</li>
<li>Creating animations</li>
</ol>
<p>The process works like this:</p>
<ol>
<li>Generate the skin-level details as a single texture.</li>
<li>Generate the model using MakeHuman</li>
<li>Dress the model using MakeHuman</li>
<li>Retarget and remap animations to the model</li>
<li>Export as a GLTF</li>
<li>Generate preview renders</li>
</ol>
<p>For documentation purposes I’ll go through each part in detail below…but first, some screenshots (see the end for a video demo):</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/chargen_01.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/chargen_01.jpg" title="">
            </a>
            <figcaption>Top-level parameters, randomization, in-game previews, and texture view</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/chargen_02.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/chargen_02.jpg" title="">
            </a>
            <figcaption>Left: color parameters; right: a preview of the resulting GLTF model</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/chargen_03.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/chargen_03.jpg" title="">
            </a>
            <figcaption>Body parameters derived from the top-level parameters, used for MakeHuman</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/chargen_05.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/chargen_05.jpg" title="">
            </a>
            <figcaption>Left: some texture parameters</figcaption>
            </figure>
<h2>Generating the texture</h2>
<p>This texture is composed of different layers to represent different features: there’s a base skintone layer, then additional layers of shading, e.g. some red in the cheeks and other high blood-flow areas, then other features like eyes, eyebrows, facial hair, close-cut hair, tattoos, and accessories/clothing items that don’t need to have separate geometry (e.g. earrings, socks).</p>
<p>These layers are added using different blend modes–e.g. some layers are simply overlaid and others are multiplied–so they mix in better with the base layers.</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/texture_layering.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/texture_layering.jpg" title="">
            </a>
            <figcaption>Texture layering</figcaption>
            </figure>
<p>Some layers are used as masks (rather than being used directly) so that they can be filled in with different colors. For example eyes (irises), hair, and socks. In these cases the texture uses a base color (usually something close to black or a very dark grey) that is used as the “anchor” or “reference” color, and then the image is colorized to maintain the relative changes in color throughout. For example, a mask texture might have the base color <code>#181818</code> but also include blacks and greys that are slightly darker/lighter, and want to change it to a red, say <code>#ff0000</code>. The image will be recolored such that pixels that were <code>#181818</code> become <code>#ff0000</code> and other pixels become a shade of red as well, maintaining the same relative lightness/darkness to the base color.</p>
<p>Generating the base skintone texture was tricky at first. Something that is probably obvious to digital/visual artists but that I had to learn is that solid colors don’t really look good or interesting (unless you’re going all-in on solid colors, like those blocky start-up illustration styles), so the original characters looked kind of bland with their perfectly uniform skintones. Creating a color field with interesting texture and variation is easy enough to do by hand in a digital painting application but took a bit of work to do procedurally. I considered trying to use Perlin noise and its ilk but I don’t have any intuition how to control noise well…so it would have taken me forever to get results I’d be happy with.</p>
<p>Instead the algorithm just roughly emulates how a person would produce such a texture…just using a paintbrush texture, painting a base layer of color, and then varying the color a bit and painting low-opacity random strokes on top:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/test_brush_splatter_0.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/test_brush_splatter_0.jpg" title="">
            </a>
            <figcaption>Color painting output</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/test_brush_splatter_1.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/test_brush_splatter_1.jpg" title="">
            </a>
            <figcaption>Color painting output</figcaption>
            </figure>
<p>I found that using <a href="https://en.wikipedia.org/wiki/CIELAB_color_space">LAB color space</a> provided the best color variations that “vibrate” or “resonate” with the base color (I love the subtle pinks and greens and blues in the examples above).</p>
<p>This approach not only produces nice textures for the base skintone but also for hair.</p>
<p>Creating the other texture layers is straightforward–just paint onto a transparent image, using this reference image to know where things will show up:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/UVReference.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/UVReference.jpg" title="">
            </a>
            <figcaption>UV reference image for texturing</figcaption>
            </figure>
<p>The last bit worth mentioning here is performance/speed. There are a few very slow points in the character generation process and texture generation is one of them…sometimes. The image manipulation is happening in Rust, which is very fast <em>if</em> compiled in release mode. Otherwise it’s on the order of 10x slower. Because I’m still developing this content management tool I’m not often building in release mode since you lose access to the browser dev tools when doing so.</p>
<p><em>Aside on texture sizes</em>: The input texture layers are mostly 2048x2048 (aside from some earlier ones which are 1024x1024). The actual skin texture output is 1024x1024, but I create a downscaled copy at 256x256. This is really small, and pixelation is definitely noticeable in the higher-res viewer but not noticeable in-game, given the size of characters and the downscaling screen shader effect (n.b. the screenshots here are using the 1024x1024 textures, not the 256x256 ones). Again, not really sure that texture size/memory use will be an issue, but I don’t need them to be bigger than this so might as well keep them small.</p>
<h2>Generating the model</h2>
<p>This step is the most straightforward since the bulk of the work is handled by MakeHuman. MakeHuman provides a number of parameters to control the body model, e.g. how much muscle there is in the upper arms, the shape of the face, etc. What I do is take a few higher-level parameters–gender, fat, muscle, height, age, and a few parameters that MakeHuman uses for more racialized features–and translate them into the more fine-grained parameters. These finer parameters are all random but parameterized by the higher-level ones, with the exception of some parameters such as facial parameters, which are totally random.</p>
<p>For example there’s a parameter called <code>arms_{L,R}_lowerarm_muscle_decr_incr</code>. The sampling distribution for this might find most of its density in <code>(-1, 0)</code> if the muscle slider is turned all the way down, and would be in <code>(0, 1)</code> if turned all the way up.</p>
<p>This step also applies the MakeHuman “game engine” rig to the model.</p>
<h2>Dressing the model</h2>
<p>The dressing of the model (applying clothes and hair) is also very straightforward since it’s again handled by MakeHuman. The part that’s more complicated is the production of the actual clothes and hair assets to be used.</p>
<p>This process is tricky in part because I’m just not a very experienced modeler, but the lowish-resolution look is more forgiving of that. The main reason it’s difficult is that MakeHuman/MakeClothes has a couple requirements that can be very hard to satisfy. The mesh must consist either entirely of quads or triangles–no mix allowed. In practice this would not be too bad–you can always convert a mesh entirely to triangles (using Blender’s <code>Triangulate Faces</code>), which as far as I know is what a game engine typically does anyways–were it not for a second MakeHuman/MakeClothes requirement that limits the maximum edges allowed for each vertex. It’s something like 8 edges max for any vertex (called “poles”). Going through and figuring out how to reconstruct your geometry to get rid of these poles is hard…some are easy, but others become weird geometry puzzles.</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/pole.jpg" title="">
            <img src="/assets/uploads/fugue/chargen/pole.jpg" title="">
            </a>
            <figcaption>A pole</figcaption>
            </figure>
<p>I haven’t been able to come up with a good foolproof method to avoid this problem. I try to stick to quads when modeling clothes/hair but sometimes you just forget and end up introducing a triangle or n-gon somewhere. Or I want to reduce the poly count so I use Blender’s <code>Decimate</code> modifier, which works amazing for reducing polys while preserving the general shape, but then introduces triangles and poles.</p>
<p>I did come up with one procedure for removing poles that has so far worked maybe 2/3 of the time, and is fortunately easy to script:</p>
<pre><span class="keyword control import">import</span> <span class="variable">bpy</span>

<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">select_more</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">hide</span><span class="punctuation bracket">(</span><span class="variable">unselected</span><span class="operator">=</span><span class="constant builtin boolean">True</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">select_less</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">delete</span><span class="punctuation bracket">(</span><span class="variable">type</span><span class="operator">=</span><span class="string">&#x27;VERT&#x27;</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">select_all</span><span class="punctuation bracket">(</span><span class="variable">action</span><span class="operator">=</span><span class="string">&#x27;SELECT&#x27;</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">edge_face_add</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">quads_convert_to_tris</span><span class="punctuation bracket">(</span><span class="variable">quad_method</span><span class="operator">=</span><span class="string">&#x27;BEAUTY&#x27;</span><span class="punctuation delimiter">,</span> <span class="variable">ngon_method</span><span class="operator">=</span><span class="string">&#x27;BEAUTY&#x27;</span><span class="punctuation bracket">)</span>
<span class="variable">bpy</span><span class="punctuation delimiter">.</span><span class="variable">ops</span><span class="punctuation delimiter">.</span><span class="variable">mesh</span><span class="punctuation delimiter">.</span><span class="variable">reveal</span><span class="punctuation bracket">(</span><span class="punctuation bracket">)</span>
</pre>
<p>What this does is it deletes the problematic vertex/pole, builds an n-gon face out of its surrounding vertices, and then converts that into triangles. Usually this creates edges that get rid of the pole completely, but it can also just move the problem to a different vertex.</p>
<p>I anticipate spending a lot of time making clothes/hair because that’s probably where the bulk of character variation will come from, so I hope I can figure out a more reliable solution soon.</p>
<p>The last thing to note here is that the grammar system I mentioned in <a href="/projects/fugue/18/">the previous post</a> is also implemented into the tool. Almost all the parameters depicted above can be randomized, including the character’s outfit, which can be randomized using an outfit grammar.</p>
<p>One funny thing is that I spent a bunch of time modeling hair and it’s given me a greater appreciation of the variety of hair styles and how much they change someone’s look. I’m sure it’s obvious to many people but not something I spent much time thinking about. Now I catch myself really studying the silhouettes of people’s hair lol.</p>
<h2>Mapping animations onto the model</h2>
<p>There isn’t a whole lot to say here since I haven’t figured out a animation/mocap process, so I’m just relying on Mixamo for now. The process of retargeting/remapping these animations to the character model is fortunately very easy thanks to a Blender addon called “<a href="https://blendermarket.com/products/auto-rig-pro">Auto-Rig Pro</a>”. I did have to create <a href="MPFB">a custom remap config</a> to go from Mixamo to MakeHuman’s game engine rig though, and it was a bit tricky to make sure that all animations were correctly exported (due to me not understanding how Blender’s actions and NLA editor work).</p>
<p>This step is also a hit for performance. The retargeting/remapping process just takes a lot of time: a few minutes for 3 animations, but this will vary on the keyframe length of each animation. Not sure that I can really do anything about that though.</p>
<h2>Exporting the model to GLTF</h2>
<p>This step is also pretty simple, just exporting the GLTF from Blender. The GLTF format is what Godot uses for importing the model.</p>
<p>The only thing I need to look into here is performance. It takes a ridiculous amount of time to export and absolutely shreds my CPU. I can barely do anything else while it’s exporting. I’m not sure what’s going on as it’s just a fairly low poly model that’s being exported.</p>
<h2>Generating preview renders</h2>
<p>The final step is generating preview renders to see what the model will actually look like. A couple of these renders are done in Blender but they aren’t as useful as the in-game renders, which let me see how the character looks with the game’s lighting conditions and screen shaders. This was also surprisingly easy to setup as Godot provides a convenient way to run the engine headlessly and take screenshots.</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/ingame_preview.webp" title="">
            <img src="/assets/uploads/fugue/chargen/ingame_preview.webp" title="">
            </a>
            <figcaption>In-game preview</figcaption>
            </figure>
<p>I was also able to use the same approach for previewing things in-game directly from Blender:</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/ingame_preview.mp4" title="" />
            <figcaption>Quickly view an in-game preview from Blender</figcaption>
            </figure></p>
<h2>Fears and Steps for the Future</h2>
<p>There’s still more work to be done. I haven’t fully finished integrating characters into Godot, so there may be other things that need to be fixed there. And I don’t have a great intuition about what poly counts I should be going for, so a great anxiety is that my poly counts will be too high and I’ll have to go back and redo the base character mesh and all the clothes/hair meshes. I don’t really anticipate this being a problem because poly count is (what I think is) low across the board and from what I’ve read poly counts are less likely to be bottlenecks nowadays. But you never know with these things…and I could probably safely lower the poly count of the base mesh, so I should probably do that earlier rather than later…</p>
<h2>Update: Lowering the mesh poly count</h2>
<p>After writing this I investigated lowering the poly count for the mesh. The original human mesh is around 3k tris–for reference, the Final Fantasy VIII Kiros model I was using for testing is around 750 tris, which was for the original PlayStation. Individual items of clothing so far ranging from 250-800 tris, though I could probably reduce those a fair amount more. Some of these clothing items delete the parts of the human mesh they cover, so they add less to the overall poly count.</p>
<p>Lowering the poly count was a difficult process: after applying Blender’s <code>Decimate</code> modifier there were several poles (the same issue mentioned above) that took a very, very long time to eliminate, but also because the poly reduction process and subsequent pole-editing messed up parts of the UV map which took awhile to fix (UV map editing in Blender is awful). I had to try and match the original UV map as much as possible or I’d need to re-create all the texture system layers, which I really did not want to do.</p>
<p>But I managed to produce a few lower-poly human meshes. The biggest reduction was down to about 750 tris. This lost too much detail, especially around the face. I tried a less extreme version that was about 1300-1400 tris, which was better, but having fewer vertices reduces the effectiveness of MakeHuman’s parameters though and made some parts too angular. Then I tried another version targeting the <code>Decimate</code> to the hands (which is the most detailed region after the face) and feet (which usually aren’t going to be visible and don’t need much detail), getting things down to about 2k tris while entirely preserving the face and preserving the original UV map as much as possible. A 33% reduction in polys isn’t bad!</p>
<p>In the higher resolution previews the hands are noticeably blockier:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/lowerpoly.png" title="">
            <img src="/assets/uploads/fugue/chargen/lowerpoly.png" title="">
            </a>
            <figcaption>Lower poly in high res</figcaption>
            </figure>
<p>But this is less apparent in-game:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chargen/ingame_preview_lowerpoly.webp" title="">
            <img src="/assets/uploads/fugue/chargen/ingame_preview_lowerpoly.webp" title="">
            </a>
            <figcaption>In-game preview</figcaption>
            </figure>
<p>For all I know this is a premature optimization and ~3k poly character models are fine. In theory if I ever need to switch the base human model I can just do so by batch re-generating all of the characters, but as the game develops it may become more complicated to do that. Hopefully I’ll have a better sense of what poly count works before that.</p>
<p><em>Small update</em>: So something about the reduced poly mesh messes up the vertex mapping to the base MakeHuman mesh, I think. Basically vertices on the face/head are being deleted when vertices in the torso should be deleted. I may need to try a cleaner approach to reducing the poly count, that won’t mess up the underlying geometry as much…e.g. doing it by hand.</p>
<h2>Update: Improving GLTF export times</h2>
<p>The GLTF export times were around 10 minutes with 3 animations, which was way too slow. I was not exporting much–only the renderable/visible objects, which was just the lowish-poly human mesh and clothes. Everything else was hidden. But for some reason (which may be related to <a href="https://github.com/KhronosGroup/glTF-Blender-IO/issues/1078">this issue</a>) the GLTF exporter still processes hidden meshes, even if they aren’t to be included in the final GLTF. So the base MakeHuman mesh, which is pretty detailed, was taking up the bulk of the processing time. After deleting that mesh and some other objects (rather than just hiding them) the export time went down to about a minute. The character generation system does this exporting through a headless Blender script, but when exporting from the Blender UI it takes only ~15-16 seconds. No idea what could be the cause of that discrepancy.</p>
<p>Now the main bottleneck is the retargeting/remapping of animations, but again, I don’t think I can do much to speed that up.</p>
<hr />
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/chargen/video_demo_sm.mp4" title="" />
            <figcaption>Video demo of the tool</figcaption>
            </figure>]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 18: Character Generation</title><link>projects/fugue/18</link><description><![CDATA[The character generation system is starting to come together. There are still a few things to figure out, but I think I have the bulk of it…]]></description><category>projects/fugue</category><pubDate>Fri, 21 Oct 2022 14:29:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>The character generation system is starting to come together. There are still a few things to figure out, but I think I have the bulk of it figured out.</p>
<p>The character generation system is roughly broken down into four sub-problems:</p>
<ol>
<li>Mesh generation: how will the actual geometry of a character be generated?</li>
<li>Texturing: how will the skin-level features (skin tone, eyes, eyebrows, nose, mouth, close-cut hair, facial hair, tattoos, scars, etc) of a character be generated?</li>
<li>Clothing/hair: how will additional geometry, like clothing and hair, be generated and mapped to the human mesh?</li>
<li>Rigging: how will the character’s skeleton be configured?</li>
</ol>
<p>(A fifth sub-problem could be “animation” but <a href="/projects/fugue/16">I’ll handle that separately</a>.)</p>
<p>A good system will encompass these sub-problems and also make it easy to:</p>
<ul>
<li>generate characters according to specific constraints through a single UI (eventually as a tab in <a href="/projects/fugue/18">the CMS</a>)</li>
<li>add or modify clothing, hair, etc</li>
<li>generate a large amount of variation across characters</li>
</ul>
<p>In summary, the whole system should be represented by a single configuration screen, and with a single press of a button I can produce a fully rigged and clothes character model. I’m not quite at that point yet but making good progress.</p>
<p>The system so far is all built around the open source <a href="http://www.makehumancommunity.org/"><code>MakeHuman</code></a>, which makes the whole process much simpler. It provides a way to generate parameterized human meshes that supports the easy adding of components like clothing, and it has an addon for working directly within Blender. <code>MakeHuman</code> works by generating a “base mesh” which then can be used with other meshes (“proxies”) that map to the vertices of the base mesh. When the base mesh is transformed–either through animation or through a variety of different body shape/proportion parameters–these proxies are transformed too. Clothes are proxies, but so are “topologies” which replace the base mesh as the human mesh. This allows me to use a custom lower-poly mesh instead of the higher-resolution default mesh.</p>
<p>So <code>MakeHuman</code> takes care of mesh generation, and it provides a way to attach clothing and hair. The clothing and hair still need to be modeled individually, but this is less daunting a task as I figure I’ll only need to create a relatively small amount of clothing forms that each have several different textures. It may be easier to automate the generation of some of these textures, e.g. color variations. In the end this is not too different than your run-of-the-mill modeling and texturing; there are just a couple of extra steps to ensure that the clothes map on to the human mesh correctly.</p>
<p><code>MakeHuman</code> also generates a rig for the mesh, so that sub-problem may be taken care of too. But because I haven’t figured out the animation process, I don’t know exactly if/how I’ll integrate the auto-generated mesh. For my test characters I’ve just been using Mixamo’s auto-rigger…so for now this one needs more work.</p>
<p>So that leaves texturing, or what I called “skin-level features”. These are features that don’t really have any volume to them, such as tattoos, scars, and undergarments and socks. This isn’t too difficult in theory: you just need to generate an image texture. The approach is to work in layers, and assemble a final texture by sampling/generating different layers for different features. So the bottom-most layer is the skintone, and on top of that you’d paste on layers of underwear, socks, eyes, nose, mouth, etc.</p>
<p><figure>
            <a href="/assets/uploads/fugue/fugue-base-uv.jpg" title="">
            <img src="/assets/uploads/fugue/fugue-base-uv.jpg" title="">
            </a>
            <figcaption>The base skin UV map</figcaption>
            </figure>
<p>The face is of course very important here, and it’s the hardest to get right. I don’t yet have a good way of generating facial features. While the other parts (socks, undergarments, etc) can be generated by hand because they don’t require a ton of variation (e.g. I could probably get away with like 20 different pairs of socks), faces should be unique per character (PCs and NPCs alike). I would rather not have to create all of these by hand.</p>
<p>I’ve had some success using Stable Diffusion to generate faces to work from but it’s not consistent enough to automate (faces may not be head-on and so require some manual adjusting, for example). I think a parameterized generator might make the most sense here, where, for example, facial features are defined by bezier curves with constrained parameter ranges, and each face is just a sample of that parameter space. There could then be a pool of textures (for skin tones, lip color, eye color, etc) that are also sampled from to fill in the details.</p>
<p>For testing I just created the skin-level texture by hand, just so I could place a character into the game and see if it works visually:</p>
<p><figure>
            <a href="/assets/uploads/fugue/test_char.gif" title="">
            <img src="/assets/uploads/fugue/test_char.gif" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>And here is a comparison with the screen effects, without the dithering, and without the resolution downsampling:</p>
<p><figure>
            <a href="/assets/uploads/fugue/test_char__comparison.jpg" title="">
            <img src="/assets/uploads/fugue/test_char__comparison.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>The face definitely needs work but I feel ok–but not thrilled–about everything else. It does feel somewhere between the graphics from the original FF8 and its remaster (except for the face), which is sort of what I was going for. I think I need to sit with it for awhile, see how it feels as the rest of the game’s environments develop, and try different character models, clothing, etc. It’s at least a starting point–I feel a bit reassured that I have <em>some</em> method for generating decent-looking characters, one that could be modified if needed.</p>
<p><figure>
            <a href="/assets/uploads/fugue/ff8_remaster.jpg" title="">
            <img src="/assets/uploads/fugue/ff8_remaster.jpg" title="">
            </a>
            <figcaption>FF8 remaster comparison, from </figcaption>
            </figure></a></p>
<p>On this point: I’m kind of hoping that all the models and characters and so on just kind of work together visually, visually but not expecting that to be the case. I’m trying to design this character generation system so that I can make adjustments to e.g. textures, models and have those adjustments propagate through all existing character models. That gives me more latitude to experiment with the game’s visual aesthetic and makes me feel less like I’m committing to a particular one so early on.</p>
<p>This brings me to the actual generation system–everything up to this point is more about producing the assets that are then mix-and-matched to generate the actual characters. I don’t want to allow for totally random character generation because there are combinations that are atypical or implausible. With clothes, for example, people generally don’t wear a dress and pants at the same time, so I want to prevent this particular outfit from being generated (apologies if you do dress this way regularly). A <a href="https://en.wikipedia.org/wiki/Context-free_grammar">context-free grammar</a> (CFG) makes the most sense to me because it allows you to define set configurations that have variation, thus avoiding these problems of complete randomness.</p>
<p>With a CFG you will essentially define different “outfits”, where each component of the outfit can be drawn from a pre-defined list of options. Say for example I need to generate a lot of road workers. A simple CFG might look like:</p>
<pre>RoadWorker:
    - HardHat
    - TShirt
    - HighVisVest
    - WorkPants
    - WorkBoots
HighVisVest:
    - YellowHighVisVest
    - OrangeHighVisVest
HardHat:
    - YellowHardHat
    - WhiteHardHat
    - HardHatWithLight
HardHatWithLight:
    - WhiteHardHatWithLight
    - YellowHardHatWithLight
TShirt:
    - RedShirt
    - BlueShirt
    - BlackShirt
WorkPants:
    - CarpenterPants
    - Jeans
WorkBoots:
    - BrownWorkBoots
    - BlackWorkBoots
</pre>
<p>A CFG is recursive in the sense that, if I want to create a <code>RoadWorker</code>, the program will see that <code>HardHat</code> itself can be expanded into different options. And then the program will see that one of those options, <code>HardHatWithLight</code>, can also be expanded into more options. So it will do this until it’s got all options, and sample from those.</p>
<p>Another feature to add is the ability to draw from the CFG with some fixed options. Like say I’m generating an audience for a group where everyone has to wear an orange beret; I can fix that option the program would only generate characters in an outfit which is allowed to include an orange beret.</p>
<p>Finally, every time a character is generated with the CFG, the resulting model will be saved with the combination of terms used to generate that character (in the case of a <code>RoadWorker</code> that might be <code>YellowHardHat,BlueShirt,OrangeHighVisVest,...</code>). This makes it easy to “regenerate” or update existing characters if one of the underlying models change. That way I can feel free to tweak the textures and models of clothing and other components without needing to manually update every character that I’ve generated so far.</p>
<p>In the near term this will probably all work via a Python script, but it would be amazing to be able to see changes in a character real-time. So a character might be generated through the CFG, but can be hand-adjusted afterwards, e.g. by swapping out that <code>BlueShirt</code> for a <code>BlackShirt</code>, or, if I go the bezier curve route for face features, by adjusting the eye shape for this character, etc. This might be feasible by calling <code>MakeHuman</code> and <code>Blender</code> via their Python interfaces, rendering the model, and then displaying the rendered image, but it sounds really complicated and janky. I’ll have to think on it some more.</p>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 17: Content Management System</title><link>projects/fugue/17</link><description><![CDATA[It’s been awhile but I have been working on Fugue here and there. The biggest accomplishment is a more cohesive content management system, …]]></description><category>projects/fugue</category><pubDate>Fri, 14 Oct 2022 14:16:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>It’s been awhile but I have been working on <em>Fugue</em> here and there. The biggest accomplishment is a more cohesive content management system, making it easier to keep most game-related content in one place and in a consistent structure. That way I don’t have to worry about misplacing things and I can build more automated processing tools without the whole development process becoming a total mess (I hope).</p>
<p><figure>
            <a href="/assets/uploads/fugue/hundun_01.jpg" title="">
            <img src="/assets/uploads/fugue/hundun_01.jpg" title="">
            </a>
            <figcaption>World Wiki</figcaption>
            </figure>
<p>One of the CMS tools is a simplified wiki for the game world and mechanics. I’m working on copying over all my random scattered notes but this is so much easier to think with already.</p>
<p><figure>
            <a href="/assets/uploads/fugue/hundun_02.jpg" title="">
            <img src="/assets/uploads/fugue/hundun_02.jpg" title="">
            </a>
            <figcaption>World Wiki entry</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/hundun_03.jpg" title="">
            <img src="/assets/uploads/fugue/hundun_03.jpg" title="">
            </a>
            <figcaption>Sequence Editor</figcaption>
            </figure>
<p>I’ve also ported over the <a href="/projects/fugue/14">sequence editor</a>. I’m not 100% certain that I’ll stick with Godot and so I want to be able to write all the action/dialogue sequences in a portable format. This saves sequences as a <code>.seq</code> file (which is really just a JSON file). Godot supports <a href="https://docs.godotengine.org/en/stable/tutorials/plugins/editor/import_plugins.html">import plugins</a> which are able to import custom filetypes into Godot resources. I’m doing the same with items (not pictured here), which as saved as <code>.item</code> (again, just a JSON file).</p>
<p>The actual integration with Godot is very hands-off. I just symlink the relevant CMS folders into my Godot project, and then the importer plugins handle the rest. That way I don’t have to mess around with copying over files, worrying if they’re the latest/correct version, etc. Whatever the CMS shows is what Godot sees.</p>
<p>Having a totally custom sequence editor gives a lot more control than the Godot addon I created. The downside is that validating actors/agents, scene objects, etc is difficult because that data is in Godot scene files (<code>.tscn</code>). These are plaintext but still requires parsing, so I wrote a <code>.tscn</code> parser which will pull out all the relevant entities that might be available to a sequence. I decided to use these extracted entities as <em>suggestions</em> for a sequence, not for validation. I thought that perhaps the workflow would be: write sequences in the CMS and then setup the Godot scene to match it, in which case validation is probably best handled from within Godot.</p>
<p>The rest is less interesting. There’s a visual reference manager, which is really just a fancy image viewer:</p>
<p><figure>
            <a href="/assets/uploads/fugue/hundun_04.jpg" title="">
            <img src="/assets/uploads/fugue/hundun_04.jpg" title="">
            </a>
            <figcaption>Reference Manager</figcaption>
            </figure>
<p>And I’ve ported over <a href="/projects/fugue/14/">the texture manager/editor from before</a>, with some snazzier features, including texture/image synthesis:</p>
<p><figure>
            <a href="/assets/uploads/fugue/hundun_05.jpg" title="">
            <img src="/assets/uploads/fugue/hundun_05.jpg" title="">
            </a>
            <figcaption>Texture Manager</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/hundun_06.jpg" title="">
            <img src="/assets/uploads/fugue/hundun_06.jpg" title="">
            </a>
            <figcaption>Texture Editor</figcaption>
            </figure>
<p>Outside of this CMS tool I’ve been experimenting with character modeling/generation, which is one of the last major (and most intimidating) content production questions (along with <a href="/projects/fugue/16/">character animation</a>–I’m waiting for the next release of <a href="https://github.com/freemocap/freemocap">FreeMoCap</a>, and I’ve kind of accepted that object modeling will just happen by hand). I feel that I’m getting close to a good process. Hopefully I’ll figure it out soon.</p>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 16: Motion Capture Tests</title><link>projects/fugue/16</link><description><![CDATA[.
After a few busy weeks I’ve found a bit of time to continue work on Fugue. One of the last major questions content production, after writ…]]></description><category>projects/fugue</category><pubDate>Fri, 12 Aug 2022 13:23:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p><figure>
            <a href="/assets/uploads/fugue/cmu_mocap_example.png" title="">
            <img src="/assets/uploads/fugue/cmu_mocap_example.png" title="">
            </a>
            <figcaption>An example rendering from the </figcaption>
            </figure></a>.</p>
<p>After a few busy weeks I’ve found a bit of time to continue work on <em>Fugue</em>. One of the last major questions content production, after <a href="https://spaceandtim.es/projects/fugue/14/">writing, textures, and music</a>, is character animation (this still leaves object and character modeling as the other two problem areas). While I believe I can get away with lower-poly models and crunchier photo-textures, I don’t think that’s the case with low-quality animation–it’s too jarring. So I want to figure out a way to produce fairly good, realistic motion on the cheap.</p>
<p>There are a number of deep learning-based projects available for motion capture without a sophisticated tracking setup. Some are even monocular, requiring only one camera. There are some commercial offerings (such as <a href="deepmotion.com">deepmotion.com</a>) but I want to see how far I can get with open source options. I’ll be able to modify those as I need and they’ll be easier to integrated into a more automated process than commercial options.</p>
<p>The open source projects are usually research projects, so they aren’t polished/are somewhat janky and probably don’t generalize very well. And their licenses often restrict usage to non-commercial purposes. For example, <a href="https://github.com/FORTH-ModelBasedTracker/MocapNET">MocapNET</a>, <a href="https://github.com/zju3dv/EasyMocap">EasyMocap</a>, and <a href="https://github.com/facebookresearch/frankmocap">FrankMocap</a> are all non-commercial uses only. I did find <a href="https://github.com/FORTH-ModelBasedTracker/MocapNET">MotioNet</a> which does allow commercial usage (under its BSD-2 license) and requires only one camera, so that was promising.</p>
<p>One alternative to the deep learning approach is to just use existing motion capture data and hope that covers all the animations I’d need. A great resource is the <a href="http://mocap.cs.cmu.edu/motcat.php">CMU Graphics Lab Motion Capture Database</a>, which has generously been <a href="https://sites.google.com/a/cgspeed.com/cgspeed/motion-capture/the-motionbuilder-friendly-bvh-conversion-release-of-cmus-motion-capture-database?authuser=0">converted to <code>.bvh</code></a> by Bruce Hahne for easy usage in Blender. The collection encompasses 2,500 motions and is “free for all uses”. The range of motions is expansive enough (including things like pantomiming a dragon) that it’s possible it will have everything I need.</p>
<p>Still, I wanted to try out the deep learning approaches, in part because I was curious.</p>
<p>One note here is that these models typically output motions as <code>.bvh</code> files. These contain motion instructions addressed to a particular skeleton (where, for example, the left leg bone might be named <code>LeftLeg</code>). I used <a href="https://www.mixamo.com/#/?type=Motion%2CMotionPack">Mixamo</a>’s auto-rigger to rig my character and the resulting skeleton has a different naming system. Fortunately there is a Blender addon, <a href="https://bitbucket.org/Diffeomorphic/retarget_bvh">“BVH Retargeter”</a>, that remaps a <code>.bvh</code> to a differently-named skeleton. It doesn’t include a mapping for Mixamo by default, but I set one up myself (<a href="https://gist.github.com/frnsys/e1eaea896bd01e6388b54e1ebf9782c7">available here</a>, it goes into the <code>known_rigs</code> directory).</p>
<p>On this note, there is also this <a href="https://github.com/DeepMotionEditing/deep-motion-editing">Deep-motion-editing</a> project which has a much more sophisticated retargeter:</p>
<p><figure>
            <a href="/assets/uploads/fugue/deep-motion-editing-retargeting.gif" title="">
            <img src="/assets/uploads/fugue/deep-motion-editing-retargeting.gif" title="">
            </a>
            <figcaption>Deep-motion-editing retargeter</figcaption>
            </figure>
<p>I don’t know yet if I’ll have a need for this, but good to know it’s there!</p>
<p>On to the tests:</p>
<p>I’m using a Kiros Seagill model (from FF8) for these tests.</p>
<p>Even though the MocapNET license is not what I need, I decided to try it anyways:</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/mocapnet-test.mp4" title="" />
            <figcaption>MocapNET test</figcaption>
            </figure>
<p>It looks ok, a little janky and all over the place though. And the hands aren’t animated.</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/motionet-test.mp4" title="" />
            <figcaption>MotioNet</figcaption>
            </figure>
<p>MotioNet looked promising but unfortunately did not have very good output. The output pose is upside-down for some reason (<a href="https://github.com/Shimingyi/MotioNet/issues/46">this is a known issue</a>), which seems like an easy enough fix, but the joint movement is stiff and incorrect.</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/cmumocap-test.mp4" title="" />
            <figcaption>CMU MoCap</figcaption>
            </figure>
<p>The CMU motion looks great of course, as it’s actually captured properly. Again, the only concern here is that it doesn’t have a wide enough range of motions.</p>
<iframe width="560" height="315" style="margin:3em auto;display:block;" src="https://www.youtube-nocookie.com/embed/WW_WpMcbzns" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
<p>The last software I tried is <a href="https://freemocap.org">FreeMoCap</a>, which is still in very early stages of development, but there’s enough to try it out. It was quite a bit more complicated to set up as it works best with multiple cameras (they can still be fairly cheap, e.g. $20-30, webcams), and requires a charuco board for calibration, which I printed off at Kinko’s. That cost me about <span class="math math-inline">30 to get it on poster board, but you can probably make something cheaper with an old cardboard box and printing on large-sized computer paper. In total I spent ~</span>100 on equipment.</p>
<p>The most important thing is to get webcams that work for the size of your recording room, so get your full body in frame for all of them (which may require wide-angle cameras). Then you need to make sure that your charuco board is large enough that its patterns are clear on the webcams–the further you position the webcams, the larger the charuco board you’ll need <em>and</em> the lower the resolution you record at, the larger the charuco board you’ll need. Note that there’s also a resolution/frame-rate trade-off: when running 3 cameras at 1080p I get about 14-15fps, but I needed to run at that size for my charuco board to render clearly. And as another note, the FPS can be bottlenecked if you use a USB hub to run your cameras through (some of the cameras may not even work in that case); I ended up plugging each camera into its own port for best performance.</p>
<p>Getting the program to work was tricky, which wasn’t a surprise given the project is in an alpha state. I had to make <a href="https://github.com/frnsys/freemocap/commit/3036555124feac4c53cc2aff3a11bfd6304c37fe">a few changes</a> to get it to run properly (mainly switching from multithreading to multiprocessing, since the threads were blocked on my system, and manually setting the FPS for my cameras, which for some reason would limit to 5FPS otherwise).</p>
<p>Below is an example of the program’s output. My recording environment is less than ideal (my camera setup was super janky, attached to books or shelves in a haphazard way), but the output looks decent. It’s jittery, and you’ll notice the pose skeleton and camera footage are swapped in the first and last videos. I’m not sure if that’s just a bug with this visualization or if it’s happening deeper in the program, in which case it may be why there’s that jitteriness and the skeleton angle is off.</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/freemocap_demo.mp4" title="" />
            <figcaption>FreeMoCap output</figcaption>
            </figure>
<p>The program can also output Blender files:</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/freemocap_blender_demo.mp4" title="" />
            <figcaption>FreeMoCap Blender output</figcaption>
            </figure>
<p>Here the issues are more apparent: the hands are especially all over the place. But even the limbs are too finicky. The demo video (above) has good limb motion, so maybe my setup is lacking (though the hands are also jittery).</p>
<p>FreeMoCap is a really promising project, but unfortunately it’s at too early of a stage to be consistent and reliable. For now I’ll probably develop the game using the CMU motion data, and then later, when I’m ready and FreeMoCap is likely much more mature I can go through and replace or refine with custom motions. Though at the rate development is going, there’s a good chance that FreeMoCap will be much further along by the time I’m ready to start really working on character animations!</p>
]]></content:encoded></item><item><title>Feeding Food</title><link>etc/feeding_food</link><description><![CDATA[This is a draft (completed in October 2020) of a piece that was never published. I’m posting it here for anyone who might be interested. Th…]]></description><category>etc</category><pubDate>Sat, 25 Jun 2022 23:13:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p><em>This is a draft (completed in October 2020) of a piece that was never published. I’m posting it here for anyone who might be interested. The food system is a massive and important topic, and here I’ve only scratched the surface of one small part of it. Researching and writing this shifted my thinking on many topics–I hope others will also get something from it.</em></p>
<h2>Limit Break</h2>
<p>Nowhere in the world do we see limitless growth. In agriculture, as in the broader natural world, there are nutritional limits that prevent plants and the life that depends on them from growing unbounded. Two limiting nutrients of special importance are nitrogen and phosphorus. Together these form a bottleneck for agricultural systems, with implications not only for food and other agricultural products but also for key features of a post-carbon world, such as bio-based alternatives to fossil fuels and their derivatives and afforestation.</p>
<p>Nitrogen is everywhere, making almost 80% of the air that surrounds us, which is why at first glance its role as a limiter might seem strange. Unlike carbon dioxide, the nitrogen in the air is inaccessible to plants. There are a variety of ways it can be made available to plants, such as through certain “nitrogen-fixing” bacteria or, much less commonly, lightning strikes, but <em>something</em> has to convert nitrogen into its inorganic form (e.g. ammonia) for plants to make use of it<sup class="footnote-reference"><a href="#CagkTS">1</a></sup><sup class="footnote-reference"><a href="#GnLT6F">2</a></sup>.</p>
<p>Phosphorus, more commonly a limiting factor in tropical areas<sup class="footnote-reference"><a href="#WCMLES">3</a></sup>, is not as abundant as nitrogen, circulating through the gradual weathering of rocks.</p>
<p>Though many cultures found ways to better conserve soil nutrients and modestly supplement the nutritional content of soils through manures or legumes (which host nitrogen-fixing bacteria)<sup class="footnote-reference"><a href="#GSSnjs">4</a></sup>, it wasn’t until the 19th century that a series of shifts occurred that effectively broke through these limits: the development of global fertilizer supply chains and the Haber-Bosch process for synthesizing nitrogen fertilizer at scale, named for Fritz Haber (sometimes called “the father of chemical warfare”) who developed the process and Carl Bosch who later improved it. This process is still the basis for essentially all synthetic fertilizer production today. Nowadays the amount of reactive nitrogen and phosphorus circulating is more than double that of the pre-industrial world<sup class="footnote-reference"><a href="#xwNKkI">5</a></sup><sup class="footnote-reference"><a href="#11eLmt">6</a></sup><sup class="footnote-reference"><a href="#a2JdEX">7</a></sup><sup class="footnote-reference"><a href="#Vb5nD3">8</a></sup>.</p>
<p>These developments proliferated over the past century–use rates of nitrogen fertilizer increased over 40 times in the US over this period<sup class="footnote-reference"><a href="#DJbgTR">9</a></sup>–massively increasing global agricultural productivity, tripling agricultural value since 1970 to $2.6 trillion<sup class="footnote-reference"><a href="#ixNtii">10</a></sup>. In the US synthetic fertilizer may be responsible for anywhere from 30 to 60% of yields, and even higher in the tropics<sup class="footnote-reference"><a href="#NOg9Fp">11</a></sup><sup class="footnote-reference"><a href="#b4aLnX">12</a></sup>. One of the most important consequences of the surpassing of these limits has been exponential population growth. Some 40% to half of the world population may owe their existence to the Haber-Bosch process<sup class="footnote-reference"><a href="#GnLT6F">2</a></sup>.</p>
<p>This massive nutritional increase comes at a substantial social and environmental cost and, at least in its current form, is unsustainable. The breaking of these nutrient limits is a major contributor to the breaking of <a href="https://www.stockholmresilience.org/research/planetary-boundaries/planetary-boundaries/about-the-research/the-nine-planetary-boundaries.html">planetary boundaries</a><sup class="footnote-reference"><a href="#MYgqN5">13</a></sup>: a recent paper estimated that almost 50% of global food production violates planetary boundaries, with almost of half to that (25% overall) due nitrogen fertilizer<sup class="footnote-reference"><a href="#bqL_FO">14</a></sup>.</p>
<p>Nitrogen fertilizers are typically applied in excess<sup class="footnote-reference"><a href="#a2JdEX">7</a></sup>; for cereal grain production only about a third of applied nitrogen is actually taken up the crop, amounting to $90 billion of wasted nitrogen<sup class="footnote-reference"><a href="#ny2fVV">15</a></sup>, with some estimates ranging from half<sup class="footnote-reference"><a href="#GnLT6F">2</a></sup> to 80%<sup class="footnote-reference"><a href="#xwNKkI">5</a></sup><sup class="footnote-reference"><a href="#UAunoy">16</a></sup> being wasted across all crops. Similarly, estimates suggest only 15 to 30% of phosphorus is taken up<sup class="footnote-reference"><a href="#S827v1">17</a></sup><sup class="footnote-reference"><a href="#T5XG95">18</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup>. But a lot of this excess fertilizer leaches into water systems<sup class="footnote-reference"><a href="#GnLT6F">2</a></sup><sup class="footnote-reference"><a href="#MYgqN5">13</a></sup><sup class="footnote-reference"><a href="#9MgKCM">19</a></sup><sup class="footnote-reference"><a href="#WHB9x1">20</a></sup><sup class="footnote-reference"><a href="#wmnexr">21</a></sup>, causing eutrophication that has contributed to over 400 marine dead zones<sup class="footnote-reference"><a href="#T5XG95">18</a></sup>. In the Gulf of Mexico such pollution from US agriculture costs the economy an estimated $1.4 billion annually by undermining fishing, recreation, and other marine activity<sup class="footnote-reference"><a href="#WHB9x1">20</a></sup><sup class="footnote-reference"><a href="#805oOe">22</a></sup>. This overflow also contributes to the flourishing of pathogens like the West Nile virus<sup class="footnote-reference"><a href="#kjx5p9">23</a></sup>. Phosphorus fertilizers also contribute to heavy metal content in agriculture<sup class="footnote-reference"><a href="#T5XG95">18</a></sup>, as much as 60% of cadmium in crops and soil<sup class="footnote-reference"><a href="#NIyY3b">24</a></sup><sup class="footnote-reference"><a href="#lftIPW">25</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup>, some of which also makes it to water sources<sup class="footnote-reference"><a href="#lftIPW">25</a></sup>. In the US, agriculture is responsible for 70% of the total nitrogen and phosphorus pollution<sup class="footnote-reference"><a href="#UAunoy">16</a></sup>.</p>
<p>This water pollution also has direct effects on human health, rendering drinking water toxic<sup class="footnote-reference"><a href="#T5XG95">18</a></sup><sup class="footnote-reference"><a href="#DJbgTR">9</a></sup>. Nitrate contamination is linked to many different diseases–blue baby syndrome, some cancers, and more. Violations of EPA limits of nitrate content in drinking water doubled from 650 in 1998 to 1,200 in 2008, while 2 million private wells are above the EPA-recommended standard<sup class="footnote-reference"><a href="#kjx5p9">23</a></sup>. This pollution is expensive to treat and the cost is usually borne by the public. The cost of a treatment facility can be hundreds of millions of dollars; the estimated cost for agriculture’s share of the pollution is around $1.7 billion annually<sup class="footnote-reference"><a href="#kjx5p9">23</a></sup>. The total cost of the environmental and health harm related to agricultural nitrogen in the US has been estimated at $157 billion per year<sup class="footnote-reference"><a href="#kjx5p9">23</a></sup>.</p>
<p>Nitrogen fertilizer overapplication also contributes to agricultural greenhouse gas emissions, especially N2O<sup class="footnote-reference"><a href="#9MgKCM">19</a></sup><sup class="footnote-reference"><a href="#ny2fVV">15</a></sup><sup class="footnote-reference"><a href="#GnLT6F">2</a></sup> which is now the main contributor to ozone depletion<sup class="footnote-reference"><a href="#DJbgTR">9</a></sup>. The amount of these emissions is estimated to increase exponentially with increased fertilizer usage<sup class="footnote-reference"><a href="#Qo4op7">26</a></sup>.</p>
<p>Other concerns regarding over-application–some also with <em>any</em> application of synthetic fertilizers–is their impact on soil health<sup class="footnote-reference"><a href="#GnLT6F">2</a></sup>, such as soil acidification<sup class="footnote-reference"><a href="#cV_sHG">27</a></sup><sup class="footnote-reference"><a href="#WHB9x1">20</a></sup> and net losses in soil nitrogen over time (meaning synthetic fertilizers’ effectiveness decreases over time)<sup class="footnote-reference"><a href="#ny2fVV">15</a></sup><sup class="footnote-reference"><a href="#gUnVx3">28</a></sup>. While disputed, some argue that synthetic fertilizer also inhibits soil’s ability to sequester carbon<sup class="footnote-reference"><a href="#b4aLnX">12</a></sup><sup class="footnote-reference"><a href="#gUnVx3">28</a></sup><sup class="footnote-reference"><a href="#chuDeg">29</a></sup><sup class="footnote-reference"><a href="#c6elUZ">30</a></sup>. What is more accepted is that more traditional techniques of maintaining soil fertility, which are often abandoned with the introduction of synthetic fertilizer<sup class="footnote-reference"><a href="#cV_sHG">27</a></sup>, improve carbon sequestration<sup class="footnote-reference"><a href="#RBM8cS">31</a></sup><sup class="footnote-reference"><a href="#g9P75W">32</a></sup>.</p>
<p>Of course, because the issue here is <em>over</em>-application–for example, China can use 30-50% less fertilizer and maintain the same yields and corn farmers in Minnesota reduced nitrogen use by 21% without a decrease in yield<sup class="footnote-reference"><a href="#WHB9x1">20</a></sup>–then the solution should be straightforward: use less of it. Recommendations to avoid fertilizer overapplication are generally about better management, more context-specific application (e.g. depending on what’s already available in the soil and what the crop requires, carefully measuring out how much to apply)<sup class="footnote-reference"><a href="#Vb5nD3">8</a></sup><sup class="footnote-reference"><a href="#cV_sHG">27</a></sup><sup class="footnote-reference"><a href="#gq-Glv">33</a></sup><sup class="footnote-reference"><a href="#keG87m">34</a></sup><sup class="footnote-reference"><a href="#WHB9x1">20</a></sup><sup class="footnote-reference"><a href="#-9ncyO">35</a></sup><sup class="footnote-reference"><a href="#jJvKtV">36</a></sup><sup class="footnote-reference"><a href="#RIno95">37</a></sup><sup class="footnote-reference"><a href="#xwNKkI">5</a></sup><sup class="footnote-reference"><a href="#GnLT6F">2</a></sup><sup class="footnote-reference"><a href="#kjx5p9">23</a></sup>. This approach has been successful–in Denmark, for example, nitrogen fertilizer application decreased 52% since 1985 following the Nitrate Directive in 1987 which prescribes specific nitrogen management practices<sup class="footnote-reference"><a href="#WHB9x1">20</a></sup>. Similarly, a simple one fertilizer management program based on color charts successfully reduced fertilizer N use by about 25%<sup class="footnote-reference"><a href="#xwNKkI">5</a></sup>. The US has also seen improved nitrogen fertilizer efficiency through education initiatives<sup class="footnote-reference"><a href="#a2JdEX">7</a></sup>, but stronger  regulation regarding synthetic fertilizer application is typically met with fierce resistance from farm lobbying groups<sup class="footnote-reference"><a href="#DJbgTR">9</a></sup>.</p>
<p>Other recommendations look a bit more deeply into why farmers over-apply fertilizer to begin with, especially around risk and incentives. Crop insurance appears to have some effect on fertilizer application rates, though there isn’t consensus around their types and strength. One position argues that crop insurance programs encourage the planting of more input-intensive crops because they are better covered by the insurance, thus increasing fertilizer application; another argues that fertilizer over-application is a risk mitigation strategy (better to over-apply than under-apply and have a small harvest) that becomes redundant with crop insurance<sup class="footnote-reference"><a href="#x-fbwX">38</a></sup><sup class="footnote-reference"><a href="#wmnexr">21</a></sup><sup class="footnote-reference"><a href="#kjx5p9">23</a></sup><sup class="footnote-reference"><a href="#keG87m">34</a></sup><sup class="footnote-reference"><a href="#WHB9x1">20</a></sup><sup class="footnote-reference"><a href="#lStjEq">39</a></sup>. Another position argues that crop insurance encourages agricultural expansion onto lands that are otherwise ill-suited for it–with greater environmental consequences–because crop insurance mitigates the risk of poor yields<sup class="footnote-reference"><a href="#y85DN-">40</a></sup>. Some empirical studies have found that enrollment in crop insurance programs does increase the use of fertilizer<sup class="footnote-reference"><a href="#x-fbwX">38</a></sup><sup class="footnote-reference"><a href="#wjZLBF">41</a></sup> and water<sup class="footnote-reference"><a href="#YDe1no">42</a></sup> and does influence land use and crop choice (e.g. towards more nutrient-demanding crops)<sup class="footnote-reference"><a href="#_OSfgz">43</a></sup>, but others have found no effect or the opposite effect on fertilizer use<sup class="footnote-reference"><a href="#YDe1no">42</a></sup><sup class="footnote-reference"><a href="#wmnexr">21</a></sup>.</p>
<p>In the case of the USDA, applications for assistance require that the applicant demonstrate genuine attempts to increase yields, which generally means applying fertilizers and adopting other conventional agriculture techniques. Such requirements are implemented out of concerns of gaming the system<sup class="footnote-reference"><a href="#25U1QS">44</a></sup>. Because crop insurance is subsidized in the US, taxpayers essentially finance the consequent environmental destruction, while also suffering the consequences of water pollution, depletion of fish stocks, and more<sup class="footnote-reference"><a href="#kjx5p9">23</a></sup><sup class="footnote-reference"><a href="#25U1QS">44</a></sup>.</p>
<p>There are, however, environmental concerns beyond over-application, especially around the production of both nitrogen and phosphorus fertilizers.</p>
<p>Nitrogen fertilizer production–i.e. the Haber-Bosch process–is a large source of agriculture’s environmental footprint<sup class="footnote-reference"><a href="#g9P75W">32</a></sup>. The process requires a hydrocarbon source, usually natural gas, which is combined with nitrogen from the air<sup class="footnote-reference"><a href="#reIkR1">45</a></sup><sup class="footnote-reference"><a href="#BKp6ry">46</a></sup><sup class="footnote-reference"><a href="#Dkw7o3">47</a></sup><sup class="footnote-reference"><a href="#-9ncyO">35</a></sup> and is also used to provide the required heat and energy. The natural gas is supposed to be used up by the process, such that methane emissions are minimal–but the actual emissions have been found to be over 145 times higher than reported<sup class="footnote-reference"><a href="#t83ZrN">48</a></sup>.</p>
<p>The production process also emits significant amounts of CO2<sup class="footnote-reference"><a href="#t83ZrN">48</a></sup>; in 2011, this accounted for 25 million tons of greenhouse gases in the US, some 14% of the emissions for the entire chemical industry<sup class="footnote-reference"><a href="#Dkw7o3">47</a></sup>. A huge chunk of agricultural emissions are actually attributable to fertilizer production due to these CO2 emissions - by one estimate, 30-33%<sup class="footnote-reference"><a href="#Dkw7o3">47</a></sup>.</p>
<p>There are other problems from fertilizer production, such as pollution contributing to an estimated 4,300 premature deaths per year<sup class="footnote-reference"><a href="#DJbgTR">9</a></sup> and substantial energy demands, accounting for an estimated third of total energy used in crop production<sup class="footnote-reference"><a href="#-9ncyO">35</a></sup>.</p>
<p>Phosphorus fertilizers have their own problems. The extraction and processing of the phosphate rock from which the fertilizer is produced come with the typical environmental issues of mining: water and air pollution, land degradation, erosion, toxic and occasionally radioactive byproducts (e.g. phosphogypsum)<sup class="footnote-reference"><a href="#RsiyqM">49</a></sup><sup class="footnote-reference"><a href="#Hxo980">50</a></sup><sup class="footnote-reference"><a href="#Dr6-vN">51</a></sup><sup class="footnote-reference"><a href="#klLI_R">52</a></sup><sup class="footnote-reference"><a href="#wnfN5D">53</a></sup><sup class="footnote-reference"><a href="#T5XG95">18</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup>. However, compared to the nitrogen fertilizer production process, phosphorus fertilizer requires a relatively modest amount of energy (about five times less than nitrogen fertilizer)<sup class="footnote-reference"><a href="#-9ncyO">35</a></sup>. Like nitrogen fertilizer, however, the process is dependent on the fossil fuel industry for inputs, namely sulfuric acid supplied as a byproduct from the oil and gas industry<sup class="footnote-reference"><a href="#11eLmt">6</a></sup>. Both nitrogen and phosphorus fertilizer productions keep agriculture tightly linked to the fossil fuel industries we need to move beyond.</p>
<p>With phosphorus fertilizers one impending issue is phosphate rock’s finite availability. No equivalent to the Haber-Bosch process exists for phosphorus fertilizer<sup class="footnote-reference"><a href="#W76QN-">54</a></sup>, so it will continue to rely mostly on mined phosphate rock–about 96% of mined phosphate rock goes to fertilizer<sup class="footnote-reference"><a href="#9MgKCM">19</a></sup><sup class="footnote-reference"><a href="#8j9-vn">55</a></sup> and this accounts for about 60% of phosphorus applied to agriculture (the rest is from recycled sources like manure)<sup class="footnote-reference"><a href="#8j9-vn">55</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup>.</p>
<p>As with other non-renewable resources, there are concerns around “peak phosphorus”<sup class="footnote-reference"><a href="#-TlPys">56</a></sup><sup class="footnote-reference"><a href="#8j9-vn">55</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup>. This is an inevitability given that it <em>is</em> a finite resource, but of course when this will occur is difficult to predict as anticipating actual reserves of any mineral is hard and estimates change frequently and by large amounts and according to economic and technological circumstances<sup class="footnote-reference"><a href="#NuvFC7">57</a></sup><sup class="footnote-reference"><a href="#-TlPys">56</a></sup><sup class="footnote-reference"><a href="#8j9-vn">55</a></sup><sup class="footnote-reference"><a href="#11eLmt">6</a></sup>. Estimates range from within a couple decades to hundreds of years<sup class="footnote-reference"><a href="#S827v1">17</a></sup><sup class="footnote-reference"><a href="#-TlPys">56</a></sup><sup class="footnote-reference"><a href="#8j9-vn">55</a></sup>.</p>
<p>At present the US is a major producer of phosphate rock, primarily in Florida, but that supply is expected to be 60% depleted by 2030 and completely gone mid-century<sup class="footnote-reference"><a href="#-TlPys">56</a></sup>. China, another major producer, is expected to deplete in the near future as well<sup class="footnote-reference"><a href="#8j9-vn">55</a></sup>.</p>
<h2>The Metabolic Rift</h2>
<p>All of these issues of the present pour out of a deeper history of fertilizer that represents a more fundamental shift in our relationship with nature. This “metabolic rift” is the sundering of agriculture from its local ecological context<sup class="footnote-reference"><a href="#6tcrtR">58</a></sup>, and has at its core exploitation, colonialism, and imperialism<sup class="footnote-reference"><a href="#Dr6-vN">51</a></sup><sup class="footnote-reference"><a href="#1TDaoD">59</a></sup><sup class="footnote-reference"><a href="#F4mkgE">60</a></sup>. The siphoning of fertility from the global periphery into Europe and its colonial descendants was foundational to pushing agricultural productivity beyond the limits of what the land could sustain.</p>
<p>Fertilizer itself was a common practice to maintain soil fertility while keeping it in production<sup class="footnote-reference"><a href="#1TDaoD">59</a></sup> but it took the form of night soil, ashes, bones, and other organic waste that were relatively local, often connecting rural and urban populations through substantial logistics systems<sup class="footnote-reference"><a href="#20dF-y">61</a></sup><sup class="footnote-reference"><a href="#GnLT6F">2</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup>. But such methods could only maintain continuous productivity for so long; nutrient recycling is not perfect<sup class="footnote-reference"><a href="#g9P75W">32</a></sup><sup class="footnote-reference"><a href="#GnLT6F">2</a></sup>, and indeed soil depletion became an issue in industrializing nations as populations grew<sup class="footnote-reference"><a href="#11eLmt">6</a></sup>. Alternative methods such as leaving land fallow or crop rotation did not fit the need for maximizing near-term productivity.</p>
<p>To resolve this dilemma, in the 19th century industrializing nations began sourcing fertilizer from distant places–mainly Peru, but also Chile, Ecuador, and Bolivia, in the form of guano and later nitrates<sup class="footnote-reference"><a href="#1TDaoD">59</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup><sup class="footnote-reference"><a href="#20dF-y">61</a></sup><sup class="footnote-reference"><a href="#F4mkgE">60</a></sup>. This “Guano Age” saw a tremendous transfer of wealth to British business interests that essentially controlled this trade<sup class="footnote-reference"><a href="#F4mkgE">60</a></sup><sup class="footnote-reference"><a href="#20dF-y">61</a></sup> as well as many deaths through horrendous slave-like working conditions of laborers from China and throughout Latin America<sup class="footnote-reference"><a href="#20dF-y">61</a></sup><sup class="footnote-reference"><a href="#n18ElG">62</a></sup><sup class="footnote-reference"><a href="#1TDaoD">59</a></sup> and through multiple wars, including one following Spain’s seizures of guano-rich islands<sup class="footnote-reference"><a href="#F4mkgE">60</a></sup>, a proxy war funded by the British so they could essentially annex Bolivian and Peruvian nitrate and guano producing regions<sup class="footnote-reference"><a href="#F4mkgE">60</a></sup><sup class="footnote-reference"><a href="#20dF-y">61</a></sup>, and a civil war in Chile also funded by the British to prevent Chile’s nationalization of its fertilizer resources<sup class="footnote-reference"><a href="#F4mkgE">60</a></sup> (Gregory Cushman’s <em>Guano and the opening of the Pacific world: a global ecological history</em> provides a detailed look into this history).</p>
<p>Many Pacific Islands also saw their share of dispossession and violence. The US sought to secure its own guano deposits, passing the Guano Islands Act in 1856 to unilaterally allow US entrepreneurs to claim new guano islands as US territories<sup class="footnote-reference"><a href="#20dF-y">61</a></sup>. Under this act 66 islands were claimed as US territory<sup class="footnote-reference"><a href="#1TDaoD">59</a></sup>, with <a href="https://www.doi.gov/oia/islands/acquisitionprocess">at least 8 still under claim or in dispute</a>. Other colonial powers followed suit, compelling a flurry of claims throughout the Pacific<sup class="footnote-reference"><a href="#1TDaoD">59</a></sup> that devastated the islands unfortunate enough to be endowed with rich deposits. Two such islands, Banaba and Nauru, were key locations for the mining of phosphate rock. The Banabans, after years of violence and occupation, were eventually resettled after about 90% of their home island’s surface was left mined and the trees they relied on for food essentially gone<sup class="footnote-reference"><a href="#yK_RmM">63</a></sup><sup class="footnote-reference"><a href="#dYKznm">64</a></sup><sup class="footnote-reference"><a href="#sKI1FQ">65</a></sup><sup class="footnote-reference"><a href="#1TDaoD">59</a></sup>. Nauru didn’t fare much better, with 80% of the surface left looking like a ‘moonscape’<sup class="footnote-reference"><a href="#xSNOuh">66</a></sup><sup class="footnote-reference"><a href="#dYKznm">64</a></sup>. While Nauru achieved independence in 1968, they are left in a state of economic despair<sup class="footnote-reference"><a href="#sKI1FQ">65</a></sup>.</p>
<p>The picture looks very different for the beneficiaries of this extractivism. The vast majority of the nutrient wealth extracted from these regions went to European and descendant countries such as the US, Australia, and New Zealand. European-style agriculture was unviable in Australia and New Zealand until imports of fertilizer derived from the Pacific islands turned each into exporters of meat and wool<sup class="footnote-reference"><a href="#1TDaoD">59</a></sup><sup class="footnote-reference"><a href="#sKI1FQ">65</a></sup> . The fertilizer that resulted allowed the agricultural expansion that supported the industrial development of these countries<sup class="footnote-reference"><a href="#20dF-y">61</a></sup>. Peru, like Nauru and Banaba, saw little benefit. With guano supplies basically depleted, Peru’s farmers became dependent on different nutrient supply chains: imported synthetic fertilizers<sup class="footnote-reference"><a href="#1TDaoD">59</a></sup>.</p>
<p>For nitrogen fertilizer the most egregious cases of this imperialist exploitation came to an end with the Haber-Bosch process<sup class="footnote-reference"><a href="#20dF-y">61</a></sup>, which as discussed above is not without its own significant problems and is still, with its reliance on fossil fuels, fundamentally extractivist. For other nutrients, especially phosphorus, this is not the case. While there Nauru and Banaba’s phosphate resources are basically depleted, North Africa is still a site of phosphate mining to this day. In particular, the case of Morocco and Western Sahara shows a clear through-line from fertilizer’s broader colonial history to its continuation in the present.</p>
<p>Under French control the region supplied phosphate for France’s agriculture<sup class="footnote-reference"><a href="#n18ElG">62</a></sup>. Morocco continues to be the leading exporter of phosphate with the largest reserves<sup class="footnote-reference"><a href="#OHQZsm">67</a></sup>, with estimates of up to 75%-85% of the world total reserves<sup class="footnote-reference"><a href="#dl83iJ">68</a></sup><sup class="footnote-reference"><a href="#W76QN-">54</a></sup><sup class="footnote-reference"><a href="#T5XG95">18</a></sup><sup class="footnote-reference"><a href="#NuvFC7">57</a></sup> . Yet some of these reserves that are counted as Morocco’s are not in fact in Morocco. They are in Western Sahara, what is sometimes called the “world’s last colony”<sup class="footnote-reference"><a href="#GfNxkv">69</a></sup><sup class="footnote-reference"><a href="#iyG-9s">70</a></sup>. Morocco has occupied Western Saharan since 1975<sup class="footnote-reference"><a href="#W76QN-">54</a></sup><sup class="footnote-reference"><a href="#GfNxkv">69</a></sup>, with about 80% of the country under Moroccan rule<sup class="footnote-reference"><a href="#tkba12">71</a></sup> under what is best described as a police state, with violence against and killings of activists, politically-motivated imprisonment, and other human rights violations<sup class="footnote-reference"><a href="#W76QN-">54</a></sup><sup class="footnote-reference"><a href="#0UY7nY">72</a></sup><sup class="footnote-reference"><a href="#B48qp4">73</a></sup><sup class="footnote-reference"><a href="#FWHaCI">74</a></sup><sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#GfNxkv">69</a></sup><sup class="footnote-reference"><a href="#iyG-9s">70</a></sup>, with hundreds of Sahrawi “disappeared” and tortured by the Moroccan government<sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#iyG-9s">70</a></sup>. Most Sahrawi fled to Algeria, where they still mostly live in refugee camps<sup class="footnote-reference"><a href="#W76QN-">54</a></sup><sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#GfNxkv">69</a></sup><sup class="footnote-reference"><a href="#iyG-9s">70</a></sup>.</p>
<p>This occupation is at least in part motivated by Western Sahara’s phosphate reserves, which is of uniquely high quality<sup class="footnote-reference"><a href="#GfNxkv">69</a></sup><sup class="footnote-reference"><a href="#OHQZsm">67</a></sup>. Some 10% of Moroccan phosphate income comes from the Bou Craa mine in Western Sahara<sup class="footnote-reference"><a href="#W76QN-">54</a></sup> and makes up most of the income Morocco gets from the region<sup class="footnote-reference"><a href="#NIyY3b">24</a></sup> (fishing is another big source<sup class="footnote-reference"><a href="#6wmhRi">75</a></sup><sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#iyG-9s">70</a></sup>). As of 2015, Morocco has made an estimated profits of $4.27 billion from Western Saharan phosphate rock mines<sup class="footnote-reference"><a href="#T5XG95">18</a></sup>.</p>
<p>The UN and the International Court of Justice both recognize Western Sahara’s right to self-determination<sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#iyG-9s">70</a></sup>, and no country officially recognizes the Moroccan occupation as legitimate<sup class="footnote-reference"><a href="#NIyY3b">24</a></sup><sup class="footnote-reference"><a href="#GfNxkv">69</a></sup><sup class="footnote-reference"><a href="#OHQZsm">67</a></sup>. Extraction of resources from an occupied territory is clear violation of international law<sup class="footnote-reference"><a href="#GfNxkv">69</a></sup>, which determines that the Sahrawi people should have “permanent sovereignty over [their] resources”<sup class="footnote-reference"><a href="#iyG-9s">70</a></sup>. Yet, over fifty years since this promise of self-determination, as countries continue to import Western Saharan exports<sup class="footnote-reference"><a href="#OHQZsm">67</a></sup><sup class="footnote-reference"><a href="#NIyY3b">24</a></sup>, has not materialized in any meaningful way.</p>
<p>This is probably because several countries have a vested interest in Morocco. Morocco an important ally to US and the recipient of the most US foreign assistance in the region<sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#GfNxkv">69</a></sup>, including financial support and training for the Moroccan military and its operations against the Polisario Front<sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#OHQZsm">67</a></sup>, the Sahrawi nationalist movement. The US also helped plan the initial Moroccan invasion of Western Sahara; Kissinger feared communist activity in the area<sup class="footnote-reference"><a href="#tkba12">71</a></sup><sup class="footnote-reference"><a href="#OHQZsm">67</a></sup>. Morocco has suggested using its phosphate production as a lever for protecting its claim to Western Sahara–to pressure Russia, for example<sup class="footnote-reference"><a href="#NIyY3b">24</a></sup>. In 1985, India recognized the independent Sahrawi state, the Sahrawi Arab Democratic Republic (SADR), but withdrew recognition in 2000 when they established a joint venture with the Morocco phosphate industry<sup class="footnote-reference"><a href="#GfNxkv">69</a></sup>.</p>
<p>Fertilizer production elsewhere also depends on phosphate exported from the area. 50% of the Bou Craa mine’s output supplies fertilizer producers in North America, though in 2018 Canada-based Nutrien, the major North American importer, stopped accepting imports from the Bou Craa mine<sup class="footnote-reference"><a href="#NIyY3b">24</a></sup>. Other major importing countries are India, New Zealand, and China<sup class="footnote-reference"><a href="#NIyY3b">24</a></sup>.  There have been some recent victories, however. In 2017, the Sahrawi Arab Democratic Republic successfully asserted a claim to a cargo of Bou Craa phosphate rock which was sold to New Zealand-based Ballance Agri-Nutrients<sup class="footnote-reference"><a href="#NIyY3b">24</a></sup>.</p>
<p>As phosphate rock supplies dwindle elsewhere, production from places like Morocco become even more important. Some projections say that Morocco’s market share could increase to 80-90% by 2030<sup class="footnote-reference"><a href="#T5XG95">18</a></sup><sup class="footnote-reference"><a href="#8j9-vn">55</a></sup>, effectively giving Morocco monopoly over the global phosphate market and a greater investment in maintaining control of Western Saharan deposits.</p>
<p>From all this it’s clear that the current use of synthetic and non-renewable fertilizers is unsustainable. Yet at the start of the millennium Vaclav Smil concluded that we are fated, at least for the next century, to depend on Haber-Bosch<sup class="footnote-reference"><a href="#GnLT6F">2</a></sup>, and presumably the system of agriculture that is built on it. Have things changed in the intervening decades? Do we have better options now?</p>
<p>There are not many options for substituting phosphate rock (for phosphorus fertilizers the main approaches are using less or exploiting excess accumulated “legacy” phosphorus<sup class="footnote-reference"><a href="#NWY5MW">76</a></sup>), so the focus here will be on nitrogen fertilizers. The main options can be roughly grouped into two categories. There are those which move away from synthetic inputs towards more “natural” approaches, such as organic farming systems, and those which more or less stick to the industrial-chemical model but substitute Haber-Bosch for different processes. Both of these feature into utopian visions of future food systems.</p>
<h2>Fertilizers By Other Names</h2>
<h3>Natural Factories? Organic Systems</h3>
<p>As alluded to above, the major differentiator of agricultural systems’ impacts is nutrient management and the nutrient bottleneck<sup class="footnote-reference"><a href="#MYgqN5">13</a></sup><sup class="footnote-reference"><a href="#9EDruS">77</a></sup><sup class="footnote-reference"><a href="#g9P75W">32</a></sup><sup class="footnote-reference"><a href="#NvBqiH">78</a></sup><sup class="footnote-reference"><a href="#tRoVq1">79</a></sup><sup class="footnote-reference"><a href="#GnLT6F">2</a></sup><sup class="footnote-reference"><a href="#1TDaoD">59</a></sup><sup class="footnote-reference"><a href="#WCMLES">3</a></sup>. Organic systems forgo synthetic fertilizers and other synthetic chemical inputs (though there are circumstances where some may be allowed). Beyond that there can be quite a lot of variety among specific organic systems. More traditional techniques such as intercropping can be used, but aren’t required for the organic label to apply<sup class="footnote-reference"><a href="#9EDruS">77</a></sup>.</p>
<p>In lieu of synthetic fertilizers, other fertilizers like manure are used. These can be less consistent than synthetic fertilizers, as they can have a lot of variety in nutritional composition<sup class="footnote-reference"><a href="#k-cu1b">80</a></sup> and also require additional microbial action before the nutrients are available to the plants (in synthetic fertilizers they’re immediately available, for better or worse)<sup class="footnote-reference"><a href="#-9ncyO">35</a></sup><sup class="footnote-reference"><a href="#NvBqiH">78</a></sup>. But, in addition to the lower environmental footprint, they have other advantages over synthetic fertilizers. Whereas synthetic fertilizers can lower the pest resistance of plants–thus requiring pesticides<sup class="footnote-reference"><a href="#qmR1cA">81</a></sup><sup class="footnote-reference"><a href="#rXNEJ9">82</a></sup>–organic fertilizers tend not to have this problem<sup class="footnote-reference"><a href="#eYEaIk">83</a></sup><sup class="footnote-reference"><a href="#Gqa5At">84</a></sup>. They may also better contribute to soil carbon sequestration<sup class="footnote-reference"><a href="#RBM8cS">31</a></sup><sup class="footnote-reference"><a href="#MYgqN5">13</a></sup> and improve soil quality in other ways<sup class="footnote-reference"><a href="#JmE9nH">85</a></sup>.</p>
<p>The benefits of organic fertilizers are somewhat tempered when taking into account the impacts of collection and transportation. A farm using organic fertilizer produced on-site is going to require less energy than one that ships organic fertilizer from some distant elsewhere. The reduced nutritional density of organic fertilizers also means that transport energy expenditure on a nutritional basis can be higher as well. But in general because no energy-intensive production process is required, the energy requirements are still substantially less than synthetic fertilizers<sup class="footnote-reference"><a href="#-9ncyO">35</a></sup>.</p>
<p>The debate around the viability of wholesale replacement of conventional agriculture with organic systems inevitably ends up on the problem of the “yield gap”–that is, the difficulty organic systems have of matching the productivity of conventional systems.</p>
<p>Comparing organic and conventional agriculture systems is complicated. There are so many other context-specific factors that influence their relative performance, such as the particular crop, the growing environment, water availability, labor costs, and so on, and these factors may be related in zero-sum ways that by now are familiar: yield increases as N fertilizer use increases, but at cost of water pollution<sup class="footnote-reference"><a href="#zAcRDv">86</a></sup><sup class="footnote-reference"><a href="#6Vr0i5">87</a></sup><sup class="footnote-reference"><a href="#WCMLES">3</a></sup>. Comparisons may use a variety of crop specifically bred to maximize productivity under conventional systems, at the expense of traits which make them more productive under organic systems<sup class="footnote-reference"><a href="#9EDruS">77</a></sup><sup class="footnote-reference"><a href="#g9P75W">32</a></sup>. Comparisons can be further complicated by histories of colonialism and displacement, where the highest-quality land is captured by large-scale operations that also happen to utilize industrial agriculture techniques, thus further contributing to higher yields. Larger gaps are found when cereal crops are compared, but this might be because Green Revolution technologies have focused on improving cereal yields in particular<sup class="footnote-reference"><a href="#9EDruS">77</a></sup>. This is part of a larger trend: agricultural research largely focuses on techniques and technologies applicable in conventional systems, whereas organic and sustainable techniques are relatively underfunded<sup class="footnote-reference"><a href="#11eLmt">6</a></sup>. The yield gap could be closed further with more research and funding.</p>
<p>One meta-analysis over several hundred agricultural systems–biased towards Western agricultural systems, including the most industrialized systems–concluded that organic systems fall short against conventional systems when compared on a yield basis; i.e. organic systems require more land, result in more eutrophication, and have similar greenhouse gas emissions per unit of food produced<sup class="footnote-reference"><a href="#MYgqN5">13</a></sup><sup class="footnote-reference"><a href="#g9P75W">32</a></sup><sup class="footnote-reference"><a href="#A88JZE">88</a></sup>. The yield gap ranged from a concerning 50% to a more modest ~90% of conventional output<sup class="footnote-reference"><a href="#g9P75W">32</a></sup><sup class="footnote-reference"><a href="#9EDruS">77</a></sup>. Use of well-known techniques like cover cropping and intercropping can further close the gap<sup class="footnote-reference"><a href="#MYgqN5">13</a></sup><sup class="footnote-reference"><a href="#9EDruS">77</a></sup><sup class="footnote-reference"><a href="#k-cu1b">80</a></sup>, but the gap could also widen under the effects of climate change<sup class="footnote-reference"><a href="#A88JZE">88</a></sup>.</p>
<p>When this yield gap is taken into account, many of the environmental benefits of organic agriculture are severely reduced to the point where conventional agriculture looks <em>more</em> environmentally friendly. The difference is usually attributed to the fact that organic methods require much more land to achieve the same output<sup class="footnote-reference"><a href="#A88JZE">88</a></sup>. Thus, for example, benefits in soil carbon sequestration are offset by the increase in deforestation from expansion of agricultural lands<sup class="footnote-reference"><a href="#VRkTI1">89</a></sup><sup class="footnote-reference"><a href="#MYgqN5">13</a></sup><sup class="footnote-reference"><a href="#6Vr0i5">87</a></sup>. These comparisons, however, use life-cycle assessments (LCA) that are often biased towards the conventional conception of agriculture–that is, focused on agricultural outputs as products–failing to account for the very different conception from organic and other alternative forms that prioritize ecosystem health and have longer-term outlooks. For example, the effects of pesticides, though a key difference between organic and intensive systems, is often not considered<sup class="footnote-reference"><a href="#XqfIyA">90</a></sup>. Land degradation is also generally not included in these assessments<sup class="footnote-reference"><a href="#XqfIyA">90</a></sup>. On a long enough time scale the land degradation resulting from conventional agriculture undermines agricultural productivity (thus lowering these efficiency benefits from the LCA perspective)<sup class="footnote-reference"><a href="#chuDeg">29</a></sup>. We might also consider that, though perhaps industrial agriculture theoretically has lower land use requirements, the political economy of industrial agriculture is such that it will expand regardless of this land-use efficiency. Organic agriculture, as co-opted by existing agribusiness, is not itself necessarily immune to this.</p>
<p>Such results by no means indicate that conventional agriculture is “sustainable” (especially considering its dependency on finite resources such as phosphate rock) or that it’s “low-impact” (still requiring more energy than organic and with human health consequences from pesticides, water pollution, and so on)<sup class="footnote-reference"><a href="#MYgqN5">13</a></sup>. In any case, the prospect that industrial agriculture, which drives all the issues described above, is somehow <em>better</em> for the environment is a troubling if counterintuitive finding. Are there other newer approaches that resolve this dilemma? Ones that are both high-yielding <em>and</em> less harmful?</p>
<h3>Take It Inside: Indoor Systems</h3>
<p>One common proposal for improving agriculture–in terms of both yields and impacts–is to challenge its relationship to land. This set of agricultural systems fit neatly into narratives of high-tech progress, including hydroponics, aeroponics, aquaponics, and vertical farming. Hydroponics and aeroponics are two prevailing soil-less growing techniques, in which plants are grown out of water (in hydroponics and aquaponics) or nothing at all (aeroponics), and vertical farming can operate on either. These roughly all fall under the umbrella of indoor farming techniques (they don’t <em>need</em> to be indoor, but they almost always are), which also encompasses more “traditional” greenhouse approaches, but has a more potent contemporary imaginary in the form of extremely high yield per acre operations on otherwise non-arable land, with tightly-controlled environments and factory-like efficiency (some of these methods are grouped under PFALs: “plant factories with artificial lighting”<sup class="footnote-reference"><a href="#h3rK4I">91</a></sup> or just “plant factories” as artificial lighting is usually a given).</p>
<p>Within the -ponic techniques is substantial variety: the exact method can vary (hydroponic, for example, includes “deep water culture” and “nutrient film technique” among others), as can specifics of the configuration (though these techniques are usually associated with artificial lighting, they can also use sunlight), and growing environment (higher energy requirements, for example, in a colder climate)<sup class="footnote-reference"><a href="#niudWK">92</a></sup><sup class="footnote-reference"><a href="#MYgqN5">13</a></sup>, and the specific crop grown, so generalizations can be a little tricky. But there is enough in common across these approaches that some comparisons are possible.</p>
<p>In terms of yields, hydroponic systems can have higher yields than conventional open-field systems<sup class="footnote-reference"><a href="#h86-LB">93</a></sup><sup class="footnote-reference"><a href="#UAunoy">16</a></sup>. In the context of urban agriculture, a substantial amount of a city’s food demand can be met with local rooftop farms: for example an estimated 77% of Bologna’s food demand is met in this way<sup class="footnote-reference"><a href="#p7HtiI">94</a></sup>. A recent study on urban horticulture in the UK (Sheffield) suggests that the expansion of rooftop farms could help meet a substantial amount of the city’s fruit and vegetable needs<sup class="footnote-reference"><a href="#rv81w9">95</a></sup>.</p>
<p>With respect to fertilizer’s environmental impacts, these configurations feature closed water systems, meaning that water is used more effectively and recycled. This reduces both water usage and nutrient runoff and improves nutrient efficiency compared to conventional systems<sup class="footnote-reference"><a href="#h86-LB">93</a></sup><sup class="footnote-reference"><a href="#asKMyE">96</a></sup><sup class="footnote-reference"><a href="#2mmDMi">97</a></sup><sup class="footnote-reference"><a href="#UAunoy">16</a></sup><sup class="footnote-reference"><a href="#MUqB6Z">98</a></sup><sup class="footnote-reference"><a href="#SVy7lA">99</a></sup><sup class="footnote-reference"><a href="#bg_3yV">100</a></sup><sup class="footnote-reference"><a href="#h3rK4I">91</a></sup>. However, there is still potential for mismanagement and downstream pollution, as salt accumulation in the circulating nutrient solution still results in wastewater that must be properly disposed of<sup class="footnote-reference"><a href="#niudWK">92</a></sup><sup class="footnote-reference"><a href="#p7HtiI">94</a></sup>.</p>
<p>A closed system can be more self-sustaining in other ways, such as using biomass waste to generate biogas to heat the greenhouse or using anaerobic digestion to produce fertilizer on-site<sup class="footnote-reference"><a href="#niudWK">92</a></sup>. Aquaponics generally avoids the use of synthetic fertilizers because fish waste provides nutrients<sup class="footnote-reference"><a href="#MUqB6Z">98</a></sup><sup class="footnote-reference"><a href="#0fy2T7">101</a></sup><sup class="footnote-reference"><a href="#UAunoy">16</a></sup>, though this does not necessarily mean a complete independence from synthetic fertilizers: fish feed is still an external input, and some setups may require nutritional supplements<sup class="footnote-reference"><a href="#UAunoy">16</a></sup>.</p>
<p>Advocates of these systems claim they don’t require pesticides, but indoor livestock farming was pitched on similar promises that haven’t panned out<sup class="footnote-reference"><a href="#N9vj7r">102</a></sup>. Avoiding pesticide use is even more crucial when these farms are in cities<sup class="footnote-reference"><a href="#p7HtiI">94</a></sup>, so this claim warrants even more scrutiny than in other contexts.</p>
<p>These systems can have lower emissions<sup class="footnote-reference"><a href="#2mmDMi">97</a></sup><sup class="footnote-reference"><a href="#h86-LB">93</a></sup>, with most emissions coming from the facility structure (steel and concrete)<sup class="footnote-reference"><a href="#2mmDMi">97</a></sup><sup class="footnote-reference"><a href="#h3rK4I">91</a></sup>, other fixed infrastructure (e.g. pipes)<sup class="footnote-reference"><a href="#SVy7lA">99</a></sup><sup class="footnote-reference"><a href="#h86-LB">93</a></sup><sup class="footnote-reference"><a href="#p7HtiI">94</a></sup><sup class="footnote-reference"><a href="#2mmDMi">97</a></sup>, and energy use<sup class="footnote-reference"><a href="#bg_3yV">100</a></sup><sup class="footnote-reference"><a href="#DWzyiM">103</a></sup>, though this varies with energy mix. One way to reduce emissions and other impacts from the facility structure is to re-use existing buildings, though this comes with penalties as the buildings are not tailored specifically for indoor agriculture<sup class="footnote-reference"><a href="#p7HtiI">94</a></sup><sup class="footnote-reference"><a href="#bg_3yV">100</a></sup>.</p>
<p>Perhaps one of the most lauded benefits is versatility in location–indoor methods don’t require arable land<sup class="footnote-reference"><a href="#DWzyiM">103</a></sup>. Indeed, they can require substantially less land even when considering the land use for energy sources. One paper estimates 1:3 ratio of greenhouse area to solar panel area and assumes “a conversion efficiency of 14% and an average daily solar radiation value of 6.5 kWh per square meter per year”<sup class="footnote-reference"><a href="#6_E3PQ">104</a></sup>. Using sunlight rather than artificial lighting is even better–one could imagine reclaiming the top floors of abandoned buildings to augment local food production.</p>
<p>From a financial perspective, these indoor systems tend to have high capital costs<sup class="footnote-reference"><a href="#DWzyiM">103</a></sup><sup class="footnote-reference"><a href="#Q6OKTn">105</a></sup><sup class="footnote-reference"><a href="#MUqB6Z">98</a></sup><sup class="footnote-reference"><a href="#7r2zQD">106</a></sup><sup class="footnote-reference"><a href="#6_E3PQ">104</a></sup>. This includes not only equipment costs, but also the land itself, which in urban centers are expensive compared to rural land, and operating costs<sup class="footnote-reference"><a href="#7r2zQD">106</a></sup>–you pay for what is otherwise provided for free, e.g. sunlight. They tend to grow only leafy green and herbs for business model viability<sup class="footnote-reference"><a href="#Q6OKTn">105</a></sup><sup class="footnote-reference"><a href="#N9vj7r">102</a></sup>, especially because conventional agriculture can still produce the same food for much more cheaply.</p>
<p>Even though the arability of the farm site itself is less important, other geographical aspects still are. For example, where water is particularly expensive (e.g. in Egypt where deep wells must be dug and maintained<sup class="footnote-reference"><a href="#MUqB6Z">98</a></sup>), the cost of starting an aquaponics farm is still quite expensive<sup class="footnote-reference"><a href="#MUqB6Z">98</a></sup>. Of course, there are situations where the high cost may make sense if it’s not possible to grow anything otherwise and other land uses don’t make sense<sup class="footnote-reference"><a href="#7r2zQD">106</a></sup><sup class="footnote-reference"><a href="#6_E3PQ">104</a></sup>.</p>
<p>The climate of the site is another important factor. Hydroponics systems can have tremendously more energy requirements compared to conventional agriculture, varying a lot by climate (cooler climates require more heating, for example), which can be disproportionate to yield increases<sup class="footnote-reference"><a href="#6_E3PQ">104</a></sup><sup class="footnote-reference"><a href="#MYgqN5">13</a></sup><sup class="footnote-reference"><a href="#NzY5M2">107</a></sup><sup class="footnote-reference"><a href="#SVy7lA">99</a></sup><sup class="footnote-reference"><a href="#niudWK">92</a></sup><sup class="footnote-reference"><a href="#UAunoy">16</a></sup>. Lighting is the other big energy factor, but climate control is the cause for most of the variation between hydroponic systems<sup class="footnote-reference"><a href="#bg_3yV">100</a></sup><sup class="footnote-reference"><a href="#6_E3PQ">104</a></sup><sup class="footnote-reference"><a href="#p7HtiI">94</a></sup><sup class="footnote-reference"><a href="#DWzyiM">103</a></sup><sup class="footnote-reference"><a href="#UAunoy">16</a></sup>. If the system is such that it has exposure to natural light (e.g. rooftop gardens), then the energy demand is of course further reduced.</p>
<p>In urban environments, these systems can have several additional benefits, depending on how tightly they’re integrated with existing urban processes<sup class="footnote-reference"><a href="#DWzyiM">103</a></sup><sup class="footnote-reference"><a href="#niudWK">92</a></sup><sup class="footnote-reference"><a href="#bg_3yV">100</a></sup><sup class="footnote-reference"><a href="#h3rK4I">91</a></sup>. The proximity to consumers can reduce impacts from packaging and transport<sup class="footnote-reference"><a href="#p7HtiI">94</a></sup><sup class="footnote-reference"><a href="#h3rK4I">91</a></sup>, as well as minimizing food loss as well<sup class="footnote-reference"><a href="#p7HtiI">94</a></sup><sup class="footnote-reference"><a href="#DWzyiM">103</a></sup>. Integration with rainwater harvesting systems can reduce draw on city water supplies<sup class="footnote-reference"><a href="#p7HtiI">94</a></sup><sup class="footnote-reference"><a href="#UAunoy">16</a></sup>, and wastewater systems can potentially be developed as nutrient solutions, rather than relying on synthetic fertilizers<sup class="footnote-reference"><a href="#niudWK">92</a></sup>. This could reduce the energy used in wastewater treatment, as the nutrients currently processed out to avoid eutrophication can be used to feed plants instead<sup class="footnote-reference"><a href="#CCu0Y4">108</a></sup>.</p>
<p>But the fact that indoor methods don’t require arable land is a little deceiving. Like conventional agriculture, arability still must be “imported” via inputs like synthetic fertilizers, so in some respects environmental impacts are merely dislocated from the site of production rather than altogether eliminated. Indoor methods are generally not designed to use organic fertilizers, as organic fertilizers are less consistent, less nutritionally dense, and often require some kind of microbial action to make the nutrients available to the plant (the exception here is aquaponics, which is designed around fish waste as fertilizer). For indoor systems, fertilizer production is still the major contributor to eutrophication<sup class="footnote-reference"><a href="#p7HtiI">94</a></sup><sup class="footnote-reference"><a href="#h86-LB">93</a></sup><sup class="footnote-reference"><a href="#2mmDMi">97</a></sup><sup class="footnote-reference"><a href="#DWzyiM">103</a></sup>. Even though less of this occurs at the site of use, plenty still occurs along the production and distribution chain.</p>
<p>So while these indoor approaches appear to have many benefits and may have a role to play in food production for a limited set of contexts<sup class="footnote-reference"><a href="#NzY5M2">107</a></sup> (where energy costs are favorable, renewable energy sources are used, the high capital requirements are manageable, and to supplement the diets of land-scarce urban centers), but we shouldn’t expect them to replace agriculture wholesale. And they do not necessarily lend themselves to socially-desirable models of production. One could imagine a near future in which insolvent smallholder farms on already marginal lands are displaced for investors to build towering vertical farms in their place.</p>
<p>With regards to fertilizer, they’re still held back by many of the problems with synthetic fertilizers–especially their production. Are we stuck with the Haber-Bosch process? Is there a cleaner way of producing them?</p>
<h3>Other Routes to Nitrogen</h3>
<p>Though the Haber-Bosch process is the dominant way of producing nitrogen fertilizer, there are a variety of potential alternatives<sup class="footnote-reference"><a href="#Njg3MG">109</a></sup><sup class="footnote-reference"><a href="#3TO-Xf">110</a></sup>. These alternatives usually focus on Haber-Bosch’s use of fossil feedstock and high energy requirements, stemming from its need for very high temperatures (300-500C) and pressures (200-300atm)<sup class="footnote-reference"><a href="#jJeN-d">111</a></sup>–“the single most energy-guzzling element of farming”<sup class="footnote-reference"><a href="#7uvLUI">112</a></sup>. These intense demands contrast to the microbes that fix nitrogen under far less extreme temperatures and pressures due to nitrogenase enzymes<sup class="footnote-reference"><a href="#jJeN-d">111</a></sup>.</p>
<p>Naturally, the promise of these nitrogenase enzymes has attracted research interest. One direction is focused on producing nitrogen fertilizer with solar power, at room temperature and normal pressure using these enzymes <sup class="footnote-reference"><a href="#7uvLUI">112</a></sup><sup class="footnote-reference"><a href="#ZDdmZm">113</a></sup>, though at present the process is slower than the Haber-Bosch process<sup class="footnote-reference"><a href="#SCd_XA">114</a></sup>. There is also more recent research into methods using primarily water (for the hydrogen, that is normally supplied by fossil fuels in the Haber-Bosch process<sup class="footnote-reference"><a href="#11eLmt">6</a></sup><sup class="footnote-reference"><a href="#jJeN-d">111</a></sup>), air, and electricity (“primarily” because the process may require expensive metals like palladium as a catalyst<sup class="footnote-reference"><a href="#6E6B74">115</a></sup>) to create small fertilizer synthesizing devices. Other “solar” fertilizers are similarly produced from water and air but use solar energy directly, rather than through electricity. These also tend to produce more dilute fertilizers that can help avoid overapplication<sup class="footnote-reference"><a href="#OWZmZG">116</a></sup>. This could take the form of relatively small, low-maintenance devices–“artificial leaves”<sup class="footnote-reference"><a href="#NjI3ZT">117</a></sup>–that are amendable to decentralized production<sup class="footnote-reference"><a href="#OWZmZG">116</a></sup> <sup class="footnote-reference"><a href="#jJeN-d">111</a></sup>. A decentralized model has several advantages, such as reducing transportation needs, which can make up a significant portion of fertilizer costs, especially for areas with poor infrastructure<sup class="footnote-reference"><a href="#OWZmZG">116</a></sup>. It may also offer an alternative to the existing capital-intensive, highly-concentrated world of fertilizer production, with its deeply entrenched interests and commitment to the Haber-Bosch status quo.</p>
<p>The American Farm Bureau Federation (AFBF), an agriculture industry lobbying group, is deeply committed to the fossil fuel-based method. The AFBF has a long history of working closely with the fossil fuel industry, supporting oil and gas domestic extraction (e.g. fracking), and even coal (which can be used as an input into fertilizer production<sup class="footnote-reference"><a href="#BKp6ry">46</a></sup>, and common in Chinese ammonia production<sup class="footnote-reference"><a href="#Dkw7o3">47</a></sup>). This support has sometimes taken the form of outright climate change denial<sup class="footnote-reference"><a href="#LB_VhL">118</a></sup>. The Fertilizer Institute, a lobbying group for the fertilizer industry, is also closely connected to the fossil fuel industry, supporting expanded natural gas production, framing it explicitly as necessary for national food security and threatened by climate change policy<sup class="footnote-reference"><a href="#NjhhZG">119</a></sup>. This allegiance is likely only to grow stronger as pressure grows against the fossil fuel industry.</p>
<p>Questions of industry power aside, there is a lot of uncertainty about the viability of these alternative technologies<sup class="footnote-reference"><a href="#SCd_XA">114</a></sup><sup class="footnote-reference"><a href="#jJeN-d">111</a></sup><sup class="footnote-reference"><a href="#6E6B74">115</a></sup>. A handful of companies cropped up a few years ago trying to produce net-zero emissions fertilizer by replacing Haber-Bosch fossil feedstocks with biomass and switching to renewable energy<sup class="footnote-reference"><a href="#xfu7aQ">120</a></sup>, but none of the plants ever went through and the companies all went bankrupt<sup class="footnote-reference"><a href="#THbpjP">121</a></sup><sup class="footnote-reference"><a href="#lb85Sy">122</a></sup>. The available information seems to indicate mismanagement as a big contributor to these failures but it seems reasonable that the recent decline in natural gas prices–which has led to conventional nitrogen fertilizer production in the US to expand<sup class="footnote-reference"><a href="#Dkw7o3">47</a></sup><sup class="footnote-reference"><a href="#t83ZrN">48</a></sup>–is likely a large factor as well. The economics continue to favor fossil feedstocks.</p>
<p>Finally, changing the production process doesn’t necessarily help address many of the other downstream effects of nitrogen fertilizer. What room is there then for innovating on fertilizer? Is there something with the productivity of synthetic fertilizer but with less of the harm?</p>
<h3>“A Sewer is a Mistake”</h3>
<blockquote>
<p>A handful of social reformers lamented this partition, begging their fellow citizens to bridge the expanding chasm between city and farm. In his 1862 novel Les Misérables, Victor Hugo wrote, “There is no guano comparable in fertility with the detritus of a capital. A great city is the most mighty of dung-makers. Certain success would attend the experiment of employing the city to manure the plain. If our gold is manure, our manure, on the other hand, is gold.”<sup class="footnote-reference"><a href="#20dF-y">61</a></sup></p>
</blockquote>
<p>One option is to return to the older way of thinking: nutrients not as something to be <em>produced</em> but as something to be <em>reused</em>. The use of animal manure is a common example. If animal wastes can be used as fertilizer, then why not human waste too? 75 to 90% of nitrogen intake is excreted as urine<sup class="footnote-reference"><a href="#GnLT6F">2</a></sup>, which is also responsible for more than half of both the phosphorus and potassium in domestic wastewater (an estimated 16% of all mined phosphorus passes through the wastewater system) while constituting less than 1% of its volume<sup class="footnote-reference"><a href="#3KzcuP">123</a></sup>. In fact, recycling of human waste into fertilizer was once a key part of the agricultural nutrient cycle, until demand outpaced the recycled nutrients, more powerful fertilizers were introduced, and waste became seen as less of a resource and more of a problem (e.g. because of diseases) to be managed<sup class="footnote-reference"><a href="#o6QLUC">124</a></sup><sup class="footnote-reference"><a href="#5PpnDo">125</a></sup>. Subsequent sanitation innovations responding to this conception of waste-as-problem such as flush toilets and more sophisticated sewage systems with the purpose of moving waste away from people also contributed to the disruption of these older “circular economies”<sup class="footnote-reference"><a href="#S827v1">17</a></sup>.</p>
<p>That such a system worked in the past means that we could try to restore it, and there is a renewed interest in recycling human waste into fertilizer<sup class="footnote-reference"><a href="#Kj0lzS">126</a></sup>.  Phosphorus can be recovered from wastewater through a variety of means, such as using sewage sludge, which has been used to generate high yields<sup class="footnote-reference"><a href="#k-cu1b">80</a></sup>. Or the nutrient-rich wastewater can be used directly as a medium to grow microalgae to treat the wastewater and harvest nitrogen and phosphorus to produce fertilizers<sup class="footnote-reference"><a href="#NGRjMm">127</a></sup>.  We excrete almost all of the phosphorus we ingest<sup class="footnote-reference"><a href="#S827v1">17</a></sup>, and it can be recovered from wastewater<sup class="footnote-reference"><a href="#T5XG95">18</a></sup><sup class="footnote-reference"><a href="#SZKqjA">128</a></sup>. One study finds that some 40% of Australian phosphorus use can be fulfilled with a sewage recovery system<sup class="footnote-reference"><a href="#wnfN5D">53</a></sup>. The value of waste takes other forms too. Biochar is another soil amendment that can be produced from sewage sludge, which does not work well as a nitrogen fertilizer but can have other benefits such as increasing soil carbon sequestration and preventing nutrient leaching<sup class="footnote-reference"><a href="#Q0wkwe">129</a></sup><sup class="footnote-reference"><a href="#k-cu1b">80</a></sup><sup class="footnote-reference"><a href="#b4aLnX">12</a></sup><sup class="footnote-reference"><a href="#Q0wkwe">129</a></sup>.</p>
<p>Unfortunately the valorization of wastewater for fertilizer is not without problems. The removal of nitrogen and phosphorus are both energy-intensive<sup class="footnote-reference"><a href="#3KzcuP">123</a></sup> and the scalability of these systems are still uncertain<sup class="footnote-reference"><a href="#S827v1">17</a></sup>.</p>
<p>One key complication is waste contamination. Even in the past nightsoil required treatment to be safe<sup class="footnote-reference"><a href="#GnLT6F">2</a></sup>, and now we face a substantially more diverse set of chemicals, including pathogens, pharmaceuticals, cosmetics, and heavy metals from automotive and industrial runoff<sup class="footnote-reference"><a href="#dhZQIS">130</a></sup><sup class="footnote-reference"><a href="#NvBqiH">78</a></sup><sup class="footnote-reference"><a href="#3KzcuP">123</a></sup>. This is true even of animal wastes. Manure from concentrated animal feeding operations (CAFOs, i.e. “factory farms”), which, though massive in volume and thus an ample supply of nutrients, suffers from these problems of contamination<sup class="footnote-reference"><a href="#XII3Yd">131</a></sup>. This question of contamination has meant that these human waste-derived fertilizers aren’t yet permitted for organic farms<sup class="footnote-reference"><a href="#g9P75W">32</a></sup>. However, processes like vermicomposting, which uses earthworms to digest waste into more nutritious–potentially increasing some mineral concentration (phosphorus, for example) by up to 120% percent<sup class="footnote-reference"><a href="#NGRjMm">127</a></sup>, can reduce the content of some of these contaminants<sup class="footnote-reference"><a href="#dhZQIS">130</a></sup><sup class="footnote-reference"><a href="#k-cu1b">80</a></sup>. However, the economics are again unfavorable: mining phosphate rock is cheaper than recovered phosphorus.</p>
<p>Reusing excreted nutrients rather than dumping them into the environment is a clear improvement to our current system, but the biggest limitation is that no nutrient recycling process will be able to recover all of the incoming nutrients. We couldn’t rely on it alone: even a high-efficiency waste nutrient recycling system will still need to be supplemented.</p>
<h3>Little Helpers: Biofertilizers</h3>
<p>There is a class of fertilizers called “smart fertilizers” which usually refer to some slow-release mechanism so that nutrients are released more synchronously with plant uptake (i.e. released as plants need, instead of all at once). The mismatch of nutrient availability and plant need is a large factor in why fertilizer runoff and N2O emissions are as bad as they are; if plants used more of the nutrients then less would make it to waterways<sup class="footnote-reference"><a href="#b4aLnX">12</a></sup><sup class="footnote-reference"><a href="#aw_WOY">132</a></sup>. This category encompasses a number of different methods, including organic wastes<sup class="footnote-reference"><a href="#b4aLnX">12</a></sup>, using slow-release casing, and biofertilizers.</p>
<p>Biofertilizers are fertilizers based on microbes; for example, nitrogen biofertilizers take advantage of existing nitrogen-fixing microorganisms such as cyanobacteria<sup class="footnote-reference"><a href="#8Oy4Ya">133</a></sup><sup class="footnote-reference"><a href="#vbD7xV">134</a></sup><sup class="footnote-reference"><a href="#plIvni">135</a></sup><sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#kYho7r">137</a></sup>. Like other fertilizers, they increase yields<sup class="footnote-reference"><a href="#plIvni">135</a></sup><sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#dhZQIS">130</a></sup><sup class="footnote-reference"><a href="#9Fu4Jq">138</a></sup>, and like the naturally-occurring instances of these microbes, biofertilizers may provide additional benefits such as pest protection<sup class="footnote-reference"><a href="#8Oy4Ya">133</a></sup><sup class="footnote-reference"><a href="#XG2blE">139</a></sup><sup class="footnote-reference"><a href="#plIvni">135</a></sup><sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#RovmVS">140</a></sup><sup class="footnote-reference"><a href="#kYho7r">137</a></sup>, reduced soil erosion<sup class="footnote-reference"><a href="#_m8LJj">141</a></sup><sup class="footnote-reference"><a href="#kYho7r">137</a></sup>, additional growth beyond just that from the increased nutrient supply<sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#dhZQIS">130</a></sup><sup class="footnote-reference"><a href="#RovmVS">140</a></sup><sup class="footnote-reference"><a href="#kYho7r">137</a></sup>, and additional carbon sequestration<sup class="footnote-reference"><a href="#kYho7r">137</a></sup>. The production process can involve fermentation (e.g. with yeast<sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#RovmVS">140</a></sup>) or vermicomposting (i.e. the use of worms) from agricultural waste or wastewater<sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#dhZQIS">130</a></sup><sup class="footnote-reference"><a href="#k-cu1b">80</a></sup>. These processes are accessible even in conditions of low capital (they are substantially cheaper than synthetic fertilizers<sup class="footnote-reference"><a href="#plLKh6">142</a></sup><sup class="footnote-reference"><a href="#RovmVS">140</a></sup>) or without additional energy sources.</p>
<p>The use of such “plant probiotics”<sup class="footnote-reference"><a href="#plIvni">135</a></sup> is not itself new<sup class="footnote-reference"><a href="#plIvni">135</a></sup><sup class="footnote-reference"><a href="#_m8LJj">141</a></sup><sup class="footnote-reference"><a href="#k-cu1b">80</a></sup><sup class="footnote-reference"><a href="#WCjxSr">143</a></sup>–for example, use of manures also introduces these microbes<sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#_m8LJj">141</a></sup> and some are already commercialized on a small scale<sup class="footnote-reference"><a href="#plIvni">135</a></sup>. Environmental concerns around the Haber-Bosch process and other extractive fertilizer production processes, along with advances in biotechnology<sup class="footnote-reference"><a href="#0D4TCM">136</a></sup>, are drawing a renewed interest in commercializing the technology on a larger scale. There are however issues with scaling this to an industrial model: for example, transport and storage of living organisms is more complicated than relatively inert chemical fertilizers<sup class="footnote-reference"><a href="#8Oy4Ya">133</a></sup><sup class="footnote-reference"><a href="#0D4TCM">136</a></sup><sup class="footnote-reference"><a href="#k-cu1b">80</a></sup>.</p>
<p>However, again these biofertilizers are being developed within the context of the prevailing agrochemical industrial regime; companies like Bayer (who purchased Monsanto in 2018) and Nutrien (a $34-billion fertilizer company and second-largest producer of nitrogen fertilizer in the world<sup class="footnote-reference"><a href="#6rPFfC">144</a></sup>) are partnering with startups developing this biofertilizer technology, which is also focusing more on developing novel microbes rather than adapting existing ones<sup class="footnote-reference"><a href="#XG2blE">139</a></sup><sup class="footnote-reference"><a href="#rmeJiv">145</a></sup>.</p>
<p>The homemade biofertilizer <em>Super Magro</em> is one example of the more promising route biofertilizers could take. It consists of a simple, low-cost fermentation process and was released as an open source recipe for other farmers to use freely and augment<sup class="footnote-reference"><a href="#plLKh6">142</a></sup><sup class="footnote-reference"><a href="#ZvarSU">146</a></sup>.</p>
<h2>What do we do?</h2>
<p>Comparisons of these options are usually stated in terms of crop yield. Though some are still in development, these alternatives generally have yields that are worse than or only comparable to the prevailing synthetic fertilizer regime. There are cases where lower yields might be acceptable, such as with hydroponic urban agriculture where no food would be grown otherwise<sup class="footnote-reference"><a href="#N9vj7r">102</a></sup>. But in general, when viewed through crop yields, many analyses find these alternatives to be <em>more</em> environmentally damaging because of their lower yields.</p>
<p>Generally the emissions of agriculture are tied to yield<sup class="footnote-reference"><a href="#aolgfP">147</a></sup><sup class="footnote-reference"><a href="#gq-Glv">33</a></sup>; systems that are more intensive and produce higher yields end up having lower emissions per output. For example, organic systems have lower yield per hectare so they require more land to produce the same amount of food that an industrial farm would, which then leads to more deforestation and greater carbon emissions<sup class="footnote-reference"><a href="#gq-Glv">33</a></sup>. The worrying trade off between feeding people and reducing environmental impact seems to dissipate: industrial agriculture surprisingly gives us the best of both worlds. But this doesn’t make any sense–we know that approach to agriculture has substantial harms.</p>
<p>This apparent paradox becomes resolvable by examining its key assumption: that feeding everyone necessarily requires absolutely maximizing agricultural productivity, which at present means widespread synthetic fertilizer use. This is the mainstream framing of the problem, advocated by organizations like the Bill and Melinda Gates Foundation<sup class="footnote-reference"><a href="#M2JiNG">148</a></sup>. That is, the core cause of inadequate nutrition and starvation is taken to be that we aren’t growing enough food. Therefore we need powerful synthetic fertilizers to help us grow enough.</p>
<p>But are we really not growing enough food?</p>
<h2>Food Waste</h2>
<p>If we focus on food <em>production</em> we end up overlooking another important aspect: food waste. Consensus on exactly how much food is wasted is difficult because of lack of comprehensive data; estimates usually rely on surveys, looking through trash, or inferring through some other model. What is defined as food waste also varies. It can be simply the food that could have been eaten but is not (some definitions require that the food be eaten by a person, e.g. not a pet). or include food eaten in excess of nutritional requirements<sup class="footnote-reference"><a href="#-mm_V_">149</a></sup><sup class="footnote-reference"><a href="#3PEqh8">150</a></sup>, or include that can no longer be sold, even if it still edible<sup class="footnote-reference"><a href="#5PpnDo">125</a></sup>, or still further be complicated by cultural differences, where food in one culinary tradition is considered waste in another<sup class="footnote-reference"><a href="#5PpnDo">125</a></sup>.</p>
<p>What is consistent across these definitions and data is that there is a lot of food wastage. Estimates of food waste range from 20% to 50%<sup class="footnote-reference"><a href="#-mm_V_">149</a></sup><sup class="footnote-reference"><a href="#EX5yPb">151</a></sup> (the wide variation is due to the differing definitions of food waste and outdated or lack of comprehensive data<sup class="footnote-reference"><a href="#3PEqh8">150</a></sup>), and appears to be growing<sup class="footnote-reference"><a href="#UrN_YO">152</a></sup>, even as agricultural output also grows<sup class="footnote-reference"><a href="#PtEeVD">153</a></sup>. In North America and Europe alone, where most of the waste occurs (twice as much as in Sub-Saharan Africa and South and Southeast Asia), this waste could “feed the world’s hungry three times over”<sup class="footnote-reference"><a href="#-mm_V_">149</a></sup>.</p>
<p>Accounting for food waste dramatically increases the impact of each calorie of food consumed. Food waste accounts for as much as 38% of energy in the food system<sup class="footnote-reference"><a href="#PtEeVD">153</a></sup>; in the US this amounts to at least 2% of overall annual energy consumption<sup class="footnote-reference"><a href="#2MKEqv">154</a></sup>. This translates to a large amount of carbon emissions: in the UK, some 17 million tonnes CO2 emissions are attributable to food waste<sup class="footnote-reference"><a href="#OyF9aw">155</a></sup>; globally this figures to about 8 to 10% of GHG emissions (25-30% of food production’s emissions)<sup class="footnote-reference"><a href="#_M5aTx">156</a></sup>. These impacts include not only the emissions from production, but also that food waste that ends up in landfill emits CO2 and methane<sup class="footnote-reference"><a href="#UrN_YO">152</a></sup>. For the UK, an estimated half of waste emissions comes from food waste<sup class="footnote-reference"><a href="#-mm_V_">149</a></sup>. Clearly if our concern is the environmental impact of food production, then food waste represents wasted harm. Reducing food waste not only reduces the impact per calorie from our existing food system, but makes a transition to a less harmful system more feasible in general because less overall output is required<sup class="footnote-reference"><a href="#A88JZE">88</a></sup>.</p>
<p>Food waste is, on one end, usually framed as a technical problem for developing countries, and on the other, a behavioral one for developed countries. In developing countries, most food waste is attributed to lack of adequate technology and infrastructure. This might include poor transportation infrastructure that leads to food lost in transit, lack of well-sealed or cold storage leading to increased spoilage or infestation, crude harvesting equipment that leaves edible material behind<sup class="footnote-reference"><a href="#-mm_V_">149</a></sup><sup class="footnote-reference"><a href="#1GMDYy">157</a></sup><sup class="footnote-reference"><a href="#5PpnDo">125</a></sup>. In wealthier countries, more food waste occurs closer to the consumer<sup class="footnote-reference"><a href="#OyF9aw">155</a></sup><sup class="footnote-reference"><a href="#1GMDYy">157</a></sup><sup class="footnote-reference"><a href="#3PEqh8">150</a></sup><sup class="footnote-reference"><a href="#-mm_V_">149</a></sup>, in part because improved production, storage, and distribution infrastructure reduces the share of waste at earlier points in the chain but also because higher incomes entail more wasteful habits<sup class="footnote-reference"><a href="#0HzIQD">158</a></sup>, such as an avoidance of “ugly” produce<sup class="footnote-reference"><a href="#1GMDYy">157</a></sup><sup class="footnote-reference"><a href="#DAn6s4">159</a></sup><sup class="footnote-reference"><a href="#3PEqh8">150</a></sup><sup class="footnote-reference"><a href="#0HzIQD">158</a></sup>, excessive portion sizes<sup class="footnote-reference"><a href="#1GMDYy">157</a></sup>, and poor meal planning<sup class="footnote-reference"><a href="#1GMDYy">157</a></sup><sup class="footnote-reference"><a href="#3PEqh8">150</a></sup>. Confusing, inconsistent, or outright arbitrary best-by/best-before/expiration date language is also an issue<sup class="footnote-reference"><a href="#1GMDYy">157</a></sup><sup class="footnote-reference"><a href="#bkCrje">160</a></sup><sup class="footnote-reference"><a href="#DAn6s4">159</a></sup>, as are promotions encouraging larger purchases. There may also be legal obstacles preventing the distribution of excess food. The spatial organization of the global food system also drives waste: the more sprawled out a food system is, the farther food has to travel, which means more opportunities for food to be lost or spoiled along the way<sup class="footnote-reference"><a href="#3PEqh8">150</a></sup>.</p>
<p>With this understanding the policy recommendations are usually straightforward. For developing countries solutions focus on technology and infrastructure, which can be as simple as sealed storage drums<sup class="footnote-reference"><a href="#3PEqh8">150</a></sup>. Developed countries food waste policies focus around consumer education and behavior change<sup class="footnote-reference"><a href="#OyF9aw">155</a></sup><sup class="footnote-reference"><a href="#-mm_V_">149</a></sup><sup class="footnote-reference"><a href="#1GMDYy">157</a></sup><sup class="footnote-reference"><a href="#5PpnDo">125</a></sup> and removing hurdles to distributing surplus food<sup class="footnote-reference"><a href="#_M5aTx">156</a></sup>. For example, in France there is legislation from 2016 that fines groceries from throwing away food that’s still good, which has resulted in more food donations and less food waste<sup class="footnote-reference"><a href="#qklICD">161</a></sup>. There are also community-based solidarity groups such as Food Not Bombs that try to ensure that food is being used to feed people.</p>
<p>But this analysis and its consequent policy solutions overlook how endemic these problems are to the political economy of food production–not just technical or behavioral problems–and how developing and developed food waste is deeply interconnected, where food waste is in fact structurally rational.</p>
<p>For example, consider the avoidance of “ugly” produce. It is not only consumer preference at point of purchase that leaves “ugly” produce behind but the decisions of retailers as well. For example, Walmart sets standards about carrot straightness and color, causing one supplier to discard as much as 30% of its carrots that do not meet these standards<sup class="footnote-reference"><a href="#PtEeVD">153</a></sup>. The EU used to have regulations specifying standards around the curvature of bananas<sup class="footnote-reference"><a href="#5PpnDo">125</a></sup> among many other standards regarding other produce<sup class="footnote-reference"><a href="#DAn6s4">159</a></sup>. The cost of such standards are borne by smaller farmers, especially those in the Global South who have no influence over such decisions<sup class="footnote-reference"><a href="#DAn6s4">159</a></sup> and often can’t afford the more sophisticated harvesting technologies that reduce bruising<sup class="footnote-reference"><a href="#3PEqh8">150</a></sup>. In these cases the absence of demand leaves food to spoil<sup class="footnote-reference"><a href="#5PpnDo">125</a></sup>.</p>
<p>Yet, despite the narrative that producer waste is less of an issue in wealthier countries, similar dynamics are found. In California, for example, on average 24% of perfectly good food is left on fields unharvested<sup class="footnote-reference"><a href="#h2pcn_">162</a></sup>. Crop varieties, labor costs, and environmental factors all play a role, but so too do consumer preferences (leaving blemished food behind) and market prices–when prices are low, more may be left unharvested.<sup class="footnote-reference"><a href="#h2pcn_">162</a></sup></p>
<p>Questions around food production really obscure two issues at play here: one is the question of whether or not we produce enough food to meet everyone’s dietary needs, and another is whether or not that produced food is accessible to everyone. Looking more closely, our food production system blows past the first issue, and the problems of hunger and malnutrition have much less to do with sheer agricultural productivity and more to do with <em>how</em> food is production is governed and how food is distributed<sup class="footnote-reference"><a href="#9EDruS">77</a></sup><sup class="footnote-reference"><a href="#A88JZE">88</a></sup><sup class="footnote-reference"><a href="#WCMLES">3</a></sup><sup class="footnote-reference"><a href="#y3elP8">163</a></sup><sup class="footnote-reference"><a href="#SbLrmJ">164</a></sup>. The need for the environmentally-damaging acceleration of agricultural output becomes murkier.</p>
<h2>The Contradiction of Cheap Food</h2>
<p>You could argue that productivity and access are actually closely linked. According to the laws of supply and demand, increasing productivity increases access because it will drive the prices of food down. The massive productivity increases in agriculture over the past century has seen an equally massive decrease in food prices, with many food commodities at 67-87% of their 1900 price<sup class="footnote-reference"><a href="#0HzIQD">158</a></sup>. It’s hard to dispute that food prices are an important factor in food security; rising prices of food are not ever really thought of as a good sign precisely because it points to a decreased access to food.</p>
<p>With the hopes of avoiding high food prices and creating caloric abundance countries then would have an interest in developing agricultural productivity as much as possible, if not the farmers themselves. Yet then a crisis of overproduction occurs, in which a massive surplus of food does indeed drive prices down, but to the point where farmers are unable to recoup the costs of production.</p>
<p>A great deal of US agricultural policy over the past century is precisely about managing this overproduction. In the US, during downward prices and overproduction in the lead up to the Great Depression, the US had “breadlines knee-deep in wheat”<sup class="footnote-reference"><a href="#89_Ari">165</a></sup>. The US government paid farmers leave land idle  during the Great Depression to avoid overproduction and consequent price drops. Controversy around the policy in 1949–framed as paying farmers to not work–led to a different system establishing price floors, guaranteeing farmers a minimum price for their product, thus encouraging them to maximize use of their land<sup class="footnote-reference"><a href="#21Uara">166</a></sup>. This also meant that these downstream industries paid the farmers’ incomes–and included conservation incentives which discouraged intensified exploitation of more and more land<sup class="footnote-reference"><a href="#b5dodc">167</a></sup>. Some farmers support a return to these policies<sup class="footnote-reference"><a href="#BE15hC">168</a></sup><sup class="footnote-reference"><a href="#uCnTzV">169</a></sup><sup class="footnote-reference"><a href="#b5dodc">167</a></sup>, with a recognition that the drastically low prices contemporary subsidies enable also undermine the livelihoods of farmers in other countries–because cheap US exports set the price for other countries’ agricultural products and enable a dependency on imports to the detriment of self-sufficient agriculture, which then allows agribusiness to buy up unused land to produce cash crops for export<sup class="footnote-reference"><a href="#VzyJ_R">170</a></sup><sup class="footnote-reference"><a href="#DSSSgW">171</a></sup>.</p>
<p>One of the consequences of overproduction is a squeeze where farmers can’t recoup their costs of production. In the US, the 1970 price of corn was about $8 a bushel in today’s dollars. Today it’s about $4 a bushel. At the same time, the price of fertilizers have doubled<sup class="footnote-reference"><a href="#2vb73k">172</a></sup>. Trends like this mean that, for many crops, prices have been below production costs for decades<sup class="footnote-reference"><a href="#uCnTzV">169</a></sup>. The subsidies which are meant to compensate for the lost income from these lower prices do not adequately fill the gap, with farm incomes–with subsidies included–seeing large declines<sup class="footnote-reference"><a href="#uCnTzV">169</a></sup>. US farm income has been decreasing<sup class="footnote-reference"><a href="#_D3qLb">173</a></sup>, down to 50% of 2013 income in 2018<sup class="footnote-reference"><a href="#YxllD9">174</a></sup>. In Canada, farmer market net income—income after subtracting government payments, has been negative at least as of 2010<sup class="footnote-reference"><a href="#ZTliM2">175</a></sup>.</p>
<p>Debt has long played a big role in agriculture, helping to smooth out the staggered nature of farm expenditure and income–many expenses are upfront, but income isn’t realized until after the harvest<sup class="footnote-reference"><a href="#Gw1Of3">176</a></sup>. This difference is especially large in input-intensive agriculture, with the amount of chemicals used. A bad harvest can disrupt this cycle, leading to falling behind on loans and jeopardizing future access to capital<sup class="footnote-reference"><a href="#Gw1Of3">176</a></sup>.</p>
<p>Against the backdrop of this price-cost squeeze, this debt can only accumulate. In the US, farm debt has been increasing since 2013<sup class="footnote-reference"><a href="#YxllD9">174</a></sup>. At the same time the business of farm loans is expanding–the fertilizer company Nutrien expanded its farm loan program threefold to $6 billion<sup class="footnote-reference"><a href="#ir4dKG">177</a></sup>, further profiting off of a problem their expensive input regime created in the first place. Because incomes have been declining, farm loan delinquencies have hit a 9 year high<sup class="footnote-reference"><a href="#dh6wYo">178</a></sup>.</p>
<p>At the same time, these low prices, which are encouraged by subsidies and crop insurance guarantee an income to farmers, are to the benefit of downstream industries, such as livestock and snack/beverage/food processing companies, lowering the costs of their inputs. Effectively, taxpayers provide discounts for these businesses<sup class="footnote-reference"><a href="#uCnTzV">169</a></sup>, saving them some $3.9 billion per year<sup class="footnote-reference"><a href="#1cu2km">179</a></sup><sup class="footnote-reference"><a href="#aFAZbr">180</a></sup><sup class="footnote-reference"><a href="#BE15hC">168</a></sup>. With these low prices, the corn for a box of Kellog’s Corn Flakes–which makes up <a href="https://www.kelloggs.co.nz/en_NZ/products/corn-flakes-product.html#nutrition-modal">88% of the product</a>–represents only 2.4% of the retail price<sup class="footnote-reference"><a href="#cornflakes-calc">181</a></sup>. These downstream companies–as well as the input companies, i.e. those that provide fertilizer, chemicals, seeds, machinery, etc–have seen record profits<sup class="footnote-reference"><a href="#XaaQ8X">182</a></sup> and provided massive payouts to shareholders:</p>
<blockquote>
<p>As revealed in a recent report conducted by TUC and the High Pay Center on the behaviors of FTSE100 companies in the last 5 years, listed retailers paid over £2bn to shareholders in 2018, despite none of them being Living Wage Foundation accredited, while listed Food &amp; drinks companies paid almost £14bn – more than they made in net profit (£12.7bn). To put that into perspective, just a tenth of this shareholder pay-out is enough to raise the wages of 1.9 million agriculture workers around the world to a living wage, for example those who produce food at the origin of the food chains that they coordinate as lead firms.<sup class="footnote-reference"><a href="#5opCK-">183</a></sup></p>
</blockquote>
<p>In addition to cheaper inputs, overproduction gives these downstream companies more discretion over what they will and won’t accept. For example, companies adopt stricter quality standards<sup class="footnote-reference"><a href="#DAn6s4">159</a></sup> and retailers can return whatever they don’t want or fails to sell in time, at no cost<sup class="footnote-reference"><a href="#3PEqh8">150</a></sup>, making farming even riskier than before.</p>
<p>For the farmer in this trap, there appear to only be a handful of options. One standard practice is to suppress the wages of farm workers, who are already among the most precarious group of workers. In the US, the H-2A visa system is used to keep wages low for migrant labor, to the point where a quarter to almost a third of such families are below the federal poverty line<sup class="footnote-reference"><a href="#iGn-37">184</a></sup><sup class="footnote-reference"><a href="#OhftRW">185</a></sup> and lowers wages for domestic farm labor as well<sup class="footnote-reference"><a href="#GvbMOo">186</a></sup>.</p>
<p>Another option is to expand markets for food. The problem with food is that it is relatively inelastic in demand; but one argument sees food waste against a backdrop of increasing food consumption in the US, with marketing that tries to enlarge the American appetite to offload an oversupply of cheap food<sup class="footnote-reference"><a href="#UrN_YO">152</a></sup><sup class="footnote-reference"><a href="#PtEeVD">153</a></sup>. Farmers themselves do not typically have a role in this expansion; and most marketed food is in the form of snacks and processed foods of that nature; i.e. products of companies downstream from farming.</p>
<p>The other is to increase production. The low prices mean that productivity and volume is all the more important to make a living, which encourages environmentally harmful but output maximizing processes and the expansion of agricultural land<sup class="footnote-reference"><a href="#b5dodc">167</a></sup><sup class="footnote-reference"><a href="#89_Ari">165</a></sup>. This only makes the problem worse–as farmers attempt to stay afloat by accelerating production, the markets for their crops end up flooded, further driving prices down.</p>
<p>The other is to overproduce to hedge against small harvests but withhold excess to keep prices high<sup class="footnote-reference"><a href="#DAn6s4">159</a></sup>. This is why we see for example perfectly good food left unharvested to rot. This behavior seems unreasonable–it <em>is</em> in many ways–but is rational, considering the farmer’s position. When dealing with large retailers, the situation is such that if they fail to supply the agreed amount, they are dropped as a supplier<sup class="footnote-reference"><a href="#3PEqh8">150</a></sup><sup class="footnote-reference"><a href="#DAn6s4">159</a></sup>, so the rational move is to overproduce just in case.</p>
<p>All of this is made easier to endure or even profit from with scale. The high costs of inputs and low prices of output are especially felt by smaller farms. We see this in US farming: almost 80% of small family farms’ operating profit margin are in the “high risk level”. In contrast, large-scale farms tend to be at a “low risk level”<sup class="footnote-reference"><a href="#_D3qLb">173</a></sup><sup class="footnote-reference"><a href="#25U1QS">44</a></sup>.  Larger farms gain better access to loans and better prices<sup class="footnote-reference"><a href="#plji8g">187</a></sup>. The current subsidy system exacerbates this, disproportionately benefiting larger farms who aren’t struggling in the price-cost squeeze<sup class="footnote-reference"><a href="#25U1QS">44</a></sup><sup class="footnote-reference"><a href="#21Uara">166</a></sup><sup class="footnote-reference"><a href="#kjx5p9">23</a></sup><sup class="footnote-reference"><a href="#20dF-y">61</a></sup><sup class="footnote-reference"><a href="#f9wFWQ">188</a></sup> and also tend to be more environmentally destructive<sup class="footnote-reference"><a href="#chuDeg">29</a></sup>, even when accounting for the larger cropland<sup class="footnote-reference"><a href="#_D3qLb">173</a></sup>. Numbers range from 75-85% of farm subsidies going to only 10-15% of farms<sup class="footnote-reference"><a href="#N2ZNpL">189</a></sup><sup class="footnote-reference"><a href="#lStjEq">39</a></sup>, and the 2018 Farm Bill has not really altered this dynamic<sup class="footnote-reference"><a href="#fWrS7d">190</a></sup>. The advantages of highly-capitalized, larger farms contributed to the consolidation of farming into fewer bigger farms<sup class="footnote-reference"><a href="#plji8g">187</a></sup>. In the US some 3 million farms went out of business in the postwar period<sup class="footnote-reference"><a href="#CTq7gr">191</a></sup>.</p>
<p>Even though dealing with agricultural overproduction has been a chronic problem of US agriculture, it came to have its usefulness in achieving US geopolitical goals. Harriet Friedmann<sup class="footnote-reference"><a href="#DSSSgW">171</a></sup> and Philip McMichael<sup class="footnote-reference"><a href="#SbLrmJ">164</a></sup> outline a succession of “food regimes” where agricultural power is applied to capitalist expansion. Following World War II, the US instrumentalized its agricultural surplus by directing it towards contributing to European reconstruction and using food aid to slow the spread of communism<sup class="footnote-reference"><a href="#gUnVx3">28</a></sup><sup class="footnote-reference"><a href="#DSSSgW">171</a></sup><sup class="footnote-reference"><a href="#SbLrmJ">164</a></sup>. Later, finding outlets for this surplus itself became a geopolitical goal. For example, developing markets for agricultural products through World Bank and IMF structural adjustment programs and WTO free-trade agreements in the Global South<sup class="footnote-reference"><a href="#IJgxJI">192</a></sup><sup class="footnote-reference"><a href="#gUnVx3">28</a></sup><sup class="footnote-reference"><a href="#SbLrmJ">164</a></sup><sup class="footnote-reference"><a href="#efD9Gx">193</a></sup> . The development of such markets is itself partly accomplished by the surplus of US agricultural overproduction, which undermines local agriculture with low prices and disrupting food security. Rather than developing food self-sufficiency, the focus is on economic development to increase the affordability of imported food<sup class="footnote-reference"><a href="#ICFztz">194</a></sup><sup class="footnote-reference"><a href="#DSSSgW">171</a></sup>. In a strangely circular way, agriculture is no longer for growing food, but for growing commodities with which to buy food.</p>
<p>Part of these economic development programs is the consolidation of productive land and its re-orientation towards cash crops, further undermining food security<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>. This is the case in Zimbabwe, where the areas with the highest agricultural productivity also have the worst chronic malnutrition<sup class="footnote-reference"><a href="#n1iP7n">196</a></sup>. At the same time, the use of non-tariff barriers, such as sanitary and phytosanitary measures, effectively allow exporting nations to protect their own markets and make it so that only highly-capitalized operations can absorb the costs these additional measures require<sup class="footnote-reference"><a href="#0ie15A">197</a></sup>.</p>
<p>Figures like Thomas Sankara saw how food aid was exploitative and that self-sufficiency the route that preserved autonomy:</p>
<p><figure>
            <a href="/assets/uploads/sankara.jpg" title="">
            <img src="/assets/uploads/sankara.jpg" title="">
            </a>
            <figcaption>Thomas Sankara explaining food aid.</figcaption>
            </figure>
<p>However, major organizations like the UN’s FAO, World Bank, and the IMF and foundations like the Gates Foundation continue to press that low productivity is the main problem with food security and thus synthetic fertilizer, high-yielding varieties, and other Green Revolution technologies need greater levels of adoption in developing countries <sup class="footnote-reference"><a href="#9NGONY">198</a></sup><sup class="footnote-reference"><a href="#WUdPJg">199</a></sup>.</p>
<h2>Fanning the Flames</h2>
<h3>Mexico</h3>
<p>The Green Revolution was first coordinated as a development strategy in Mexico. David Barkin describes how these programs saw an <em>increase</em> in dependency on food imports<sup class="footnote-reference"><a href="#IELAEl">200</a></sup><sup class="footnote-reference"><a href="#gUnVx3">28</a></sup>, even though Mexico has all it needs for food self-sufficiency<sup class="footnote-reference"><a href="#84MAkf">201</a></sup>. Even worse, the expansion of the agricultural industry  is <em>in parallel</em> with <em>decreasing</em> food consumption. These programs of productivity increases are driven with a focus on increasing export-oriented crops, crops for markets, rather than for improving self-sufficiency<sup class="footnote-reference"><a href="#84MAkf">201</a></sup><sup class="footnote-reference"><a href="#f9wFWQ">188</a></sup>. Achieving the maximum productivity of a land isn’t possible without the capital required for the purchase of synthetic fertilizer, pesticides, high-yielding variety seeds, and so on. Poorer farmers are displaced by those with that necessary capital, instead needing to find off-farm work to buy the imported food<sup class="footnote-reference"><a href="#20dF-y">61</a></sup><sup class="footnote-reference"><a href="#84MAkf">201</a></sup><sup class="footnote-reference"><a href="#plji8g">187</a></sup><sup class="footnote-reference"><a href="#QiuPBf">202</a></sup><sup class="footnote-reference"><a href="#f9wFWQ">188</a></sup>.</p>
<p>This process of undermining self-sufficiency has the consequence of creating new markets for countries to sell their food surpluses to, and facilitates the process of proletarianization, creating a pool of cheap labor<sup class="footnote-reference"><a href="#84MAkf">201</a></sup><sup class="footnote-reference"><a href="#9NGONY">198</a></sup>. It also serves other geopolitical goals as well. Barkin quotes one American diplomat commenting on Micronesia, who plainly put it:</p>
<blockquote>
<p>If we examine our effects on the island culture, we see they have a real case. Before the U. S. arrived, the natives were self-sufficient, they picked their food off the trees or fished. Now, since we have them hooked on consumer goods, they’d starve without a can opener. Some of the radical independence leaders want to reverse this and develop the old self-sufficiency. We can’t blame them. However, we can’t leave. We need our military bases there. We have no choice. As some of my friends in Washington say, you’ve got to grab them by the balls, their minds and hearts will follow <sup class="footnote-reference"><a href="#84MAkf">201</a></sup></p>
</blockquote>
<p>Viewed this way, the Green Revolution in Mexico has a continuity with the colonization of Latin America, in which colonists monopolized the most fertile land, away from their function of sustaining the local population and instead towards producing profitable crops for export. Those who used to farm those lands are marginalized–if they weren’t outright killed–towards less productive lands with greater water scarcity<sup class="footnote-reference"><a href="#9NGONY">198</a></sup>.</p>
<h3>Sub-Saharan Africa</h3>
<p>Sub-Saharan Africa (SSA) is constant target for Green Revolution development<sup class="footnote-reference"><a href="#9gAXp1">203</a></sup>. Food imports in SSA have increased for decades<sup class="footnote-reference"><a href="#QiuPBf">202</a></sup>, and part of this is blamed on low productivity due to low fertilizer usage<sup class="footnote-reference"><a href="#yjhees">204</a></sup><sup class="footnote-reference"><a href="#Vb5nD3">8</a></sup> and high levels of soil degradation and erosion<sup class="footnote-reference"><a href="#4yxRve">205</a></sup>. Fertilizer is especially expensive in SSA, in large part due to high transportation costs<sup class="footnote-reference"><a href="#yjhees">204</a></sup> (some of this might be addressed by recent development of domestic production capacity<sup class="footnote-reference"><a href="#zyYGwn">206</a></sup>) ; farmers there can pay as much as five times as a farmer in Europe<sup class="footnote-reference"><a href="#T5XG95">18</a></sup><sup class="footnote-reference"><a href="#S827v1">17</a></sup>. Because of the overapplication of fertilizers elsewhere, and the accompanying environmental harm, some call for increasing fertilizer use in SSA with a corresponding or larger decrease elsewhere (for example, 588kg nitrogen fertilizer/ha/year in northern China vs 7kg in Kenya)<sup class="footnote-reference"><a href="#Ta21E6">207</a></sup>.</p>
<p>The soil degradation which supposedly necessitates synthetic fertilizer in SSA is often attributed to poor management, a form of development rhetoric that frames peasants as ignorant about how best to work their land<sup class="footnote-reference"><a href="#9NGONY">198</a></sup><sup class="footnote-reference"><a href="#f9wFWQ">188</a></sup><sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup><sup class="footnote-reference"><a href="#4yxRve">205</a></sup><sup class="footnote-reference"><a href="#WUdPJg">199</a></sup>. More recent degradation looks to have more to do with climatic and biophysical factors<sup class="footnote-reference"><a href="#4yxRve">205</a></sup>, but the farming of soil eroded lands has more to do with a process of marginalization–the original farmers had developed their methods of effective soil conservation<sup class="footnote-reference"><a href="#4yxRve">205</a></sup><sup class="footnote-reference"><a href="#n1iP7n">196</a></sup>–where larger landholders, European colonists, and transnational corporations monopolize the highest quality land and displace other farmers to smaller and smaller holdings, where the land has to be worked harder to meet the same needs<sup class="footnote-reference"><a href="#f9wFWQ">188</a></sup><sup class="footnote-reference"><a href="#plji8g">187</a></sup><sup class="footnote-reference"><a href="#n1iP7n">196</a></sup>. In some cases, it is these transnational companies that overwork the soil, moving on to other fertile land once it’s been exhausted<sup class="footnote-reference"><a href="#f9wFWQ">188</a></sup>.</p>
<p>The increased adoption of synthetic fertilizers might only accelerate this soil degradation. One study looked at Zambia’s input subsidy program and found that the introduction of fertilizer subsidy programs does in fact increase fertilizer usage, which subsequently leads to a reduction in traditional low- or no-input fertility-management methods such as fallowing and intercropping and an increase in continuous cropping–that is, a shift towards more intensive agriculture that disrupts natural cycles of soil restoration<sup class="footnote-reference"><a href="#TA_2RV">208</a></sup><sup class="footnote-reference"><a href="#cNmw3C">209</a></sup><sup class="footnote-reference"><a href="#F7aPre">210</a></sup>. This shift in turn contributes to reduced levels of soil organic matter, which is important for maintaining soil health, which decreases the soil quality. Though there was a short-term boost in productivity, the resulting soil degradation could lead to a net decline in the long run which can only be delayed by further increasing the usage of expensive fertilizer<sup class="footnote-reference"><a href="#cNmw3C">209</a></sup>.</p>
<p>A review of eighty studies on fertilizer subsidies in Africa found that these subsidies are more likely to go to households with larger landholdings, greater wealth, and/or connections to the government, even if programs are ostensibly deliberately designed to avoid such outcomes<sup class="footnote-reference"><a href="#Ta21E6">207</a></sup><sup class="footnote-reference"><a href="#Eb7hU3">211</a></sup>. Fertilizer use stops once subsidies are withdrawn, so farmers are left with degraded soil and unable to afford the now necessary inputs to stabilize yields. Ultimately, productivity increases peter out after a few years, and there are only negligible effects on improving self-sufficiency, reducing import dependency, and alleviating poverty<sup class="footnote-reference"><a href="#Eb7hU3">211</a></sup>.</p>
<p>These subsidies are expensive: African governments devote a large part of their budgets to these input subsidies, some $1 billion a year<sup class="footnote-reference"><a href="#cNmw3C">209</a></sup><sup class="footnote-reference"><a href="#9gAXp1">203</a></sup>. For Zambia, as much as 35% of the country’s agricultural budget was going towards fertilizer subsidies<sup class="footnote-reference"><a href="#Ta21E6">207</a></sup>. At one point, 9% of the Malawi’s entire budget went to these subsidies<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>. This is more or less a transfer of public funds to fertilizer producers like Bayer/Monsanto<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup><sup class="footnote-reference"><a href="#9gAXp1">203</a></sup>.</p>
<p>As high as these subsidies are, they can’t compete with those in wealthier countries. OECD countries provide subsidies to their own farmers of about $1 billion <em>per day</em><sup class="footnote-reference"><a href="#6eT7sI">212</a></sup>, and such financial support encompassed 30% of all farm receipts from 2003-2005<sup class="footnote-reference"><a href="#PtEeVD">153</a></sup>.</p>
<p>This is compounded by the fact that Green Revolution technologies often come as a package. Specific varieties of crops are necessary to achieve the full yield improvements of synthetic fertilizer use (this varieties are usually intellectual property), and increased sensitivity to pests from fertilizer user necessitates the use of pesticides<sup class="footnote-reference"><a href="#TA_2RV">208</a></sup><sup class="footnote-reference"><a href="#eYEaIk">83</a></sup><sup class="footnote-reference"><a href="#loSDbG">213</a></sup>. Higher productivity can also require more water, beyond what the water cycle normally provides, so irrigation also increases<sup class="footnote-reference"><a href="#20dF-y">61</a></sup>.</p>
<p>In the case of Malawi, the suggested alternative to fertilizer subsidies is addressing underlying issues:</p>
<blockquote>
<p>policies aimed at relieving the key constraints that our model tries to capture—such as land, credit and labor availability—might go further towards addressing the bottlenecks to on-farm intensification that smallholders in Malawi encounter, and could lead to the adoption of better on-farm practices that reverse soil degradation and improve the long-term viability of small-holder agriculture.<sup class="footnote-reference"><a href="#F7aPre">210</a></sup></p>
</blockquote>
<p>Interestingly, many countries in SSA are agricultural <em>exporters</em> while being net food importers. That is, SSA’s dependency on food imports is in part due to agricultural land and resources being directed for export-oriented production (in a form reminiscent of their colonial histories<sup class="footnote-reference"><a href="#7rwDL2">214</a></sup>) rather than supplying the country’s food needs–“even a small substitution in their agricultural export products into food would eliminate their deficits”<sup class="footnote-reference"><a href="#efD9Gx">193</a></sup>.</p>
<p>This push towards agricultural production for export is in part driven by this need for income to purchase food imports and in part to manage national debts. The 1990s, Malawi, under the advisement of USAID and the tobacco industry, re-oriented production from food crops to tobacco crops with the goal of paying off its debt, with part of the rationale being that revenue from tobacco exports would be plenty to purchase the food needed to account for reduced production. The consequence, however, was that the ability for Malawian farmers to feed themselves was no longer dependent on their own agricultural ability, but rather on market prices for tobacco–which fell by 37% in 2009, and made it difficult for farmers to feed themselves<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>.</p>
<p>Sometimes this shift to export-oriented cash crops is further frustrated by the surpluses of major producers. Where some countries had advantages in producing things like sugar, the rise of processed foods meant fewer people were consuming sugar directly, instead mediated by processed foods–and as such, that opened up the possibility of sugar substitutes, i.e. HFCS, which then undermined countries with the comparative advantage for sugar production, as corn was overproduced and very cheap. Thus these countries were in a double-bind: food import dependency plus declining revenues from crop exports<sup class="footnote-reference"><a href="#DSSSgW">171</a></sup>.</p>
<p>These dynamics appear elsewhere too. In Nepal, though fertilizer subsidies do tend to increase crop yields, environmental problems are exacerbated<sup class="footnote-reference"><a href="#5J1R08">215</a></sup>, and the subsidies may disproportionately benefit farmers who are more connected to the state and/or wealthier to begin with<sup class="footnote-reference"><a href="#5J1R08">215</a></sup><sup class="footnote-reference"><a href="#yjhees">204</a></sup>. In India, initial bumper crops from subsidized fertilizer application then gave way to crop failures and soil depletion<sup class="footnote-reference"><a href="#TA_2RV">208</a></sup><sup class="footnote-reference"><a href="#EnFQPP">216</a></sup>, saw a move away from traditional techniques like crop rotation towards continuous cultivation of export-oriented crops<sup class="footnote-reference"><a href="#TA_2RV">208</a></sup>, and increased stratification between farmers who could afford the Green Revolution technologies and those who could not afford to stay on their land<sup class="footnote-reference"><a href="#TA_2RV">208</a></sup><sup class="footnote-reference"><a href="#f9wFWQ">188</a></sup>. Vandana Shiva describes deeper social shifts these technologies fomented:</p>
<blockquote>
<p>The shift from internal to externally purchased inputs did not merely change ecological processes of agriculture. It also changed the structure of social and political relationships, from those based on mutual (though asymmetric) obligations—within the village to relations of each cultivator directly with banks, seed and fertilizer agencies, food procurement agencies, and electricity and irrigation organisations.<sup class="footnote-reference"><a href="#TA_2RV">208</a></sup></p>
</blockquote>
<h2>Hand to Mouth</h2>
<p><em>Content warning: There is some mention of suicide in this section.</em></p>
<p>This high-input and market-dependent form of agriculture puts farmers into a double-bind: they are both exposed to the impacts of fertilizer prices on their own production costs but also on the costs of their food<sup class="footnote-reference"><a href="#-L9TUe">217</a></sup><sup class="footnote-reference"><a href="#T5XG95">18</a></sup>. One study finds that increasing fertilizer prices would decrease crop yields by up to 13%<sup class="footnote-reference"><a href="#5DPB-1">218</a></sup>, reducing income.</p>
<p>In addition to the typical weather and climatic risks of agriculture, they are now exposed to the volatility of export restrictions, financial speculation, as well as the weather and climactic risks of wherever they import food from<sup class="footnote-reference"><a href="#9u391v">219</a></sup><sup class="footnote-reference"><a href="#z_RsHF">220</a></sup><sup class="footnote-reference"><a href="#-L9TUe">217</a></sup>! Risk has magnified, rather than diffused, through this system<sup class="footnote-reference"><a href="#6Q6GJj">221</a></sup><sup class="footnote-reference"><a href="#-L9TUe">217</a></sup><sup class="footnote-reference"><a href="#9u391v">219</a></sup><sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>.</p>
<p>Arrangements such as contract farming integrate smaller farmers into global agricultural industrial supply chains through arrangements that ensure buyers (with substantially more market power, who do not need contribute to the costs of production, also ways around labor laws) bear little of this risk<sup class="footnote-reference"><a href="#gUnVx3">28</a></sup><sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>, much like the increasing use of contract workers throughout other industries.</p>
<p>Scalability becomes absolutely vital to generate enough revenue to remain solvent. Farmers with lower yields–i.e. subsistence farmers and those with less access to the capital necessary for scaling up–are the ones at the greatest risk<sup class="footnote-reference"><a href="#dh6wYo">178</a></sup><sup class="footnote-reference"><a href="#g9P75W">32</a></sup><sup class="footnote-reference"><a href="#s7wSmH">222</a></sup>. Agricultural finance recognizes this, compounding the effect by giving larger farms cheaper loans, along with other advantages such as more opportunities to exploit cheap labor<sup class="footnote-reference"><a href="#plji8g">187</a></sup>. The trap is intensified due to the declining effectiveness of inputs, which have the effect of degrading the soil<sup class="footnote-reference"><a href="#EnFQPP">216</a></sup>. The general necessity of absolutely maximizing output for a piece of land encourages the extractivist model of agriculture, in which the soil is “mined”, with nutrients pulled out faster than they can be naturally replaced<sup class="footnote-reference"><a href="#gUnVx3">28</a></sup>; sometimes even faster than they can be “unnaturally” replaced. In India, farmers require three times the fertilizer to achieve the same yields as they used to, while the prices for those crops remain the same or decline<sup class="footnote-reference"><a href="#EnFQPP">216</a></sup>. Insolvency is basically inevitable.</p>
<p>When farmers try to re-integrate traditional practices or develop systems parallel to conventional inputs, they are shut down. In Zimbabwe, farmers could not sell their own seeds as alternatives to the engineered hybrids–the practice was made illegal<sup class="footnote-reference"><a href="#n1iP7n">196</a></sup>.</p>
<p>What are the consequences of this precarity and lack of control over one’s life? One may be an increase in farmer suicides<sup class="footnote-reference"><a href="#fFH_WZ">223</a></sup>–farming is the profession most at-risk for suicide<sup class="footnote-reference"><a href="#5RuiK0">224</a></sup>. The farmers most likely to commit suicide are those who have marginal landholdings, focus on cash crops, and are indebted, which are exacerbated by all of the dynamics described above<sup class="footnote-reference"><a href="#fFH_WZ">223</a></sup><sup class="footnote-reference"><a href="#TA_2RV">208</a></sup><sup class="footnote-reference"><a href="#WUdPJg">199</a></sup><sup class="footnote-reference"><a href="#farmer-death-dispute">225</a></sup>.</p>
<p>Another consequence of this precarity is the increasing concentration of agricultural land and production.</p>
<h2>Land Grabbing</h2>
<p>Farmers, now unable to support themselves on the land, have no choice but to sell it. Agricultural land concentrates into fewer and fewer hands, contiguous with the dispossessions that occurred with colonization. Here, however, these dispossessions result from a mix of economic factors, driven by overproduction, and legal means, with post-colonial states, under the direction of development organizations like the US’s Millennium Challenge Corporation, often facilitating the process by unilaterally replacing traditional land right systems with ones more amenable to foreign investment and ownership<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup><sup class="footnote-reference"><a href="#84MAkf">201</a></sup><sup class="footnote-reference"><a href="#xSaaDE">226</a></sup>.</p>
<p>More recently foreign acquisition of agricultural land, called “land grabs”, have attracted a lot of attention. These acquisitions may be about food, water, and energy security<sup class="footnote-reference"><a href="#tnkBMB">227</a></sup><sup class="footnote-reference"><a href="#n67Qtk">228</a></sup><sup class="footnote-reference"><a href="#Mjg2OT">229</a></sup>, just about expanding agribusiness amidst rising demand for biofuels and other cash crops<sup class="footnote-reference"><a href="#n67Qtk">228</a></sup>, and for financial speculation<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup><sup class="footnote-reference"><a href="#qsO0rc">230</a></sup>, faciliated by technologies that make their agricultural development easier to manage remotely as financial assets<sup class="footnote-reference"><a href="#MTY2Nz">231</a></sup>. The countries where these land grabs are most common in recent years are Sub-Saharan Africa and South Asia<sup class="footnote-reference"><a href="#pogchA">232</a></sup>. In Ethiopia, some 10% of the country’s agricultural land has been handed to foreign investors for commodity crops for export<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>. The World Bank and FAO has framed these as “win-win” opportunities for economic development<sup class="footnote-reference"><a href="#U_wMMf">233</a></sup><sup class="footnote-reference"><a href="#S0YUzV">234</a></sup> . In Sudan this export-oriented appropriation of land saw higher food prices, monopolized water usage, and resistance from the local population that was met with violence<sup class="footnote-reference"><a href="#xSaaDE">226</a></sup>.</p>
<p>Sometimes farmers aren’t displaced but are actively involved in the investment process, seeking capital to stay afloat<sup class="footnote-reference"><a href="#MTY2Nz">231</a></sup>. Otherwise farmers are displaced<sup class="footnote-reference"><a href="#plji8g">187</a></sup><sup class="footnote-reference"><a href="#xSaaDE">226</a></sup>: for example, a British firm acquired 9,000 ha of land in Tanzania, potentially displacing over 11,000 people for biodiesel production<sup class="footnote-reference"><a href="#YjAwYz">235</a></sup>. The newly managed farms may be highly automated so that there isn’t even much promise of any employment<sup class="footnote-reference"><a href="#Mjg2OT">229</a></sup>, so these displaced people constitute a “surplus” population often relegated to slums<sup class="footnote-reference"><a href="#plji8g">187</a></sup>. Foreign workers are brought in to work the land with relatively little interaction with the local population<sup class="footnote-reference"><a href="#pogchA">232</a></sup>; the land is meant to operate, it seems, as a virtual extension of the country that owns it.</p>
<p>This is also occurring throughout the global North, where agricultural productivity tends to be higher and property rights are less risky for investors<sup class="footnote-reference"><a href="#MTY2Nz">231</a></sup>, though the <em>Food Security is National Security Act</em> was introduced in 2017 to prevent foreign control of US agricultural land<sup class="footnote-reference"><a href="#VPMWdX">236</a></sup>. In the EU, millions of farms were lost over the past decades<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>. In the US, there is the original and ongoing dispossession of indigenous lands and subsequent and ongoing dispossession of black farmers’ land<sup class="footnote-reference"><a href="#rBgP1m">237</a></sup><sup class="footnote-reference"><a href="#qsO0rc">230</a></sup><sup class="footnote-reference"><a href="#25U1QS">44</a></sup>. US agriculture is already highly concentrated: some 3% of farms in the US are responsible for 50% of the value of all agricultural production<sup class="footnote-reference"><a href="#farm-calc">238</a></sup><sup class="footnote-reference"><a href="#25U1QS">44</a></sup>.</p>
<p>Often this land remains idle. For example, biofuel production slowed when oil became cheap again, and it wasn’t worth developing the land<sup class="footnote-reference"><a href="#b0fCi_">239</a></sup>.</p>
<h2>Back to Biomass</h2>
<p>Agricultural products encompass much more than just food; they are also produced as fuel, pharmaceuticals, bioplastics, and so on. Even within the category of “food” there are agricultural products for direct human consumption, those that are used as animal feed, and that used for food processing (e.g. snacks, beverages, oils). These categories are not clear cut either: corn may be grown for any of these, but corn itself is a heterogeneous crop and individual corn varieties are not necessarily fungible. Corn grown for animal feed, for instance, will be starchier than that grown for direct human consumption. Cane or beet sugar, though something we use in cooking directly, is more commonly an input into the snack and beverage industry (where it hasn’t been out competed by corn-derived high fructose corn syrup). The same is true for other such “flex crops”, which have a variety of possible end-uses.</p>
<p>The sustainability of food production and its ability to actually feed people then is deeply connected to these alternative uses of agricultural capacity. For example, expanded demand for biofuels may cause food prices to rise (30% of grain price increases during the 2007-2008 global price food spike is attributed to biofuel demand<sup class="footnote-reference"><a href="#UI49PE">240</a></sup>) and encourage deforestation from agricultural expansion <sup class="footnote-reference"><a href="#Hv99Zg">241</a></sup><sup class="footnote-reference"><a href="#29nIvt">242</a></sup><sup class="footnote-reference"><a href="#-L9TUe">217</a></sup>. Here food’s market value dictates whether or not it’s grown instead of potentially more profitable alternatives. But there are many things we can do to reduce the necessity of fuels; we cannot reduce our need for food to live.</p>
<h2>Agroecology and Technology</h2>
<p>What alternative is there to all of this? The commodification of food–seeing it as something to be produced and sold like factory goods–drives a lot of the dynamics described above. Agroecology that sees food not as something to be manufactured and agriculture not as a factory-like process but as a scaffolding for relationships and a source of autonomy.</p>
<p>Agroecology has some overlap with practices like organic and regenerative agriculture, at least in terms of focusing on environmentally-friendlier techniques, but where it differs is its commitment to social and economic issues outside of the specific production process (sometimes contrasted with a “input substitution” approach to agriculture<sup class="footnote-reference"><a href="#CTq7gr">191</a></sup>). An organic or a regenerative farm’s efforts at sustainable or remediative production might be hampered by market demands, for example<sup class="footnote-reference"><a href="#Qk2cSx">243</a></sup>. That’s sort of reflective of organic agriculture’s trajectory. As Julie Gutman describes in <em>Agrarian Dreams: The Paradox of Organic Farming in California</em>, organic agriculture originally encompassed more radical notions of food system change but was over time shaped to be focused on very specific aspects of the production process and integrated into the existing agribusiness industry<sup class="footnote-reference"><a href="#eZiX81">244</a></sup>. Agroecology is not itself immune to this kind of co-optation, as a recent report on “junk agroecology” describes<sup class="footnote-reference"><a href="#OWYzOT">245</a></sup>.</p>
<p>Peter Rosset and Miguel Altieri outline agroecological production principles:</p>
<blockquote>
<p>The production system must (1) reduce energy and resource use and regulate the overall energy input so that the output:input ratio is high; (2) reduce nutrient losses by effectively containing leaching, runoff, and erosion, and improve nutrient recycling through the use of legumes, organic manure and compost, and other effective recycling mechanisms; (3) encourage local production of food items adapted to the natural and socioeconomic setting; (4) sustain desired net output by preserving natural resources (by minimizing soil degradation); and (5) reduce costs and increase the efficiency and economic viability of small and medium-sized farms, thereby promoting a diverse, potentially resilient agricultural system.<sup class="footnote-reference"><a href="#CTq7gr">191</a></sup></p>
</blockquote>
<p>Actual techniques can encompass many things, such as re-integrating rural-urban nutrient cycles<sup class="footnote-reference"><a href="#tn7pv5">246</a></sup>, using natural fertilizers and nitrogen-fixing cover crops like legumes, soil-conserving and soil-building practices, ecologically-rooted pest management practices, and so on<sup class="footnote-reference"><a href="#CTq7gr">191</a></sup>. These have both environmental and economic benefits. For example: a system integrating perennial native prairie plants can reduce fertilizer use and runoff, saving more than $850 million per year in costs and damage<sup class="footnote-reference"><a href="#kjx5p9">23</a></sup>, and can increase yields by improving soil health, such as with the use of “fertilizer trees” as in parts of Africa (a practice called “evergreen agriculture”)<sup class="footnote-reference"><a href="#MDJhOG">247</a></sup><sup class="footnote-reference"><a href="#MzFjM2">248</a></sup>. These techniques can be used while considering their social and political effects. George Washington Carver, for example, advocated the use of legumes (such as peanuts) both as a way of maintaining soil health but also as part of a program for economic and political autonomy<sup class="footnote-reference"><a href="#yCg9cs">249</a></sup>. Agroecological soil management practices can improve fertility without needing to resort to subsidized inputs<sup class="footnote-reference"><a href="#NzA0ND">250</a></sup>, helping break the debt cycle. In general, these approaches have been found to improve crop yields while reducing inputs<sup class="footnote-reference"><a href="#NzA0ND">250</a></sup>.</p>
<p>The acroecology movement is led by peasants and peasant organizations like the Landless Workers Movement (MST), the Zapatista Army for National Liberation (ELZN), and La Via Campesina, with networks encompassing thousands and thousands of small producers across continents<sup class="footnote-reference"><a href="#gUnVx3">28</a></sup><sup class="footnote-reference"><a href="#xvQJ09">251</a></sup><sup class="footnote-reference"><a href="#N5Xxen">252</a></sup>. Peasants are a powerful force; despite centuries of dispossession, over half of the world’s arable land is still under their ownership<sup class="footnote-reference"><a href="#gUnVx3">28</a></sup>, and, despite industrial agriculture’s dominance in our food system, are major producers of food.</p>
<p>Smallholders (farmers with &lt;2ha of land) produce about a third of the world food supply (measured as calories) on about a quarter of the agricultural area (close to half of the food supply if farms &lt;5ha of land are included)<sup class="footnote-reference"><a href="#f91sr2">253</a></sup>. What this implies is that smallholders already have productivity that out pace larger-scale operations, even on land that may be marginal. Further research and development of agroecological, low-input methods have the possibility to increase this number even more. However, funding tends to disappear for researchers developing these techniques<sup class="footnote-reference"><a href="#6eT7sI">212</a></sup><sup class="footnote-reference"><a href="#jLJS3O">254</a></sup>. One example is that, following a $1.7 million donation to Iowa State University by the Koch Foundation (the Koch brothers own Koch Fertilizer), the university’s Aldo Leopold Center for Sustainable Agriculture had its funding pulled after 30 years<sup class="footnote-reference"><a href="#MDY1MW">255</a></sup>. Despite this, agroecological innovation happens outside of formal research settings through peer-to-peer knowledge exchange and development. Unlike the agricultural input industry, which is top-down and where products are pushed onto farmers who have essentially no input in their design, agroecological techniques are often co-created by peasants and refined to their own specific contexts<sup class="footnote-reference"><a href="#gUnVx3">28</a></sup>.</p>
<p>Agroecology is sometimes characterized as a romanticization of labor-intensive subsistence farming<sup class="footnote-reference"><a href="#NTAxNG">256</a></sup>. A lot of labor-saving technologies basically work by substituting human labor with fossil fuels. If we look at the energy efficiency of these technologies, we see a different picture: about five times energy (fossil fuels, mostly) go into one kg of cereal in industrialized countries vs farmers in Africa, with more drastic differences on a crop-by-crop comparison, such as 33 times energy in the US to produce one kilo of maize as a traditional farmer in Mexico<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup>. There are similar estimates for industrial food production more generally, 3kcal fossil fuel for 1kcal food<sup class="footnote-reference"><a href="#UrN_YO">152</a></sup>, with estimates as high as 7kcal for 1kcal<sup class="footnote-reference"><a href="#PtEeVD">153</a></sup> or 10kcal<sup class="footnote-reference"><a href="#loSDbG">213</a></sup><sup class="footnote-reference"><a href="#xZRHAQ">257</a></sup>. That the industrial-style of agriculture (input-heavy) is a net negative in terms of energy has been demonstrated since at least 1960s; which is characterized in terms of crops that are bred to maximize productivity in terms of the valuable parts of the crop (e.g. what is edible) at the expense of other functions, such as pest resistance, which are instead externalized to, for example, pesticides<sup class="footnote-reference"><a href="#Dy07it">258</a></sup>.</p>
<p>Similarly, agroecological methods have been characterized as equivalent to traditional subsistence practices or the movement as anti-technology<sup class="footnote-reference"><a href="#NDRlNz">259</a></sup>. It may be more appropriate to say that it has a different understanding of technology, measuring it not only by how useful it is in the field, but by what impacts it has on relationships. Does it create a dependency on finite resources and empower large companies? Does it involve buying into a system of debt<sup class="footnote-reference"><a href="#jLJS3O">254</a></sup>? “Technology” is also often conflated with industrial, large-scale, and energy-intensive processes, but traditional labor-saving practices like coppicing<sup class="footnote-reference"><a href="#YzcxZm">260</a></sup>or the ongoing development of perennial grains<sup class="footnote-reference"><a href="#MDI5YW">261</a></sup> can also be considered technologies of sorts. The previously mentioned fertilizer tree system is itself an outcome of research starting in the 1980’s on nitrogen fertilization alternatives, conducted with the participation of farmers<sup class="footnote-reference"><a href="#MzFjM2">248</a></sup>, offering an example of productive agroecological research. The Out of the Woods collective also describe “cyborg ecology”, where technology adoption should not be out of some binary commitment to a constructed purity around traditional techniques or modern technologies but out of evaluating what works without sacrificing ecological and social priorities<sup class="footnote-reference"><a href="#xvQJ09">251</a></sup>. The distributed production of solar fertilizers mentioned much earlier might fit this criteria.</p>
<p>Cuba is sometimes pointed to as an example of what agroecological practices could make possible on a larger scale. Cuban agriculture was once more akin to industrial, Green Revolution agriculture found elsewhere, supported by trade deals with the Soviet Union which supplied the necessary inputs: fossil fuels, fertilizers, machinery, etc.<sup class="footnote-reference"><a href="#WCjxSr">143</a></sup><sup class="footnote-reference"><a href="#N5Xxen">252</a></sup> When the Soviet Union collapsed, these inputs were suddenly unavailable, resulting in GDP and calorie consumption each plummeting by one-third<sup class="footnote-reference"><a href="#uINpOc">262</a></sup><sup class="footnote-reference"><a href="#mTmy0d">263</a></sup><sup class="footnote-reference"><a href="#s7wSmH">222</a></sup><sup class="footnote-reference"><a href="#hNT-Wb">264</a></sup><sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. Ongoing US blockades prevented dumping of cheap food into the Cuban market, further forcing Cuba to develop its own self-sufficiency in the absence of these inputs<sup class="footnote-reference"><a href="#s7wSmH">222</a></sup>.</p>
<p>Through this “Special Period”, land reform redistributed over 1 million hectares of state-owned land to a variety of cooperatives and individuals<sup class="footnote-reference"><a href="#uINpOc">262</a></sup><sup class="footnote-reference"><a href="#mTmy0d">263</a></sup><sup class="footnote-reference"><a href="#WCjxSr">143</a></sup><sup class="footnote-reference"><a href="#N5Xxen">252</a></sup><sup class="footnote-reference"><a href="#hNT-Wb">264</a></sup> (under usufruct terms, so most of the land is still state-owned<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>). Cuba went on to achieve the highest per capita food growth rates in Latin America<sup class="footnote-reference"><a href="#N5Xxen">252</a></sup>, facilitated by the land reform and the adoption and peer-to-peer transmission of agroecological techniques via peasant movements such as <em>Campesino-a-Campesino</em><sup class="footnote-reference"><a href="#N5Xxen">252</a></sup><sup class="footnote-reference"><a href="#s7wSmH">222</a></sup><sup class="footnote-reference"><a href="#WCjxSr">143</a></sup><sup class="footnote-reference"><a href="#gUnVx3">28</a></sup>–the latter of which was ongoing, but provided an opportunity to expand after the forced withdrawal of the industrial regime<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. Over 65% of the country’s food is produced by peasant family farms on 35% of the total arable land.<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>Cuban urban gardens, <em>organopónicos</em>, also a legacy of the post-Soviet “Special Period”, produce as much as 70% of the fresh vegetables consumed in cities<sup class="footnote-reference"><a href="#uINpOc">262</a></sup><sup class="footnote-reference"><a href="#mTmy0d">263</a></sup> and 50% of the produce for the entire country<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. Lower levels of dissolved nitrogen in the island’s rivers, compared to the US’s Mississippi River Basin, is speculated to be a consequence of this shift in farming practices<sup class="footnote-reference"><a href="#ddQXKa">265</a></sup>.</p>
<p>This is not to say Cuban agriculture is fully agroecological–there are still conventional farms (usually state-run) and varying adoption of agroecological techniques<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. There is still some dependency on oil for agriculture, though those who have adopted agroecology are more resilient to its absence, such as from US sanctions this past year<sup class="footnote-reference"><a href="#CyLLCM">266</a></sup>.</p>
<p>Cuba’s food system still has other issues, such as with food waste, which is comparable to rates elsewhere, and generally attributed to infrastructural inadequacies rather than the overproduction and market-driven causes in the global north<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. Yet this still results in inadequate food for many.</p>
<p>Pressure from agribusiness entering into Cuba<sup class="footnote-reference"><a href="#dI882e">267</a></sup>, especially with opening Cuba-US relations (for example: a Cargill-associated “US Agriculture Coalition for Cuba” seeks to “to lift the embargo in order to liberalize trade and investment and reestablish Cuba as a market for US products”<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>), and tensions within the country with some leaders advocating for higher-input/more conventional systems<sup class="footnote-reference"><a href="#mTmy0d">263</a></sup>. Changing relationships with the US may be the largest determinant of how Cuban agriculture changes in the future, with fears that it may become more focused on export for organic food markets and less on supplying domestic needs<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>.</p>
<p>Cuba’s dependency on expensive food imports has also increased<sup class="footnote-reference"><a href="#WCjxSr">143</a></sup> which has made expanded self-sufficiency a priority. Laws were passed in 2008 and 2012 to enact a further distribution of 1.7 million hectares of land to over 200,000 farmers, with roughly an additional 900,00 hectares up for distribution in 2017<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. The impacts so far are unclear – the overall amount of food imports is contested, with one figure placing it at 40%<sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. Hurricanes increase Cuba’s dependency on food imports, though the agroecological farms tend to recover more quickly than monoculture farms<sup class="footnote-reference"><a href="#mTmy0d">263</a></sup><sup class="footnote-reference"><a href="#y3elP8">163</a></sup>. Though Cuba’s food system is not perfect, it shows that an agroecological system is worthwhile and achievable.</p>
<h2>Conclusion: Healing the Rift</h2>
<p>The focus here has been on food, but these issues will become more pressing as the economy–if we are to adequately address climate change–shifts back to one with greater dependence on biomass for materials. Consider that <a href="https://www.ranken-energy.com/index.php/products-made-from-petroleum/">a tremendous amount of materials are petroleum-derived</a> or otherwise produced from non-renewable resources<sup class="footnote-reference"><a href="#tn7pv5">246</a></sup>–including those that industrial agriculture rely on<sup class="footnote-reference"><a href="#gUnVx3">28</a></sup>. Switching to bioplastics, for instance, can have greater environmental impacts and greenhouse gas emissions than petroleum-based plastics due to land use change<sup class="footnote-reference"><a href="#r0Ivkr">268</a></sup>.</p>
<p>Climate change will lead to an aggregate decrease in agricultural productivity<sup class="footnote-reference"><a href="#9JGUIY">269</a></sup><sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup><sup class="footnote-reference"><a href="#ixNtii">10</a></sup>, increasing the number and scale of droughts and heatwaves<sup class="footnote-reference"><a href="#Q_PkPf">270</a></sup> and eroding and submerging productive land<sup class="footnote-reference"><a href="#ZmFlM2">271</a></sup>. Food prices would rise and possibly encourage an influx of investors and speculation. We could see climate change and its effects on food production used to increase pressure of technocratic development authorities to act with a stronger mandate to implement Green Revolution-style programs and strengthen the narrative of peasants using land unproductively and as justification for land grabs. Climate change is already having an effect on displacing farmers<sup class="footnote-reference"><a href="#n67Qtk">228</a></sup>.</p>
<p>The key cause for these issues with conventional agriculture stem from the fact that it is not designed to fulfill a need—i.e. sustenance and nutrition, though it is often spoken as such in policy and popular discourse—but rather, it is designed to produce and sell commodities. There is a huge dissonance between the refrain of FAO population projections and the need to increase food production to feed them, when the current system of tremendous output fails to feed even the people we have now.</p>
<p>A report from Nature notes that, “[p]roducing enough food for the world’s population in 2050 will be easy.”<sup class="footnote-reference"><a href="#6eT7sI">212</a></sup>. The report goes on to note, the more urgent challenges are sustainable productivity and, more importantly, poverty–poverty that is itself produced by this productivist agricultural regime. As the authors note:</p>
<blockquote>
<p>The 2008 food crisis, which pushed around 100 million people into hunger, was not so much a result of a food shortage as of a market volatility — with causes going far beyond supply and demand — that sent prices through the roof and sparked riots in several countries.<sup class="footnote-reference"><a href="#6eT7sI">212</a></sup></p>
</blockquote>
<p>A recent paper similarly suggests that almost 11 billion people can be adequately fed within planetary boundaries, but it requires a radical restructuring of global agriculture<sup class="footnote-reference"><a href="#bqL_FO">14</a></sup>.</p>
<p>One way to support this restructuring is to return wealth that has been extracted from these post-colonial nations and invest it in agricultural infrastructure that support greater food autonomy. It can mean increasing public research for agroecological methods and land reform, such as redistributing land back to those who have stewarded it for generations<sup class="footnote-reference"><a href="#9NGONY">198</a></sup>. It requires moving on from the concept of <em>food security</em>–market access to food–to <em>food sovereignty</em>: producing food for need, prioritizing agroecological methods, local production and control<sup class="footnote-reference"><a href="#6IG7Q7">195</a></sup><sup class="footnote-reference"><a href="#dxkGaV">272</a></sup><sup class="footnote-reference"><a href="#PtEeVD">153</a></sup>, and restoring more context-appropriate traditional crops where they have been displaced by commodity crops<sup class="footnote-reference"><a href="#n1iP7n">196</a></sup>.</p>
<p>The problems of fertilizer are inseparable from the broader political and economic problems of food production. Throughout history people have recognized how a community’s control over their own means of living is a prerequisite for flourishing and self-determination. As Vann R. Newkirk II notes in his “<a href="https://www.theatlantic.com/magazine/archive/2019/09/this-land-was-our-land/594742/">The Great Land Robbery</a>”:</p>
<blockquote>
<p>There’s a reason the fabled promise that spread among freedmen after the Civil War was not a check, a job, or a refundable tax credit, but 40 acres of farmland to call home.</p>
</blockquote>
<div class="footnote-definition" id="EnFQPP"><sup class="footnote-definition-label">216</sup>
<p>‘Green Revolution’ Trapping India’s Farmers In Debt. Daniel Zwerdling. April 19, 2009. <a href="https://www.npr.org/2009/04/14/102944731/green-revolution-trapping-indias-farmers-in-debt">https://www.npr.org/2009/04/14/102944731/green-revolution-trapping-indias-farmers-in-debt</a></p>
</div>
<div class="footnote-definition" id="fWrS7d"><sup class="footnote-definition-label">190</sup>
<p>2018 Farm Bill Drilldown: Commodity Programs and Crop Insurance. National Sustainable Agriculture Coalition. December 14, 2018. <a href="https://sustainableagriculture.net/blog/2018-farm-bill-commodity-subsidies-crop-insurance/">https://sustainableagriculture.net/blog/2018-farm-bill-commodity-subsidies-crop-insurance/</a></p>
</div>
<div class="footnote-definition" id="reIkR1"><sup class="footnote-definition-label">45</sup>
<p><a href="https://www.yara.com/crop-nutrition/why-fertilizer/production-of-fertillizer/">https://www.yara.com/crop-nutrition/why-fertilizer/production-of-fertillizer/</a></p>
</div>
<div class="footnote-definition" id="b5dodc"><sup class="footnote-definition-label">167</sup>
<p>A Farmer Living Wage. National Family Farm Coalition. Retrieved from <a href="https://nffc.net/what-we-do/farmer-living-wage/">https://nffc.net/what-we-do/farmer-living-wage/</a></p>
</div>
<div class="footnote-definition" id="YTe4xu"><sup class="footnote-definition-label">273</sup>
<p>A new way to curb nitrogen pollution: Regulate fertilizer producers, not just farmers. David Kanter. January 20, 2019. <a href="https://www.salon.com/2019/01/20/a-new-way-to-curb-nitrogen-pollution-regulate-fertilizer-producers-not-just-farmers_partner/">https://www.salon.com/2019/01/20/a-new-way-to-curb-nitrogen-pollution-regulate-fertilizer-producers-not-just-farmers_partner/</a></p>
</div>
<div class="footnote-definition" id="VzyJ_R"><sup class="footnote-definition-label">170</sup>
<p>A Report on the United Farmers and Rancher Congress. September 11, 1996.</p>
</div>
<div class="footnote-definition" id="6E6B74"><sup class="footnote-definition-label">115</sup>
<p>A sustainable, energy-saving way to make the key ingredient in fertilizers. Xiaofeng Feng. May 23, 2018. <a href="https://theconversation.com/a-sustainable-energy-saving-way-to-make-the-key-ingredient-in-fertilizers-96693">https://theconversation.com/a-sustainable-energy-saving-way-to-make-the-key-ingredient-in-fertilizers-96693</a></p>
</div>
<div class="footnote-definition" id="b0fCi_"><sup class="footnote-definition-label">239</sup>
<p>After Geoengineering: Climate Tragedy, Repair, and Restoration. Holly Jean Buck.</p>
</div>
<div class="footnote-definition" id="eZiX81"><sup class="footnote-definition-label">244</sup>
<p>Agrarian Dreams: The Paradox of Organic Farming in California. Julie Guthman. 2004.</p>
</div>
<div class="footnote-definition" id="tn7pv5"><sup class="footnote-definition-label">246</sup>
<p>Ajl, M. (2014). The hypertrophic city versus the planet of fields. Implosions/Explosions: towards a study of planetary urbanization, 533-550.</p>
</div>
<div class="footnote-definition" id="5PpnDo"><sup class="footnote-definition-label">125</sup>
<p>Alexander, C., Gregson, N., &amp; Gille, Z. (2013). Food waste. The handbook of food research, 1, 471-483.</p>
</div>
<div class="footnote-definition" id="GSSnjs"><sup class="footnote-definition-label">4</sup>
<p>Allen, R. C. (2008). The nitrogen hypothesis and the English agricultural revolution: A biological analysis. The Journal of Economic History, 68(1), 182-210.</p>
</div>
<div class="footnote-definition" id="mTmy0d"><sup class="footnote-definition-label">263</sup>
<p>Altieri, M. A., &amp; Funes-Monzote, F. R. (2012). The paradox of Cuban agriculture. Monthly Review, 63(8), 23-33.</p>
</div>
<div class="footnote-definition" id="eYEaIk"><sup class="footnote-definition-label">83</sup>
<p>Altieri, M. A., &amp; Nicholls, C. I. (2003). Soil fertility management and insect pests: harmonizing soil and plant health in agroecosystems. Soil and Tillage Research, 72(2), 203-211.</p>
</div>
<div class="footnote-definition" id="wnfN5D"><sup class="footnote-definition-label">53</sup>
<p>Amann, A., Zoboli, O., Krampe, J., Rechberger, H., Zessner, M., &amp; Egle, L. (2018). Environmental impacts of phosphorus recovery from municipal wastewater. Resources, Conservation and Recycling, 130, 127-139.</p>
</div>
<div class="footnote-definition" id="h86-LB"><sup class="footnote-definition-label">93</sup>
<p>Anton, A., Montero, J. I., Munoz, P., &amp; Castells, F. (2005). LCA and tomato production in Mediterranean greenhouses. International Journal of Agricultural Resources, Governance and Ecology, 4(2), 102-112.</p>
</div>
<div class="footnote-definition" id="plIvni"><sup class="footnote-definition-label">135</sup>
<p>Backer, R., Rokem, J. S., Ilangumaran, G., Lamont, J., Praslickova, D., Ricci, E., … &amp; Smith, D. L. (2018). Plant growth-promoting rhizobacteria: context, mechanisms of action, and roadmap to commercialization of biostimulants for sustainable agriculture. Frontiers in plant science, 9.</p>
</div>
<div class="footnote-definition" id="WCMLES"><sup class="footnote-definition-label">3</sup>
<p>Badgley, C., Moghtader, J., Quintero, E., Zakem, E., Chappell, M. J., Aviles-Vazquez, K., … &amp; Perfecto, I. (2007). Organic agriculture and the global food supply. Renewable agriculture and food systems, 22(2), 86-108.</p>
</div>
<div class="footnote-definition" id="h2pcn_"><sup class="footnote-definition-label">162</sup>
<p>Baker, G. A., Gray, L. C., Harwood, M. J., Osland, T. J., &amp; Tooley, J. B. C. (2019). On-farm food loss in northern and central California: Results of field survey measurements. Resources, Conservation and Recycling, 149, 541-549.</p>
</div>
<div class="footnote-definition" id="7r2zQD"><sup class="footnote-definition-label">106</sup>
<p>Banerjee, C., &amp; Adenaeuer, L. (2014). Up, up and away! The economics of vertical farming. Journal of Agricultural Studies, 2(1), 40-60.</p>
</div>
<div class="footnote-definition" id="6_E3PQ"><sup class="footnote-definition-label">104</sup>
<p>Barbosa, G., Gadelha, F., Kublik, N., Proctor, A., Reichelm, L., Weissinger, E., … &amp; Halden, R. (2015). Comparison of land, water, and energy requirements of lettuce grown using hydroponic vs. conventional agricultural methods. International journal of environmental research and public health, 12(6), 6879-6891.</p>
</div>
<div class="footnote-definition" id="84MAkf"><sup class="footnote-definition-label">201</sup>
<p>Barkin, D. (1987). The end to food self-sufficiency in Mexico. Latin American Perspectives, 14(3), 271-297.</p>
</div>
<div class="footnote-definition" id="IELAEl"><sup class="footnote-definition-label">200</sup>
<p>Barkin, D. (2002). The reconstruction of a modern Mexican peasantry. The Journal of Peasant Studies, 30(1), 73-90.</p>
</div>
<div class="footnote-definition" id="9NGONY"><sup class="footnote-definition-label">198</sup>
<p>Barkin, D. (2005). Wealth, poverty and sustainable development (No. 0506003). University Library of Munich, Germany.</p>
</div>
<div class="footnote-definition" id="XG2blE"><sup class="footnote-definition-label">139</sup>
<p>Bayer and Ginkgo Bioworks Unveil Joint Venture, Joyn Bio, and Establish Operations in Boston and West Sacramento. March 20, 2018. <a href="https://www.prnewswire.com/news-releases/bayer-and-ginkgo-bioworks-unveil-joint-venture-joyn-bio-and-establish-operations-in-boston-and-west-sacramento-300616544.html">https://www.prnewswire.com/news-releases/bayer-and-ginkgo-bioworks-unveil-joint-venture-joyn-bio-and-establish-operations-in-boston-and-west-sacramento-300616544.html</a></p>
</div>
<div class="footnote-definition" id="XCXZkD"><sup class="footnote-definition-label">274</sup>
<p>Belavina, E. (2020). Grocery store density and food waste. Manufacturing &amp; Service Operations Management.</p>
</div>
<div class="footnote-definition" id="asKMyE"><sup class="footnote-definition-label">96</sup>
<p>BENIS, K., GOMES, R., VICENTE, R., FERRAO, P., &amp; FERNANDEZ, J. (2015). Rooftop greenhouses: LCA and energy simulation. In Proceedings of International Conference CISBAT 2015 Future Buildings and Districts Sustainability from Nano to Urban Scale (No. CONF, pp. 95-100). LESO-PB, EPFL.</p>
</div>
<div class="footnote-definition" id="Q6OKTn"><sup class="footnote-definition-label">105</sup>
<p>Benke, K., &amp; Tomkins, B. (2017). Future food-production systems: vertical farming and controlled-environment agriculture. Sustainability: Science, Practice and Policy, 13(1), 13-26.</p>
</div>
<div class="footnote-definition" id="Qk2cSx"><sup class="footnote-definition-label">243</sup>
<p>Big Food is Betting on Regenerative Agriculture to Thwart Climate Change. Gosia Wozniacka. October 29, 2019. Retrieved from <a href="https://civileats.com/2019/10/29/big-food-is-betting-on-regenerative-agriculture-to-thwart-climate-change/">https://civileats.com/2019/10/29/big-food-is-betting-on-regenerative-agriculture-to-thwart-climate-change/</a></p>
</div>
<div class="footnote-definition" id="loSDbG"><sup class="footnote-definition-label">213</sup>
<p>Biel, R. A. (2016). Sustainable Food Systems (pp. 74-89). UCL press.</p>
</div>
<div class="footnote-definition" id="_m8LJj"><sup class="footnote-definition-label">141</sup>
<p>Biofertilizer. The Azolla Foundation. <a href="http://theazollafoundation.org/azollas-uses/as-a-biofertilizer/">http://theazollafoundation.org/azollas-uses/as-a-biofertilizer/</a></p>
</div>
<div class="footnote-definition" id="THbpjP"><sup class="footnote-definition-label">121</sup>
<p>BioNitrogen in bankruptcy. Trevor Brown. November 6, 2015. Retrieved from <a href="https://ammoniaindustry.com/bionitrogen-in-bankruptcy/">https://ammoniaindustry.com/bionitrogen-in-bankruptcy/</a></p>
</div>
<div class="footnote-definition" id="f9wFWQ"><sup class="footnote-definition-label">188</sup>
<p>Blaikie, P. (1985). The political economy of soil erosion in developing countries. Routledge.</p>
</div>
<div class="footnote-definition" id="0HzIQD"><sup class="footnote-definition-label">158</sup>
<p>Bovay, J., &amp; Zhang, W. (2019). A Century of Profligacy? The Measurement and Evolution of Food Waste. Agricultural and Resource Economics Review, 1-35.</p>
</div>
<div class="footnote-definition" id="5DPB-1"><sup class="footnote-definition-label">218</sup>
<p>Brunelle, T., Dumas, P., Souty, F., Dorin, B., &amp; Nadaud, F. (2015). Evaluating the impact of rising fertilizer prices on crop yields. Agricultural economics, 46(5), 653-666.</p>
</div>
<div class="footnote-definition" id="_D3qLb"><sup class="footnote-definition-label">173</sup>
<p>Burns, C., &amp; MacDonald, J. M. (2018). America’s Diverse Family Farms: 2018 Edition. EIB-203, USDA-Economic Research Service.</p>
</div>
<div class="footnote-definition" id="b4aLnX"><sup class="footnote-definition-label">12</sup>
<p>Calabi-Floody, M., Medina, J., Rumpel, C., Condron, L. M., Hernandez, M., Dumont, M., &amp; de la Luz Mora, M. (2018). Smart fertilizers as a strategy for sustainable agriculture. In Advances in Agronomy (Vol. 147, pp. 119-157). Academic Press.</p>
</div>
<div class="footnote-definition" id="9MgKCM"><sup class="footnote-definition-label">19</sup>
<p>Campbell, B. M., Beare, D. J., Bennett, E. M., Hall-Spencer, J. M., Ingram, J. S., Jaramillo, F., … &amp; Shindell, D. (2017). Agriculture production as a major driver of the Earth system exceeding planetary boundaries. Ecology and Society, 22(4).</p>
</div>
<div class="footnote-definition" id="OHQZsm"><sup class="footnote-definition-label">67</sup>
<p>Camprubí, L. (2015). Resource geopolitics: Cold war technologies, global fertilizers, and the fate of Western Sahara. Technology and Culture, 56(3), 676-703.</p>
</div>
<div class="footnote-definition" id="aolgfP"><sup class="footnote-definition-label">147</sup>
<p>Canter, C. E., Qin, Z., Cai, H., Dunn, J. B., Wang, M., &amp; Scott, D. A. (2017). Fossil energy consumption and greenhouse gas emissions, including soil carbon effects, of producing agriculture and forestry feedstocks. In: Efroymson, RA; Langholtz, MH; Johnson, KE; Stokes, BJ, eds. 2016 billion-ton report: Advancing domestic resources for a thriving bioeconomy. Volume 2: Environmental sustainability effects of select scenarios from volume 1. ORNL/TM-2016/727. Oak Ridge, TN: Oak Ridge National Laboratory: 85-137., 2017, 85-137.</p>
</div>
<div class="footnote-definition" id="Hxo980"><sup class="footnote-definition-label">50</sup>
<p>Cañedo-Argüelles, M., Brucet, S., Carrasco, S., Flor-Arnau, N., Ordeix, M., Ponsá, S., &amp; Coring, E. (2017). Effects of potash mining on river ecosystems: An experimental study. Environmental pollution, 224, 759-770.</p>
</div>
<div class="footnote-definition" id="lb85Sy"><sup class="footnote-definition-label">122</sup>
<p>Casselton, ND — Agrebon. Trevor Brown. November 1, 2013. Retrieved from <a href="https://ammoniaindustry.com/casselton-nd-agrebon/">https://ammoniaindustry.com/casselton-nd-agrebon/</a></p>
</div>
<div class="footnote-definition" id="Q0wkwe"><sup class="footnote-definition-label">129</sup>
<p>Chan, K. Y., &amp; Xu, Z. (2012). Biochar: nutrient properties and their enhancement. In Biochar for environmental management (pp. 99-116). Routledge.</p>
</div>
<div class="footnote-definition" id="Gqa5At"><sup class="footnote-definition-label">84</sup>
<p>Chau, L. M., &amp; Heong, K. L. (2005). Effects of organic fertilizers on insect pest and diseases of rice. Omonrice, 13, 26-33.</p>
</div>
<div class="footnote-definition" id="_OSfgz"><sup class="footnote-definition-label">43</sup>
<p>Claassen, R., Langpap, C., &amp; Wu, J. (2016). Impacts of federal crop insurance on land use and environmental quality. American Journal of Agricultural Economics, 99(3), 592-613.</p>
</div>
<div class="footnote-definition" id="F4mkgE"><sup class="footnote-definition-label">60</sup>
<p>Clark, B., &amp; Foster, J. B. (2009). Ecological imperialism and the global metabolic rift: Unequal exchange and the guano/nitrates trade. International Journal of Comparative Sociology, 50(3-4), 311-334.</p>
</div>
<div class="footnote-definition" id="MYgqN5"><sup class="footnote-definition-label">13</sup>
<p>Clark, M., &amp; Tilman, D. (2017). Comparative analysis of environmental impacts of agricultural production systems, agricultural input efficiency, and food choice. Environmental Research Letters, 12(6), 064016.</p>
</div>
<div class="footnote-definition" id="9JGUIY"><sup class="footnote-definition-label">269</sup>
<p>Climate Change and Land: Summary for Policymakers. IPCC. 2019.</p>
</div>
<div class="footnote-definition" id="6Q6GJj"><sup class="footnote-definition-label">221</sup>
<p>Climate Change and Rising Food Prices Heightened Arab Spring. Ines Perez. March 4, 2013. Retrieved from <a href="https://www.scientificamerican.com/article/climate-change-and-rising-food-prices-heightened-arab-spring/">https://www.scientificamerican.com/article/climate-change-and-rising-food-prices-heightened-arab-spring/</a></p>
</div>
<div class="footnote-definition" id="PtEeVD"><sup class="footnote-definition-label">153</sup>
<p>Cloke, J. (2013). Empires of waste and the food security meme. Geography Compass, 7(9), 622-636.</p>
</div>
<div class="footnote-definition" id="dxkGaV"><sup class="footnote-definition-label">272</sup>
<p>Cochrane, L. (2011). Food security or food sovereignty: The case of land grabs. The Journal of Humanitarian Assistance, 5.</p>
</div>
<div class="footnote-definition" id="xSNOuh"><sup class="footnote-definition-label">66</sup>
<p>Connell, J. (2006). Nauru: The first failed Pacific state?. The Round Table, 95(383), 47-63.</p>
</div>
<div class="footnote-definition" id="xvQJ09"><sup class="footnote-definition-label">251</sup>
<p>Contemporary agriculture: climate, capital, and cyborg ecology. Out of the Woods. Retrieved from <a href="https://libcom.org/blog/contemporary-agriculture-climate-capital-cyborg-ecology-17072015">https://libcom.org/blog/contemporary-agriculture-climate-capital-cyborg-ecology-17072015</a></p>
</div>
<div class="footnote-definition" id="8j9-vn"><sup class="footnote-definition-label">55</sup>
<p>Cooper, J., Lombardi, R., Boardman, D., &amp; Carliell-Marquet, C. (2011). The future distribution and production of global phosphate rock reserves. Resources, Conservation and Recycling, 57, 78-86.</p>
</div>
<div class="footnote-definition" id="S827v1"><sup class="footnote-definition-label">17</sup>
<p>Cordell, D., Drangert, J. O., &amp; White, S. (2009). The story of phosphorus: global food security and food for thought. Global environmental change, 19(2), 292-305.</p>
</div>
<div class="footnote-definition" id="T5XG95"><sup class="footnote-definition-label">18</sup>
<p>Cordell, D., Turner, A., &amp; Chong, J. (2015). The hidden cost of phosphate fertilizers: mapping multi-stakeholder supply chain risks and impacts from mine to fork. Global Change, Peace &amp; Security, 27(3), 323-343.</p>
</div>
<div class="footnote-definition" id="yjhees"><sup class="footnote-definition-label">204</sup>
<p>Crawford, E. W., Jayne, T. S., &amp; Kelly, V. A. (2005). Alternative approaches for promoting fertilizer use in africa, with emphasis on the role of subsidies (No. 1095-2016-88224).</p>
</div>
<div class="footnote-definition" id="YDe1no"><sup class="footnote-definition-label">42</sup>
<p>Crop insurance is good for farmers, but not always for the environment. Don Fullerton, Julian Reif, Megan Konar, Tatyana Deryugina. June 29, 2018. <a href="https://theconversation.com/crop-insurance-is-good-for-farmers-but-not-always-for-the-environment-96841">https://theconversation.com/crop-insurance-is-good-for-farmers-but-not-always-for-the-environment-96841</a></p>
</div>
<div class="footnote-definition" id="CyLLCM"><sup class="footnote-definition-label">266</sup>
<p>Cuba faces squeeze on food production as US oil sanctions bite. Ed Augustin. March 18, 2020. Retrieved from <a href="https://www.theguardian.com/world/2020/mar/18/cuba-food-production-us-oil-sanctions">https://www.theguardian.com/world/2020/mar/18/cuba-food-production-us-oil-sanctions</a></p>
</div>
<div class="footnote-definition" id="ddQXKa"><sup class="footnote-definition-label">265</sup>
<p>Cuba’s rivers run clean after decades of sustainable farming. February 4, 2020. Retrieved from <a href="https://www.nature.com/articles/d41586-020-00263-6">https://www.nature.com/articles/d41586-020-00263-6</a></p>
</div>
<div class="footnote-definition" id="1TDaoD"><sup class="footnote-definition-label">59</sup>
<p>Cushman, G. T. (2013). Guano and the opening of the Pacific world: a global ecological history. Cambridge University Press.</p>
</div>
<div class="footnote-definition" id="2MKEqv"><sup class="footnote-definition-label">154</sup>
<p>Cuéllar, A. D., &amp; Webber, M. E. (2010). Wasted food, wasted energy: the embedded energy in food waste in the United States. Environmental science &amp; technology, 44(16), 6464-6469.</p>
</div>
<div class="footnote-definition" id="11eLmt"><sup class="footnote-definition-label">6</sup>
<p>Dawson, C. J., &amp; Hilton, J. (2011). Fertiliser availability in a resource-limited world: Production and recycling of nitrogen and phosphorus. Food Policy, 36, S14-S22.</p>
</div>
<div class="footnote-definition" id="QiuPBf"><sup class="footnote-definition-label">202</sup>
<p>de Graaff, J., Kessler, A., &amp; Nibbering, J. W. (2011). Agriculture and food security in selected countries in Sub-Saharan Africa: diversity in trends and opportunities. Food Security, 3(2), 195-213.</p>
</div>
<div class="footnote-definition" id="vbD7xV"><sup class="footnote-definition-label">134</sup>
<p>Death by fertilizer. Nathanael Johnson. October 2, 2018. <a href="https://grist.org/article/billionaires-and-bacteria-are-racing-to-save-us-from-death-by-fertilizer/">https://grist.org/article/billionaires-and-bacteria-are-racing-to-save-us-from-death-by-fertilizer/</a></p>
</div>
<div class="footnote-definition" id="JmE9nH"><sup class="footnote-definition-label">85</sup>
<p>Do industrial agricultural methods actually yield more food per acre than organic ones? Nathanael Johnson. October 14, 2015. <a href="https://grist.org/food/do-industrial-agricultural-methods-actually-yield-more-food-per-acre-than-organic-ones/">https://grist.org/food/do-industrial-agricultural-methods-actually-yield-more-food-per-acre-than-organic-ones/</a></p>
</div>
<div class="footnote-definition" id="-MnR_A"><sup class="footnote-definition-label">275</sup>
<p>Don’t End Agricultural Subsidies, Fix Them. Mark Bittman. March 1, 2011. Retrieved from <a href="https://opinionator.blogs.nytimes.com/2011/03/01/dont-end-agricultural-subsidies-fix-them/">https://opinionator.blogs.nytimes.com/2011/03/01/dont-end-agricultural-subsidies-fix-them/</a></p>
</div>
<div class="footnote-definition" id="ixNtii"><sup class="footnote-definition-label">10</sup>
<p>Díaz, S., Settele, J., Brondízio, E., Ngo, H., Guèze, M., Agard, J., … &amp; Chan, K. (2019). Summary for policymakers of the global assessment report on biodiversity and ecosystem services of the Intergovernmental Science-Policy Platform on Biodiversity and Ecosystem Services.</p>
</div>
<div class="footnote-definition" id="uINpOc"><sup class="footnote-definition-label">262</sup>
<p>Eat Local: Cuba’s Urban Gardens Raise Food on Zero Emissions. Max Ajl. January 27, 2009. <a href="https://insideclimatenews.org/news/20090127/eat-local-cubas-urban-gardens-raise-food-zero-emissions">https://insideclimatenews.org/news/20090127/eat-local-cubas-urban-gardens-raise-food-zero-emissions</a></p>
</div>
<div class="footnote-definition" id="rv81w9"><sup class="footnote-definition-label">95</sup>
<p>Edmondson, J. L., Cunningham, H., Tingley, D. O. D., Dobson, M. C., Grafius, D. R., Leake, J. R., … &amp; Stovin, V. (2020). The hidden potential of urban horticulture. Nature Food, 1(3), 155-159.</p>
</div>
<div class="footnote-definition" id="dYKznm"><sup class="footnote-definition-label">64</sup>
<p>Edwards, J. B. (2014). Phosphate mining and the relocation of the Banabans to northern Fiji in 1945: Lessons for climate change-forced displacement. Journal de la Société des Océanistes, (138-139), 121-136.</p>
</div>
<div class="footnote-definition" id="MUqB6Z"><sup class="footnote-definition-label">98</sup>
<p>El-Essawy, H., Nasr, P., &amp; Sewilam, H. (2019). Aquaponics: a sustainable alternative to conventional agriculture in Egypt–a pilot scale investigation. Environmental Science and Pollution Research, 26(16), 15872-15883.</p>
</div>
<div class="footnote-definition" id="PRW7gt"><sup class="footnote-definition-label">276</sup>
<p>Facilitate the Growth of Organic by Ending Subsidies for Chemical Inputs. Joelle Katto Andrighetto. October 10, 2018.</p>
</div>
<div class="footnote-definition" id="BKp6ry"><sup class="footnote-definition-label">46</sup>
<p>Fact Book 2018. Nutrien. 2018.</p>
</div>
<div class="footnote-definition" id="uCnTzV"><sup class="footnote-definition-label">169</sup>
<p>Fair Prices for Farmers. National Family Farm Coalition. Retrieved from <a href="https://nffc.net/what-we-do/fair-prices-for-farmers/">https://nffc.net/what-we-do/fair-prices-for-farmers/</a></p>
</div>
<div class="footnote-definition" id="ey5TJ-"><sup class="footnote-definition-label">277</sup>
<p>Fan, M. S., Zhao, F. J., Fairweather-Tait, S. J., Poulton, P. R., Dunham, S. J., &amp; McGrath, S. P. (2008). Evidence of decreasing mineral density in wheat grain over the last 160 years. Journal of Trace Elements in Medicine and Biology, 22(4), 315-324.</p>
</div>
<div class="footnote-definition" id="U_wMMf"><sup class="footnote-definition-label">233</sup>
<p>FAO Economic and Social Development Department, 2009. “From Land Grab to Win-Win - Seizing the Opportunities of International Investments in Agriculture,” FAO - Economic and Social Perspectives 4EN, Economic and Social Development Department of the Food and Agriculture Organization of the United Nations (FAO).</p>
</div>
<div class="footnote-definition" id="dh6wYo"><sup class="footnote-definition-label">178</sup>
<p>Farm loan delinquencies highest in 9 years as prices slump. Roxana Hegeman. February 28, 2019. <a href="https://www.apnews.com/7881b72df9aa41c28900acba09558e5e">https://www.apnews.com/7881b72df9aa41c28900acba09558e5e</a></p>
</div>
<div class="footnote-definition" id="OhftRW"><sup class="footnote-definition-label">185</sup>
<p>Farmworkers’ Low Wage Rates Have Risen Modestly; Now Congress May Pass a Law to Lower Them. Madeline Ramey. September 19, 2018. Retrieved from <a href="https://www.farmworkerjustice.org/fj-blog/2018/09/farmworkers-low-wage-rates-have-risen-modestly-now-congress-may-pass-law-lower-them">https://www.farmworkerjustice.org/fj-blog/2018/09/farmworkers-low-wage-rates-have-risen-modestly-now-congress-may-pass-law-lower-them</a></p>
</div>
<div class="footnote-definition" id="DJbgTR"><sup class="footnote-definition-label">9</sup>
<p>Farming’s growing problem. Joe Wertz. January 22, 2020. Retrieved from <a href="https://publicintegrity.org/environment/unintended-consequences-farming-fertilizer-climate-health-water-nitrogen/">https://publicintegrity.org/environment/unintended-consequences-farming-fertilizer-climate-health-water-nitrogen/</a></p>
</div>
<div class="footnote-definition" id="y3elP8"><sup class="footnote-definition-label">163</sup>
<p>Fernandez, M., Williams, J., Figueroa, G., Lovelace, G. G., Machado, M., Vasquez, L., … &amp; Aguilar, F. F. (2018). New opportunities, new challenges: Harnessing Cuba’s advances in agroecology and sustainable agriculture in the context of changing relations with the United States. Elem Sci Anth, 6(1).</p>
</div>
<div class="footnote-definition" id="ir4dKG"><sup class="footnote-definition-label">177</sup>
<p>Fertilizer dealer Nutrien aims to triple U.S. farm loans, guided by ex-Walmart executive. Rod Nickel. May 31, 2019. <a href="https://www.reuters.com/article/us-nutrien-farming-loans-exclusive/exclsuive-fertilizer-dealer-nutrien-aims-to-triple-u-s-farm-loans-guided-by-ex-walmart-executive-idUSKCN1T12AL">https://www.reuters.com/article/us-nutrien-farming-loans-exclusive/exclsuive-fertilizer-dealer-nutrien-aims-to-triple-u-s-farm-loans-guided-by-ex-walmart-executive-idUSKCN1T12AL</a></p>
</div>
<div class="footnote-definition" id="Dkw7o3"><sup class="footnote-definition-label">47</sup>
<p>Fertilizer Plants Spring Up to Take Advantage of U.S.’s Cheap Natural Gas. Celeste LeCompte. April 25, 2013. <a href="https://www.scientificamerican.com/article/fertilizer-plants-grow-thanks-to-cheap-natural-gas/">https://www.scientificamerican.com/article/fertilizer-plants-grow-thanks-to-cheap-natural-gas/</a></p>
</div>
<div class="footnote-definition" id="k-cu1b"><sup class="footnote-definition-label">80</sup>
<p>Flores-Félix, J. D., Menéndez, E., Rivas, R., &amp; de la Encarnación Velázquez, M. (2019). Future Perspective in Organic Farming Fertilization: Management and Product. In Organic Farming (pp. 269-315). Woodhead Publishing.</p>
</div>
<div class="footnote-definition" id="-L9TUe"><sup class="footnote-definition-label">217</sup>
<p>Food Price Volatility and Insecurity. Toni Johnson. January 16, 2013. Retrieved from <a href="https://www.cfr.org/backgrounder/food-price-volatility-and-insecurity">https://www.cfr.org/backgrounder/food-price-volatility-and-insecurity</a></p>
</div>
<div class="footnote-definition" id="3PEqh8"><sup class="footnote-definition-label">150</sup>
<p>Food waste within food supply chains: quantification and potential for change</p>
</div>
<div class="footnote-definition" id="VPMWdX"><sup class="footnote-definition-label">236</sup>
<p>Foreign investment in U.S. farmland on the rise. Johnathan Hettinger, Robert Holly, Jelter Meers. June 22, 2017. <a href="https://investigatemidwest.org/2017/06/22/foreign-investment-into-u-s-farmland-on-the-rise/">https://investigatemidwest.org/2017/06/22/foreign-investment-into-u-s-farmland-on-the-rise/</a></p>
</div>
<div class="footnote-definition" id="6tcrtR"><sup class="footnote-definition-label">58</sup>
<p>Foster, J. B. (1999). Marx’s theory of metabolic rift: Classical foundations for environmental sociology. American journal of sociology, 105(2), 366-405.</p>
</div>
<div class="footnote-definition" id="qklICD"><sup class="footnote-definition-label">161</sup>
<p>French Food Waste Law Changing How Grocery Stores Approach Excess Food. Eleanor Beardsley. February 24, 2018. <a href="https://www.npr.org/sections/thesalt/2018/02/24/586579455/french-food-waste-law-changing-how-grocery-stores-approach-excess-food">https://www.npr.org/sections/thesalt/2018/02/24/586579455/french-food-waste-law-changing-how-grocery-stores-approach-excess-food</a></p>
</div>
<div class="footnote-definition" id="DSSSgW"><sup class="footnote-definition-label">171</sup>
<p>Friedmann, H. (1993). The political economy of food: a global crisis. New left review, (197), 29-57.</p>
</div>
<div class="footnote-definition" id="tRoVq1"><sup class="footnote-definition-label">79</sup>
<p>Frink, C. R., Waggoner, P. E., &amp; Ausubel, J. H. (1999). Nitrogen fertilizer: retrospect and prospect. Proceedings of the National Academy of Sciences, 96(4), 1175-1180.</p>
</div>
<div class="footnote-definition" id="S0YUzV"><sup class="footnote-definition-label">234</sup>
<p>From Public Good to Private Profit: The Shifting Discourse on Land Grabbing. Sarika Mathur. September 6, 2011. Retrieved from <a href="https://www.globalpolicy.org/world-hunger/land-ownership-and-hunger/50685-from-public-good-to-private-profit-the-shifting-discourse-on-land-grabbing.html?itemid=id#1292">https://www.globalpolicy.org/world-hunger/land-ownership-and-hunger/50685-from-public-good-to-private-profit-the-shifting-discourse-on-land-grabbing.html?itemid=id#1292</a></p>
</div>
<div class="footnote-definition" id="RBM8cS"><sup class="footnote-definition-label">31</sup>
<p>Gattinger, A., Muller, A., Haeni, M., Skinner, C., Fliessbach, A., Buchmann, N., … &amp; Niggli, U. (2012). Enhanced top soil carbon stocks under organic farming. Proceedings of the National Academy of Sciences, 109(44), 18226-18231.</p>
</div>
<div class="footnote-definition" id="-9ncyO"><sup class="footnote-definition-label">35</sup>
<p>Gellings, C. W., &amp; Parmenter, K. E. (2016). Energy efficiency in fertilizer production and use. Efficient Use and Conservation of Energy; Gellings, CW, Ed.; Encyclopedia of Life Support Systems, 123-136.</p>
</div>
<div class="footnote-definition" id="6IG7Q7"><sup class="footnote-definition-label">195</sup>
<p>Genetic Resources Action International, &amp; GRAIN. (2012). The great food robbery: how corporations control food, grab land and destroy the climate. Fahamu/Pambazuka.</p>
</div>
<div class="footnote-definition" id="BE15hC"><sup class="footnote-definition-label">168</sup>
<p>George Monbiot Misinterprets Farm Subsidies 1. Brad Wilson. February 23, 2016. Retrieved from <a href="https://zcomm.org/zblogs/george-monbiot-misinterprets-farm-subsidies-1/">https://zcomm.org/zblogs/george-monbiot-misinterprets-farm-subsidies-1/</a></p>
</div>
<div class="footnote-definition" id="yCg9cs"><sup class="footnote-definition-label">249</sup>
<p>George Washington Carver: Touching Infinity. Devyn Springer. February 21, 2020. Retrieved from <a href="https://wearyourvoicemag.com/identities/george-washington-carver-touching-infinity">https://wearyourvoicemag.com/identities/george-washington-carver-touching-infinity</a></p>
</div>
<div class="footnote-definition" id="bqL_FO"><sup class="footnote-definition-label">14</sup>
<p>Gerten, D., Heck, V., Jägermeyr, J., Bodirsky, B. L., Fetzer, I., Jalava, M., … &amp; Schellnhuber, H. J. (2020). Feeding ten billion people is possible within four terrestrial planetary boundaries. Nature Sustainability, 1-9.</p>
</div>
<div class="footnote-definition" id="6eT7sI"><sup class="footnote-definition-label">212</sup>
<p>Gilbert, N., Gewin, V., Tollefson, J., Sachs, J., &amp; Potrykus, I. (2010). How to feed a hungry world. Nature, 466, 531-532.</p>
</div>
<div class="footnote-definition" id="DAn6s4"><sup class="footnote-definition-label">159</sup>
<p>Gille, Z. (2012). From risk to waste: global food waste regimes. The Sociological Review, 60, 27-46.</p>
</div>
<div class="footnote-definition" id="gUnVx3"><sup class="footnote-definition-label">28</sup>
<p>Giraldo, O. F. (2019). Political ecology of agriculture: agroecology and post-development. Springer.</p>
</div>
<div class="footnote-definition" id="o6QLUC"><sup class="footnote-definition-label">124</sup>
<p>Gone Tomorrow: The Hidden Life of Garbage. Heather Rogers. 2005.</p>
</div>
<div class="footnote-definition" id="WHB9x1"><sup class="footnote-definition-label">20</sup>
<p>Good, A. G., &amp; Beatty, P. H. (2011). Fertilizing nature: a tragedy of excess in the commons. PLoS biology, 9(8), e1001124.</p>
</div>
<div class="footnote-definition" id="1GMDYy"><sup class="footnote-definition-label">157</sup>
<p>Gustavsson, J., Cederberg, C., Sonesson, U., Van Otterdijk, R., &amp; Meybeck, A. (2011). Global food losses and food waste (pp. 1-38). Rome: FAO.</p>
</div>
<div class="footnote-definition" id="iGn-37"><sup class="footnote-definition-label">184</sup>
<p>Growers Sue to Roll Back Farm Workers’ Wages. David Bacon. January 25, 2019. Retrieved from <a href="https://prospect.org/labor/growers-sue-roll-back-farm-workers-wages/">https://prospect.org/labor/growers-sue-roll-back-farm-workers-wages/</a></p>
</div>
<div class="footnote-definition" id="UrN_YO"><sup class="footnote-definition-label">152</sup>
<p>Hall, K. D., Guo, J., Dore, M., &amp; Chow, C. C. (2009). The progressive increase of food waste in America and its environmental impact. PloS one, 4(11), e7940.</p>
</div>
<div class="footnote-definition" id="wsk7V0"><sup class="footnote-definition-label">278</sup>
<p>Hamouchene, H. Extractivism and resistance in North Africa. November 2019.</p>
</div>
<div class="footnote-definition" id="6wmhRi"><sup class="footnote-definition-label">75</sup>
<p>Has another cargo of fishmeal from Western Sahara arrived in Germany? Western Sahara Resource Watch. May 2, 2019. Retrieved from <a href="https://www.wsrw.org/a105x4505">https://www.wsrw.org/a105x4505</a>.</p>
</div>
<div class="footnote-definition" id="IJgxJI"><sup class="footnote-definition-label">192</sup>
<p>Holt-Giménez, E., &amp; Altieri, M. A. (2013). Agroecology, food sovereignty, and the new green revolution. Agroecology and sustainable Food systems, 37(1), 90-102.</p>
</div>
<div class="footnote-definition" id="NJ5gmi"><sup class="footnote-definition-label">279</sup>
<p>Hong, C., Mueller, N. D., Burney, J. A., Zhang, Y., AghaKouchak, A., Moore, F. C., … &amp; Davis, S. J. (2020). Impacts of ozone and climate change on yields of perennial crops in California. Nature Food, 1(3), 166-172.</p>
</div>
<div class="footnote-definition" id="25U1QS"><sup class="footnote-definition-label">44</sup>
<p>How Does the Farm Bill Affect Everyday Americans? Elliott Negin, Ricardo Salvador. March 1, 2018. <a href="https://blog.ucsusa.org/elliott-negin/farm-bill-and-everyday-americans">https://blog.ucsusa.org/elliott-negin/farm-bill-and-everyday-americans</a></p>
</div>
<div class="footnote-definition" id="9gAXp1"><sup class="footnote-definition-label">203</sup>
<p>How Farm Policy and Big Ag Impact Farmers in the U.S. and Abroad. Eva Perroni, Timothy Wise. March 7, 2019. <a href="https://civileats.com/2019/03/07/how-farm-policy-and-big-ag-impact-farmers-in-the-u-s-and-abroad/">https://civileats.com/2019/03/07/how-farm-policy-and-big-ag-impact-farmers-in-the-u-s-and-abroad/</a></p>
</div>
<div class="footnote-definition" id="5opCK-"><sup class="footnote-definition-label">183</sup>
<p>How Finance Structures Global Value Chains. Tomaso Ferrando. January 6, 2020. Retrieved from <a href="https://lpeblog.org/2020/01/06/how-finance-structures-global-value-chains/#more-3156">https://lpeblog.org/2020/01/06/how-finance-structures-global-value-chains/#more-3156</a></p>
</div>
<div class="footnote-definition" id="chuDeg"><sup class="footnote-definition-label">29</sup>
<p>How U.S. Agricultural Subsidies Degrade Land and Soil. July 2019. <a href="https://foodtank.com/news/2019/07/opinion-how-us-agricultural-subsidies-degrade-land-and-soil/">https://foodtank.com/news/2019/07/opinion-how-us-agricultural-subsidies-degrade-land-and-soil/</a></p>
</div>
<div class="footnote-definition" id="XII3Yd"><sup class="footnote-definition-label">131</sup>
<p>Hribar, C. (2010). Understanding concentrated animal feeding operations and their impact on communities.</p>
</div>
<div class="footnote-definition" id="wmnexr"><sup class="footnote-definition-label">21</sup>
<p>Ifft, J., &amp; Jodlowski, M. (2018). Federal crop insurance participation and adoption of sustainable production practices by US corn farms (No. 2133-2018-5427).</p>
</div>
<div class="footnote-definition" id="jLJS3O"><sup class="footnote-definition-label">254</sup>
<p>In Defense of Agroecology. Ellinor Isgren, Thaddeo Kahigwa Tibasiima. July 15, 2019. Retrieved from <a href="https://thebreakthrough.org/journal/no-11-summer-2019/in-defense-of-agroecology">https://thebreakthrough.org/journal/no-11-summer-2019/in-defense-of-agroecology</a></p>
</div>
<div class="footnote-definition" id="RsiyqM"><sup class="footnote-definition-label">49</sup>
<p>International Fertilizer Industry Association. (2001). Environmental aspects of phosphate and potash mining. UNEP.</p>
</div>
<div class="footnote-definition" id="6Vr0i5"><sup class="footnote-definition-label">87</sup>
<p>Is organic really better for the environment than conventional agriculture? Hannah Ritchie. October 19, 2017. <a href="https://ourworldindata.org/is-organic-agriculture-better-for-the-environment">https://ourworldindata.org/is-organic-agriculture-better-for-the-environment</a></p>
</div>
<div class="footnote-definition" id="n18ElG"><sup class="footnote-definition-label">62</sup>
<p>Jackson, S. (2016). The phosphate archipelago: Imperial mining and global agriculture in French North Africa. Jahrbuch für Wirtschaftsgeschichte/Economic History Yearbook, 57(1), 187-214.</p>
</div>
<div class="footnote-definition" id="Eb7hU3"><sup class="footnote-definition-label">211</sup>
<p>Jayne, T. S., Mason, N. M., Burke, W. J., &amp; Ariga, J. (2018). Taking stock of Africa’s second-generation agricultural input subsidy programs. Food Policy, 75, 1-14.</p>
</div>
<div class="footnote-definition" id="tkba12"><sup class="footnote-definition-label">71</sup>
<p>Jensen, G. (2013). War and insurgency in the Western Sahara. Current Politics and Economics of Africa, 6(4), 339.</p>
</div>
<div class="footnote-definition" id="iCI29j"><sup class="footnote-definition-label">280</sup>
<p>Johnson, T. (2016). Nitrogen nation: The legacy of World War I and the politics of chemical agriculture in the United States, 1916–1933. Agricultural History, 90(2), 209-229.</p>
</div>
<div class="footnote-definition" id="GvbMOo"><sup class="footnote-definition-label">186</sup>
<p>Justice, F. (2011). No way to treat a guest: why the H-2A agricultural visa program fails US and foreign workers. Washington, DC: Farmworker Justice, 1-44.</p>
</div>
<div class="footnote-definition" id="9u391v"><sup class="footnote-definition-label">219</sup>
<p>Kalkuhl, M., Von Braun, J., &amp; Torero, M. (Eds.). (2016). Food price volatility and its implications for food security and policy: Volatile and Extreme Food Prices, Food Security, and Policy: An Overview. Springer Open.</p>
</div>
<div class="footnote-definition" id="0ie15A"><sup class="footnote-definition-label">197</sup>
<p>Kallummal, M., Mendiratta, D., &amp; Sangita, S. (2018). US Import Refusals of Agricultural Products and Their Impact on the Participation of Indian Firms. Agrarian South: Journal of Political Economy, 7(1), 78-104.</p>
</div>
<div class="footnote-definition" id="fFH_WZ"><sup class="footnote-definition-label">223</sup>
<p>Kennedy, J., &amp; King, L. (2014). The political economy of farmers’ suicides in India: indebted cash-crop farmers with marginal landholdings explain state-level variation in suicide rates. Globalization and health, 10(1), 16.</p>
</div>
<div class="footnote-definition" id="v5woiW"><sup class="footnote-definition-label">281</sup>
<p>Khan, S. A., Mulvaney, R. L., Ellsworth, T. R., &amp; Boast, C. W. (2007). The myth of nitrogen fertilization for soil carbon sequestration. Journal of Environmental Quality, 36(6), 1821-1832.</p>
</div>
<div class="footnote-definition" id="4yxRve"><sup class="footnote-definition-label">205</sup>
<p>Kiage, L. M. (2013). Perspectives on the assumed causes of land degradation in the rangelands of Sub-Saharan Africa. Progress in Physical Geography, 37(5), 664-684.</p>
</div>
<div class="footnote-definition" id="yK_RmM"><sup class="footnote-definition-label">63</sup>
<p>King, S., &amp; Sigrah, K. R. (2004, November). Legacy of a miner’s daughter and assessment of the social changes of the Banabans after phosphate mining on Banaba. In Changing Islands–Changing Worlds. Islands of the World VIII International Conference. Taiwan.</p>
</div>
<div class="footnote-definition" id="Hv99Zg"><sup class="footnote-definition-label">241</sup>
<p>Koizumi, T. (2015). Biofuels and food security. Renewable and Sustainable Energy Reviews, 52, 829-841.</p>
</div>
<div class="footnote-definition" id="h3rK4I"><sup class="footnote-definition-label">91</sup>
<p>Kozai, T., &amp; Niu, G. (2016). Conclusions: Resource-Saving and Resource-Consuming Characteristics of PFALs. In Plant Factory (pp. 395-399). Academic Press.</p>
</div>
<div class="footnote-definition" id="kYho7r"><sup class="footnote-definition-label">137</sup>
<p>Kumar, J., Singh, D., Tyagi, M. B., &amp; Kumar, A. (2019). Cyanobacteria: Applications in Biotechnology. In Cyanobacteria (pp. 327-346). Academic Press.</p>
</div>
<div class="footnote-definition" id="eX2km5"><sup class="footnote-definition-label">282</sup>
<p>Kumar, R. R., &amp; Cho, J. Y. (2014). Reuse of hydroponic waste solution. Environmental Science and Pollution Research, 21(16), 9569-9577.</p>
</div>
<div class="footnote-definition" id="xwNKkI"><sup class="footnote-definition-label">5</sup>
<p>Ladha, J. K., Pathak, H., Krupnik, T. J., Six, J., &amp; van Kessel, C. (2005). Efficiency of fertilizer nitrogen in cereal production: retrospects and prospects. Advances in agronomy, 87, 85-156.</p>
</div>
<div class="footnote-definition" id="Dr6-vN"><sup class="footnote-definition-label">51</sup>
<p>Langa, S. G. (2014). Potash extraction and historical environmental conflict in the Bages region (Spain). Investigaciones Geográficas (Esp), (61), 5-16.</p>
</div>
<div class="footnote-definition" id="YxllD9"><sup class="footnote-definition-label">174</sup>
<p>Large Loans Drive Further Increases in Farm Lending. Nathan Kauffman, Ty Kreitman. July 18, 2019. <a href="https://www.kansascityfed.org/research/indicatorsdata/agfinancedatabook/articles/2019/7-18-19/ag-finance-dbk-7-18-2019">https://www.kansascityfed.org/research/indicatorsdata/agfinancedatabook/articles/2019/7-18-19/ag-finance-dbk-7-18-2019</a></p>
</div>
<div class="footnote-definition" id="SCd_XA"><sup class="footnote-definition-label">114</sup>
<p>Light sparks conversion of dinitrogen to ammonia. Stu Borman. April 22, 2016. <a href="https://cen.acs.org/articles/94/i17/Light-sparks-conversion-dinitrogen-ammonia.html">https://cen.acs.org/articles/94/i17/Light-sparks-conversion-dinitrogen-ammonia.html</a></p>
</div>
<div class="footnote-definition" id="rBgP1m"><sup class="footnote-definition-label">237</sup>
<p>Losing ground. Reveal. July 1, 2017. Retrieved from <a href="https://www.revealnews.org/episodes/losing-ground/">https://www.revealnews.org/episodes/losing-ground/</a></p>
</div>
<div class="footnote-definition" id="Vb5nD3"><sup class="footnote-definition-label">8</sup>
<p>Lu, C. C., &amp; Tian, H. (2017). Global nitrogen and phosphorus fertilizer use for agriculture production in the past half century: shifted hot spots and nutrient imbalance. Earth System Science Data, 9, 181.</p>
</div>
<div class="footnote-definition" id="rXNEJ9"><sup class="footnote-definition-label">82</sup>
<p>Lu, Z. X., Yu, X. P., Heong, K. L., &amp; Cui, H. U. (2007). Effect of nitrogen fertilizer on herbivores and its stimulation to major insect pests in rice. Rice Science, 14(1), 56-66.</p>
</div>
<div class="footnote-definition" id="Dy07it"><sup class="footnote-definition-label">258</sup>
<p>Madison, M. G. (1997). ‘Potatoes Made of Oil’: Eugene and Howard Odum and the Origins and Limits of American Agroecology. Environment and History, 3(2), 209-238.</p>
</div>
<div class="footnote-definition" id="plji8g"><sup class="footnote-definition-label">187</sup>
<p>Magdoff, F. (2013). Twenty-first-century land grabs: Accumulation by agricultural dispossession. Monthly Review, 65(6), 1.</p>
</div>
<div class="footnote-definition" id="F7aPre"><sup class="footnote-definition-label">210</sup>
<p>Malawi’s fertilizer subsidies are not a panacea for farmer households. Adam Komarek, Siwa Msangi. May 12, 2017. <a href="http://www.ifpri.org/blog/malawis-fertilizer-subsidies-are-not-panacea-farmer-households">http://www.ifpri.org/blog/malawis-fertilizer-subsidies-are-not-panacea-farmer-households</a></p>
</div>
<div class="footnote-definition" id="tnkBMB"><sup class="footnote-definition-label">227</sup>
<p>Mann, H., &amp; Smaller, C. (2010). Foreign land purchases for agriculture: What impact on sustainable development. Sustainable development innovation briefs, 8, 1-8.</p>
</div>
<div class="footnote-definition" id="bg_3yV"><sup class="footnote-definition-label">100</sup>
<p>Martin, M., &amp; Molin, E. (2019). Environmental Assessment of an Urban Vertical Hydroponic Farming System in Sweden. Sustainability, 11(15), 4124.</p>
</div>
<div class="footnote-definition" id="kEbW_r"><sup class="footnote-definition-label">283</sup>
<p>Mason, N. M., Jayne, T. S., &amp; Van De Walle, N. (2017). The political economy of fertilizer subsidy programs in Africa: Evidence from Zambia. American Journal of Agricultural Economics, 99(3), 705-731.</p>
</div>
<div class="footnote-definition" id="21Uara"><sup class="footnote-definition-label">166</sup>
<p>Mazzarino, T. (2012). Policy Alternatives for Federal Agricultural Subsidies: Fertilization Protocols and Their Effects on Crop Yields, Sustainability, and Food Justice.</p>
</div>
<div class="footnote-definition" id="SbLrmJ"><sup class="footnote-definition-label">164</sup>
<p>McMichael, P. (2016). Commentary: Food regime for thought. The Journal of Peasant Studies, 43(3), 648-670.</p>
</div>
<div class="footnote-definition" id="lftIPW"><sup class="footnote-definition-label">25</sup>
<p>Mehmood, T., Chaudhry, M. M., Tufail, M., &amp; Irfan, N. (2009). Heavy metal pollution from phosphate rock used for the production of fertilizer in Pakistan. Microchemical Journal, 91(1), 94-99.</p>
</div>
<div class="footnote-definition" id="SZKqjA"><sup class="footnote-definition-label">128</sup>
<p>Mehta, C. M., Hunter, M. N., Leong, G., &amp; Batstone, D. J. (2018). The value of wastewater derived struvite as a source of phosphorus fertilizer. CLEAN–Soil, Air, Water, 46(7), 1700027.</p>
</div>
<div class="footnote-definition" id="20dF-y"><sup class="footnote-definition-label">61</sup>
<p>Melillo, E. D. (2012). The first green revolution: debt peonage and the making of the nitrogen fertilizer trade, 1840–1930. The American Historical Review, 117(4), 1028-1060.</p>
</div>
<div class="footnote-definition" id="cV_sHG"><sup class="footnote-definition-label">27</sup>
<p>Miao, Y., Stewart, B. A., &amp; Zhang, F. (2011). Long-term experiments for sustainable nutrient management in China. A review. Agronomy for Sustainable Development, 31(2), 397-414.</p>
</div>
<div class="footnote-definition" id="Gw1Of3"><sup class="footnote-definition-label">176</sup>
<p>Miller, C., &amp; Jones, L. (2010). Agricultural value chain finance: Tools and lessons. Food and Agriculture Organization of the United Nations and Practical Action Pub..</p>
</div>
<div class="footnote-definition" id="dl83iJ"><sup class="footnote-definition-label">68</sup>
<p>Mineral Resource of the Month: Phosphate Rock, Stephen M. Jasinski (December 2, 2013) <a href="https://www.earthmagazine.org/article/mineral-resource-month-phosphate-rock">https://www.earthmagazine.org/article/mineral-resource-month-phosphate-rock</a></p>
</div>
<div class="footnote-definition" id="8Oy4Ya"><sup class="footnote-definition-label">133</sup>
<p>Mohammadi, K., &amp; Sohrabi, Y. (2012). Bacterial biofertilizers for sustainable crop production: a review. J Agric Biol Sci, 7, 307-316.</p>
</div>
<div class="footnote-definition" id="niudWK"><sup class="footnote-definition-label">92</sup>
<p>Mohareb, E., Heller, M., Novak, P., Goldstein, B., Fonoll, X., &amp; Raskin, L. (2017). Considerations for reducing food system energy demand while scaling up urban agriculture. Environmental Research Letters, 12(12), 125004.</p>
</div>
<div class="footnote-definition" id="cNmw3C"><sup class="footnote-definition-label">209</sup>
<p>Morgan, S. N., Mason, N. M., Levine, N. K., &amp; Zulu-Mbata, O. (2019). Dis-incentivizing sustainable intensification? The case of Zambia’s maize-fertilizer subsidy program. World Development, 122, 54-69.</p>
</div>
<div class="footnote-definition" id="FWHaCI"><sup class="footnote-definition-label">74</sup>
<p>Morocco/Western Sahara: Investigate brutal crackdown on Sahrawi protesters. Amnesty International. August 1, 2019. <a href="https://www.amnesty.org/en/latest/news/2019/08/morocco-western-sahara-investigate-brutal-crackdown-on-sahrawi-protesters/">https://www.amnesty.org/en/latest/news/2019/08/morocco-western-sahara-investigate-brutal-crackdown-on-sahrawi-protesters/</a></p>
</div>
<div class="footnote-definition" id="A88JZE"><sup class="footnote-definition-label">88</sup>
<p>Muller, A., Schader, C., Scialabba, N. E. H., Brüggemann, J., Isensee, A., Erb, K. H., … &amp; Niggli, U. (2017). Strategies for feeding the world more sustainably with organic agriculture. Nature communications, 8(1), 1290.</p>
</div>
<div class="footnote-definition" id="ny2fVV"><sup class="footnote-definition-label">15</sup>
<p>Mulvaney, R. L., Khan, S. A., &amp; Ellsworth, T. R. (2009). Synthetic nitrogen fertilizers deplete soil nitrogen: a global dilemma for sustainable cereal production. Journal of environmental quality, 38(6), 2295-2314.</p>
</div>
<div class="footnote-definition" id="2mmDMi"><sup class="footnote-definition-label">97</sup>
<p>Muñoz, P., Antón, A., Nuñez, M., Paranjpe, A., Ariño, J., Castells, X., … &amp; Rieradevall, J. (2007, October). Comparing the environmental impacts of greenhouse versus open-field tomato production in the Mediterranean region. In International Symposium on High Technology for Greenhouse System Management: Greensys2007 801 (pp. 1591-1596).</p>
</div>
<div class="footnote-definition" id="5RuiK0"><sup class="footnote-definition-label">224</sup>
<p>Nair, S. R. Agrarian Suicides in India: Myth and Reality. Development Policy Review.</p>
</div>
<div class="footnote-definition" id="XaaQ8X"><sup class="footnote-definition-label">182</sup>
<p>National Farmers Union (Canada). (2005). The farm crisis &amp; corporate profits: A report. Saskatoon, Sask.: National Farmers Union.</p>
</div>
<div class="footnote-definition" id="Q_PkPf"><sup class="footnote-definition-label">270</sup>
<p>Newly Identified Jet-Stream Pattern Could Imperil Global Food Supplies. Jeff Masters. December 9, 2019. Retrieved from <a href="https://blogs.scientificamerican.com/eye-of-the-storm/newly-identified-jet-stream-pattern-could-imperil-global-food-supplies/">https://blogs.scientificamerican.com/eye-of-the-storm/newly-identified-jet-stream-pattern-could-imperil-global-food-supplies/</a></p>
</div>
<div class="footnote-definition" id="efD9Gx"><sup class="footnote-definition-label">193</sup>
<p>Ng, F., &amp; Aksoy, M. A. (2008). Who are the net food importing countries?. The World Bank.</p>
</div>
<div class="footnote-definition" id="3TO-Xf"><sup class="footnote-definition-label">110</sup>
<p>Nitrogen Production Technologies. Retrieved from <a href="https://wcroc.cfans.umn.edu/research-programs/renewable-energy/energy-crops/nitrogen-production">https://wcroc.cfans.umn.edu/research-programs/renewable-energy/energy-crops/nitrogen-production</a></p>
</div>
<div class="footnote-definition" id="1cu2km"><sup class="footnote-definition-label">179</sup>
<p>No Quick Subsidies Fix for Food System. Wenonah Hauter. March 31, 2011. <a href="https://civileats.com/2011/03/31/no-quick-subsidies-fix-for-food-system/">https://civileats.com/2011/03/31/no-quick-subsidies-fix-for-food-system/</a></p>
</div>
<div class="footnote-definition" id="rmeJiv"><sup class="footnote-definition-label">145</sup>
<p>Nutrien Is Quietly Positioning Itself for the Future of Agriculture. Maxx Chatsko. April 14, 2019. <a href="https://www.fool.com/investing/2019/04/14/nutrien-is-quietly-positioning-itself-for-the-futu.aspx">https://www.fool.com/investing/2019/04/14/nutrien-is-quietly-positioning-itself-for-the-futu.aspx</a></p>
</div>
<div class="footnote-definition" id="6rPFfC"><sup class="footnote-definition-label">144</sup>
<p>Nutrien. November 25, 2019. Retrieved from <a href="https://en.wikipedia.org/wiki/Nutrien">https://en.wikipedia.org/wiki/Nutrien</a></p>
</div>
<div class="footnote-definition" id="qmR1cA"><sup class="footnote-definition-label">81</sup>
<p>Olesen, J. E., Jørgensen, L. N., Petersen, J., &amp; Mortensen, J. V. (2003). Effects of rate and timing of nitrogen fertilizer on disease control by fungicides in winter wheat. 1. Grain yield and foliar disease control. The Journal of Agricultural Science, 140(1), 1-13.</p>
</div>
<div class="footnote-definition" id="k0dCn_"><sup class="footnote-definition-label">284</sup>
<p>On Farming YouTube, Emu Eggs and Hay Bales Find Loyal Fans. Louise Matsakis. December 18, 2019. Retrieved from <a href="https://www.wired.com/story/farming-youtube-emu-eggs-hay-bales-find-fans/">https://www.wired.com/story/farming-youtube-emu-eggs-hay-bales-find-fans/</a></p>
</div>
<div class="footnote-definition" id="xSaaDE"><sup class="footnote-definition-label">226</sup>
<p>One of Africa’s Most Fertile Lands Is Struggling to Feed Its Own People. Peter Schwartzstein. April 2, 2019. Retrieved from <a href="https://www.bloomberg.com/features/2019-sudan-nile-land-farming/">https://www.bloomberg.com/features/2019-sudan-nile-land-farming/</a></p>
</div>
<div class="footnote-definition" id="klLI_R"><sup class="footnote-definition-label">52</sup>
<p>Othman, I., &amp; Al-Masri, M. S. (2007). Impact of phosphate industry on the environment: a case study. Applied Radiation and Isotopes, 65(1), 131-141.</p>
</div>
<div class="footnote-definition" id="N2ZNpL"><sup class="footnote-definition-label">189</sup>
<p>Our crazy farm subsidies, explained. Amelia Urry. April 20, 2015. Retrieved from <a href="https://grist.org/food/our-crazy-farm-subsidies-explained/">https://grist.org/food/our-crazy-farm-subsidies-explained/</a></p>
</div>
<div class="footnote-definition" id="NIyY3b"><sup class="footnote-definition-label">24</sup>
<p>P For Plunder: Morocco’s exports of phosphates from occupied Western Sahara. Western Sahara Resource Watch. April 2019. <a href="https://www.wsrw.org/files/dated/2019-04-08/pforplunder2019_web.pdf">https://www.wsrw.org/files/dated/2019-04-08/pforplunder2019_web.pdf</a></p>
</div>
<div class="footnote-definition" id="WCjxSr"><sup class="footnote-definition-label">143</sup>
<p>Palma, I. P., Toral, J. N., Vázquez, M. R. P., Fuentes, N. F., &amp; Hernández, F. G. (2015). Historical changes in the process of agricultural development in Cuba. Journal of Cleaner Production, 96, 77-84.</p>
</div>
<div class="footnote-definition" id="-mm_V_"><sup class="footnote-definition-label">149</sup>
<p>Papargyropoulou, E., Lozano, R., Steinberger, J. K., Wright, N., &amp; bin Ujang, Z. (2014). The food waste hierarchy as a framework for the management of food surplus and food waste. Journal of Cleaner Production, 76, 106-115.</p>
</div>
<div class="footnote-definition" id="5J1R08"><sup class="footnote-definition-label">215</sup>
<p>Paudel, J., &amp; Crago, C. L. (2017). Fertilizer Subsidy and Agricultural Productivity: Empirical Evidence from Nepal.</p>
</div>
<div class="footnote-definition" id="r0Ivkr"><sup class="footnote-definition-label">268</sup>
<p>Piemonte, V., &amp; Gironi, F. (2012). Bioplastics and GHGs saving: the land use change (LUC) emissions issue. Energy Sources, Part A: Recovery, Utilization, and Environmental Effects, 34(21), 1995-2003.</p>
</div>
<div class="footnote-definition" id="RIno95"><sup class="footnote-definition-label">37</sup>
<p>Policy Brief: Fertilizer Recommendations and In-kind Subsidies Increase Uptake and Yields among Maize Farmers in Mexico. Aprajit Mahajan, Xavier Gine, Carolina Corral, Enrique Seira. <a href="https://basis.ucdavis.edu/publication/policy-brief-fertilizer-recommendations-and-kind-subsidies-increase-uptake-and-yields">https://basis.ucdavis.edu/publication/policy-brief-fertilizer-recommendations-and-kind-subsidies-increase-uptake-and-yields</a></p>
</div>
<div class="footnote-definition" id="9EDruS"><sup class="footnote-definition-label">77</sup>
<p>Ponisio, L. C., M’Gonigle, L. K., Mace, K. C., Palomino, J., de Valpine, P., &amp; Kremen, C. (2015). Diversification practices reduce organic to conventional yield gap. Proceedings of the Royal Society B: Biological Sciences, 282(1799), 20141396.</p>
</div>
<div class="footnote-definition" id="17qcjP"><sup class="footnote-definition-label">285</sup>
<p>Prakash, S., &amp; Verma, J. P. (2016). Global perspective of potash for fertilizer production. In Potassium solubilizing microorganisms for sustainable agriculture (pp. 327-331). Springer, New Delhi.</p>
</div>
<div class="footnote-definition" id="ZvarSU"><sup class="footnote-definition-label">146</sup>
<p>Producción de biol SUPERMAGRO. Nelly Aliaga. <a href="http://www.agrolalibertad.gob.pe/sites/default/files/Manual_de__Bioles_rina.pdf">http://www.agrolalibertad.gob.pe/sites/default/files/Manual_de__Bioles_rina.pdf</a></p>
</div>
<div class="footnote-definition" id="pogchA"><sup class="footnote-definition-label">232</sup>
<p>Puel, J. M. (2012). Are Sovereign Wealth Funds’ Investments in Agriculture Political?. Études rurales, (2), 161-176.</p>
</div>
<div class="footnote-definition" id="OyF9aw"><sup class="footnote-definition-label">155</sup>
<p>Quested, T. E., Marsh, E., Stunell, D., &amp; Parry, A. D. (2013). Spaghetti soup: The complex world of food waste behaviours. Resources, Conservation and Recycling, 79, 43-51.</p>
</div>
<div class="footnote-definition" id="3KzcuP"><sup class="footnote-definition-label">123</sup>
<p>Randall, D. G., &amp; Naidoo, V. (2018). Urine: The liquid gold of wastewater. Journal of Environmental Chemical Engineering, 6(2), 2627-2635.</p>
</div>
<div class="footnote-definition" id="c6elUZ"><sup class="footnote-definition-label">30</sup>
<p>Reay, D. S., Dentener, F., Smith, P., Grace, J., &amp; Feely, R. A. (2008). Global nitrogen deposition and carbon sinks. Nature Geoscience, 1(7), 430.</p>
</div>
<div class="footnote-definition" id="plLKh6"><sup class="footnote-definition-label">142</sup>
<p>Recipe for Success: Brew Your Own Biofertilizer. Anna Birn. January 30, 2019. <a href="https://smallfarms.cornell.edu/2019/01/recipe-for-success-brew-your-own-biofertilizer/">https://smallfarms.cornell.edu/2019/01/recipe-for-success-brew-your-own-biofertilizer/</a></p>
</div>
<div class="footnote-definition" id="x-fbwX"><sup class="footnote-definition-label">38</sup>
<p>Regmi, M., Briggeman, B., &amp; Featherstone, A. (2019). Estimating Effects of Crop Insurance Enrollment on Farm Input Use.</p>
</div>
<div class="footnote-definition" id="9Fu4Jq"><sup class="footnote-definition-label">138</sup>
<p>Replacing fertilizer with plant probiotics could slash greenhouse gases. October 2, 2018. <a href="https://www.technologyreview.com/f/612223/forget-fertilizer-this-startup-aims-to-slash-greenhouse-gases-with-plant/">https://www.technologyreview.com/f/612223/forget-fertilizer-this-startup-aims-to-slash-greenhouse-gases-with-plant/</a></p>
</div>
<div class="footnote-definition" id="xfu7aQ"><sup class="footnote-definition-label">120</sup>
<p>Renewable Ammonia from Biomass: SynGest, BioNitrogen, Agrebon. Trevor Brown. April 24, 2013. Retrieved from <a href="https://nh3fuelassociation.org/2013/04/24/ammonia-from-biomass/">https://nh3fuelassociation.org/2013/04/24/ammonia-from-biomass/</a></p>
</div>
<div class="footnote-definition" id="f91sr2"><sup class="footnote-definition-label">253</sup>
<p>Ricciardi, V., Ramankutty, N., Mehrabi, Z., Jarvis, L., &amp; Chookolingo, B. (2018). How much of the world’s food do smallholders produce?. Global food security, 17, 64-72.</p>
</div>
<div class="footnote-definition" id="DWzyiM"><sup class="footnote-definition-label">103</sup>
<p>Romeo, D., Vea, E. B., &amp; Thomsen, M. (2018). Environmental impacts of urban hydroponics in Europe: a case study in Lyon. Procedia CIRP, 69, 540-545.</p>
</div>
<div class="footnote-definition" id="dhZQIS"><sup class="footnote-definition-label">130</sup>
<p>Rorat, A., &amp; Vandenbulcke, F. (2019). Earthworms converting domestic and food industry wastes into biofertilizer. In Industrial and Municipal Sludge (pp. 83-106). Butterworth-Heinemann.</p>
</div>
<div class="footnote-definition" id="UI49PE"><sup class="footnote-definition-label">240</sup>
<p>Rosegrant, M. W. (2008). Biofuels and grain prices: impacts and policy responses (pp. 1-4). Washington, DC: International Food Policy Research Institute.</p>
</div>
<div class="footnote-definition" id="_M5aTx"><sup class="footnote-definition-label">156</sup>
<p>Rosenzweig, C., Mbow, C., Barioni, L. G., Benton, T. G., Herrero, M., Krishnapillai, M., … &amp; Tubiello, F. N. (2020). Climate change responses benefit from a global food system approach. Nature Food, 1(2), 94-97.</p>
</div>
<div class="footnote-definition" id="CTq7gr"><sup class="footnote-definition-label">191</sup>
<p>Rosset, P. M., &amp; Altieri, M. A. (1997). Agroecology versus input substitution: a fundamental contradiction of sustainable agriculture. Society &amp; Natural Resources, 10(3), 283-295.</p>
</div>
<div class="footnote-definition" id="N5Xxen"><sup class="footnote-definition-label">252</sup>
<p>Rosset, P. M., Machín Sosa, B., Roque Jaime, A. M., &amp; Ávila Lozano, D. R. (2011). The Campesino-to-Campesino agroecology movement of ANAP in Cuba: social process methodology in the construction of sustainable peasant agriculture and food sovereignty. The Journal of peasant studies, 38(1), 161-191.</p>
</div>
<div class="footnote-definition" id="_0pHOL"><sup class="footnote-definition-label">286</sup>
<p>Rougoor, C. W., Van Zeijts, H., Hofreither, M. F., &amp; Bäckman, S. (2001). Experiences with fertilizer taxes in Europe. Journal of Environmental Planning and Management, 44(6), 877-887.</p>
</div>
<div class="footnote-definition" id="SVy7lA"><sup class="footnote-definition-label">99</sup>
<p>Russo, G., &amp; Scarascia Mugnozza, G. (2004, September). LCA methodology applied to various typology of greenhouses. In International Conference on Sustainable Greenhouse Systems-Greensys2004 691 (pp. 837-844).</p>
</div>
<div class="footnote-definition" id="g9P75W"><sup class="footnote-definition-label">32</sup>
<p>Röös, E., Mie, A., Wivstad, M., Salomon, E., Johansson, B., Gunnarsson, S., … &amp; Watson, C. A. (2018). Risks and opportunities of increasing yields in organic farming. A review. Agronomy for sustainable development, 38(2), 14.</p>
</div>
<div class="footnote-definition" id="riIcAm"><sup class="footnote-definition-label">287</sup>
<p>Rulli, M. C., Saviori, A., &amp; D’Odorico, P. (2013). Global land and water grabbing. Proceedings of the National Academy of Sciences, 110(3), 892-897.</p>
</div>
<div class="footnote-definition" id="NvBqiH"><sup class="footnote-definition-label">78</sup>
<p>Saeid, A., &amp; Chojnacka, K. (2019). Fertlizers: Need for new strategies. In Organic Farming (pp. 91-116). Woodhead Publishing.</p>
</div>
<div class="footnote-definition" id="p7HtiI"><sup class="footnote-definition-label">94</sup>
<p>Sanjuan-Delmás, D., Llorach-Massana, P., Nadal, A., Ercilla-Montserrat, M., Muñoz, P., Montero, J. I., … &amp; Rieradevall, J. (2018). Environmental assessment of an integrated rooftop greenhouse for food production in cities. Journal of cleaner production, 177, 326-337.</p>
</div>
<div class="footnote-definition" id="tT6HJr"><sup class="footnote-definition-label">288</sup>
<p>Schaffartzik, A., Mayer, A., Gingrich, S., Eisenmenger, N., Loy, C., &amp; Krausmann, F. (2014). The global metabolic transition: Regional patterns and trends of global material flows, 1950–2010. Global Environmental Change, 26, 87-97.</p>
</div>
<div class="footnote-definition" id="UPu3aS"><sup class="footnote-definition-label">289</sup>
<p>Schechinger, A. W., &amp; Cox, C. Feeding the world: Think US agriculture will end world hunger? Think again. EWG; 2016.</p>
</div>
<div class="footnote-definition" id="CCu0Y4"><sup class="footnote-definition-label">108</sup>
<p>Schrammel, E. (2015). A cost-benefit analysis of hydroponic wastewater treatment in Sweden.</p>
</div>
<div class="footnote-definition" id="zAcRDv"><sup class="footnote-definition-label">86</sup>
<p>Seufert, V., &amp; Ramankutty, N. (2017). Many shades of gray—The context-dependent performance of organic agriculture. Science advances, 3(3), e1602638.</p>
</div>
<div class="footnote-definition" id="ICFztz"><sup class="footnote-definition-label">194</sup>
<p>Shaw, D. J. (2007). World food security: A History since 1945.</p>
</div>
<div class="footnote-definition" id="Qo4op7"><sup class="footnote-definition-label">26</sup>
<p>Shcherbak, I., Millar, N., &amp; Robertson, G. P. (2014). Global metaanalysis of the nonlinear response of soil nitrous oxide (N2O) emissions to fertilizer nitrogen. Proceedings of the National Academy of Sciences, 111(25), 9199-9204.</p>
</div>
<div class="footnote-definition" id="keG87m"><sup class="footnote-definition-label">34</sup>
<p>Sheriff, G. (2005). Efficient waste? Why farmers over-apply nutrients and the implications for policy design. Review of Agricultural Economics, 27(4), 542-557.</p>
</div>
<div class="footnote-definition" id="jJeN-d"><sup class="footnote-definition-label">111</sup>
<p>Shipman, M. A., &amp; Symes, M. D. (2017). Recent progress towards the electrosynthesis of ammonia from sustainable resources. Catalysis Today, 286, 57-68.</p>
</div>
<div class="footnote-definition" id="TA_2RV"><sup class="footnote-definition-label">208</sup>
<p>Shiva, V. (1991). The violence of the green revolution: Third World agriculture, ecology and politics.</p>
</div>
<div class="footnote-definition" id="s7wSmH"><sup class="footnote-definition-label">222</sup>
<p>Simon Reardon, J. A., &amp; Pérez, R. A. (2010). Agroecology and the development of indicators of food sovereignty in Cuban food systems. Journal of Sustainable Agriculture, 34(8), 907-922.</p>
</div>
<div class="footnote-definition" id="RovmVS"><sup class="footnote-definition-label">140</sup>
<p>Singh, V. K., Singh, M., Singh, S. K., Kumar, C., &amp; Kumar, A. (2019). Sustainable Agricultural Practices Using Beneficial Fungi Under Changing Climate Scenario. In Climate Change and Agricultural Ecosystems (pp. 25-42). Woodhead Publishing.</p>
</div>
<div class="footnote-definition" id="zyYGwn"><sup class="footnote-definition-label">206</sup>
<p>Small farmers feel left out amid a boom in African fertilizer production. Rupa Shenoy. January 22, 2020. Retrieved from <a href="https://grist.org/food/small-farmers-feel-left-out-amid-a-boom-in-african-fertilizer-production/">https://grist.org/food/small-farmers-feel-left-out-amid-a-boom-in-african-fertilizer-production/</a></p>
</div>
<div class="footnote-definition" id="GnLT6F"><sup class="footnote-definition-label">2</sup>
<p>Smil, V. (2004). Enriching the earth: Fritz Haber, Carl Bosch, and the transformation of world food production. MIT press.</p>
</div>
<div class="footnote-definition" id="iyG-9s"><sup class="footnote-definition-label">70</sup>
<p>Smith, L. E. (2005). The struggle for Western Sahara: What future for Africa’s last colony?. The Journal of North African Studies, 10(3-4), 545-563.</p>
</div>
<div class="footnote-definition" id="VRkTI1"><sup class="footnote-definition-label">89</sup>
<p>Smith, Laurence G.; Kirk, Guy J. D.; Jones, Philip J.; Williams, Adrian G. (2019): The greenhouse gas impacts of converting food production in England and Wales to organic methods. In Nat Commun 10 (1), pp. 1–10. DOI: 10.1038/s41467-019-12622-7.</p>
</div>
<div class="footnote-definition" id="gq-Glv"><sup class="footnote-definition-label">33</sup>
<p>Snyder, C. S., Bruulsema, T. W., Jensen, T. L., &amp; Fixen, P. E. (2009). Review of greenhouse gas emissions from crop production systems and fertilizer management effects. Agriculture, Ecosystems &amp; Environment, 133(3-4), 247-266.</p>
</div>
<div class="footnote-definition" id="aFAZbr"><sup class="footnote-definition-label">180</sup>
<p>Starmer, E., &amp; Wise, T. A. (2007). Feeding at the Trough: Industrial Livestock Firms Saved $35 Billion from Low Feed Prices. GDAE Policy Brief, (07-03).</p>
</div>
<div class="footnote-definition" id="EX5yPb"><sup class="footnote-definition-label">151</sup>
<p>Stenmarck, Â., Jensen, C., Quested, T., Moates, G., Buksti, M., Cseh, B., … &amp; Scherhaufer, S. (2016). Estimates of European food waste levels. IVL Swedish Environmental Research Institute.</p>
</div>
<div class="footnote-definition" id="NOg9Fp"><sup class="footnote-definition-label">11</sup>
<p>Stewart, W. M., Dibb, D. W., Johnston, A. E., &amp; Smyth, T. J. (2005). The contribution of commercial fertilizer nutrients to food production. Agronomy Journal, 97(1), 1-6.</p>
</div>
<div class="footnote-definition" id="EUeRDZ"><sup class="footnote-definition-label">290</sup>
<p>Strong Demand From Farmers For Crop-Boosting Potash Triggers A Mining Rush. Tim Treadgold. March 20, 2019. <a href="https://www.forbes.com/sites/timtreadgold/2019/03/20/strong-demand-from-farmers-for-crop-boosting-potash-triggers-a-mining-rush/#39d26f54436a">https://www.forbes.com/sites/timtreadgold/2019/03/20/strong-demand-from-farmers-for-crop-boosting-potash-triggers-a-mining-rush/#39d26f54436a</a></p>
</div>
<div class="footnote-definition" id="Ta21E6"><sup class="footnote-definition-label">207</sup>
<p>Subsidized Fertilizer: The Answer to Africa’s Food Crisis? Brendan Borrell. June 18, 2009. <a href="https://www.scientificamerican.com/article/subsidized-fertilizer-africa/">https://www.scientificamerican.com/article/subsidized-fertilizer-africa/</a></p>
</div>
<div class="footnote-definition" id="kjx5p9"><sup class="footnote-definition-label">23</sup>
<p>Subsidizing Waste: How Inefficient US Farm Policy Costs Taxpayers, Businesses, and Farmers Billions. Union of Concerned Scientists. August 2016.</p>
</div>
<div class="footnote-definition" id="y85DN-"><sup class="footnote-definition-label">40</sup>
<p>Sumner, D. A., &amp; Zulauf, C. R. (2012). Economic and environmental effects of agricultural insurance programs (No. 643-2016-44463).</p>
</div>
<div class="footnote-definition" id="0D4TCM"><sup class="footnote-definition-label">136</sup>
<p>Suthar, H., Hingurao, K., Vaghashiya, J., &amp; Parmar, J. (2017). Fermentation: A Process for Biofertilizer Production. In Microorganisms for Green Revolution (pp. 229-252). Springer, Singapore.</p>
</div>
<div class="footnote-definition" id="jJvKtV"><sup class="footnote-definition-label">36</sup>
<p>Syers, J. K., Johnston, A. E., &amp; Curtin, D. (2008). Efficiency of soil and fertilizer phosphorus use. FAO Fertilizer and plant nutrition bulletin, 18(108).</p>
</div>
<div class="footnote-definition" id="sKI1FQ"><sup class="footnote-definition-label">65</sup>
<p>Teaiwa, K. (2015). Ruining Pacific islands: Australia’s phosphate imperialism. Australian Historical Studies, 46(3), 374-391.</p>
</div>
<div class="footnote-definition" id="805oOe"><sup class="footnote-definition-label">22</sup>
<p>The Danger Downstream. Spike Johnson. January 28, 2020. Retrieved from <a href="https://grist.org/food/gulf-shrimpers-fight-for-their-livelihoods-in-a-fertilizer-fueled-dead-zone/">https://grist.org/food/gulf-shrimpers-fight-for-their-livelihoods-in-a-fertilizer-fueled-dead-zone/</a></p>
</div>
<div class="footnote-definition" id="W76QN-"><sup class="footnote-definition-label">54</sup>
<p>The Desert Rock That Feeds the World. Alex Kasprak. November 29, 2016. <a href="https://www.theatlantic.com/science/archive/2016/11/the-desert-rock-that-feeds-the-world/508853/">https://www.theatlantic.com/science/archive/2016/11/the-desert-rock-that-feeds-the-world/508853/</a></p>
</div>
<div class="footnote-definition" id="dI882e"><sup class="footnote-definition-label">267</sup>
<p>The Environmental Situation in Cuba. People in Need. December 2015.</p>
</div>
<div class="footnote-definition" id="LB_VhL"><sup class="footnote-definition-label">118</sup>
<p>The Farm Bureau: Big Oil’s Unnoticed Ally Fighting Climate Science and Policy. Neela Banerjee, Georgina Gustin, John H. Cushman Jr. December 21, 2018. Retrieved from <a href="https://insideclimatenews.org/news/20122018/american-farm-bureau-fossil-fuel-nexus-climate-change-denial-science-agriculture-carbon-policy-opposition">https://insideclimatenews.org/news/20122018/american-farm-bureau-fossil-fuel-nexus-climate-change-denial-science-agriculture-carbon-policy-opposition</a>.</p>
</div>
<div class="footnote-definition" id="WUdPJg"><sup class="footnote-definition-label">199</sup>
<p>The fight for the future of food. Joeva Rock. December 18, 2019. Retrieved from <a href="https://africasacountry.com/2019/12/the-fight-for-the-future-of-food">https://africasacountry.com/2019/12/the-fight-for-the-future-of-food</a></p>
</div>
<div class="footnote-definition" id="n67Qtk"><sup class="footnote-definition-label">228</sup>
<p>The global farmland grab in 2016: how big, how bad? GRAIN. June 14, 2016. Retrieved from <a href="https://www.grain.org/article/entries/5492-the-global-farmland-grab-in-2016-how-big-how-bad">https://www.grain.org/article/entries/5492-the-global-farmland-grab-in-2016-how-big-how-bad</a></p>
</div>
<div class="footnote-definition" id="qsO0rc"><sup class="footnote-definition-label">230</sup>
<p>The Great Land Robbery. Vann R. Newkirk II. September 2019. Retrieved from <a href="https://www.theatlantic.com/magazine/archive/2019/09/this-land-was-our-land/594742/">https://www.theatlantic.com/magazine/archive/2019/09/this-land-was-our-land/594742/</a></p>
</div>
<div class="footnote-definition" id="0fy2T7"><sup class="footnote-definition-label">101</sup>
<p>The How-To of Organic Hydroponics. Lynette Morgan. January 30, 2014. <a href="https://www.maximumyield.com/the-how-to-of-organic-hydroponics/2/1299">https://www.maximumyield.com/the-how-to-of-organic-hydroponics/2/1299</a></p>
</div>
<div class="footnote-definition" id="2vb73k"><sup class="footnote-definition-label">172</sup>
<p>The Key to Saving Family Farms Is in the Soil. David R. Montgomery. October 19, 2019. <a href="https://www.ecowatch.com/family-farms-regenerative-farming-practices-2641025788.html">https://www.ecowatch.com/family-farms-regenerative-farming-practices-2641025788.html</a></p>
</div>
<div class="footnote-definition" id="CagkTS"><sup class="footnote-definition-label">1</sup>
<p>The Mysteries of Fertilizer. Michael Tortorello. April 14, 2009. <a href="https://topics.blogs.nytimes.com/2009/04/14/the-mysteries-of-fertilizer/">https://topics.blogs.nytimes.com/2009/04/14/the-mysteries-of-fertilizer/</a></p>
</div>
<div class="footnote-definition" id="xZRHAQ"><sup class="footnote-definition-label">257</sup>
<p>The Oil We Eat: Following the Food Chain back to Iraq. Richard Manning. May 23, 2004. <a href="https://www.resilience.org/stories/2004-05-23/oil-we-eat-following-food-chain-back-iraq/">https://www.resilience.org/stories/2004-05-23/oil-we-eat-following-food-chain-back-iraq/</a></p>
</div>
<div class="footnote-definition" id="7uvLUI"><sup class="footnote-definition-label">112</sup>
<p>The way we make fertilizer sucks, but we haven’t had a good alternative … until now. Nathanael Johnson. April 29, 2016. <a href="https://grist.org/article/the-way-we-make-fertilizer-sucks-but-we-havent-had-a-good-alternative-until-now/">https://grist.org/article/the-way-we-make-fertilizer-sucks-but-we-havent-had-a-good-alternative-until-now/</a></p>
</div>
<div class="footnote-definition" id="a2JdEX"><sup class="footnote-definition-label">7</sup>
<p>Tilman, D., Cassman, K. G., Matson, P. A., Naylor, R., &amp; Polasky, S. (2002). Agricultural sustainability and intensive production practices. Nature, 418(6898), 671.</p>
</div>
<div class="footnote-definition" id="29nIvt"><sup class="footnote-definition-label">242</sup>
<p>Tomei, J., &amp; Helliwell, R. (2016). Food versus fuel? Going beyond biofuels. Land use policy, 56, 320-326.</p>
</div>
<div class="footnote-definition" id="Kj0lzS"><sup class="footnote-definition-label">126</sup>
<p>Transforming Food Waste into Plant-Based Technologies: Re-Nuble. September 3, 2019. Retrieved from <a href="https://www.nycfoodpolicy.org/transforming-food-waste-into-plant-based-technologies-re-nuble/">https://www.nycfoodpolicy.org/transforming-food-waste-into-plant-based-technologies-re-nuble/</a></p>
</div>
<div class="footnote-definition" id="0UY7nY"><sup class="footnote-definition-label">72</sup>
<p>UN must monitor human rights in Western Sahara and Sahrawi refugee camps. Amnesty International. April 26, 2016. <a href="https://www.amnesty.org/en/latest/news/2016/04/un-must-monitor-human-rights-in-western-sahara-and-sahrawi-refugee-camps/">https://www.amnesty.org/en/latest/news/2016/04/un-must-monitor-human-rights-in-western-sahara-and-sahrawi-refugee-camps/</a></p>
</div>
<div class="footnote-definition" id="B48qp4"><sup class="footnote-definition-label">73</sup>
<p>UN must monitor human rights in Western Sahara and Sahrawi refugee camps. Amnesty International. April 26, 2019. <a href="https://www.amnesty.org/download/Documents/MDE2902662019ENGLISH.pdf">https://www.amnesty.org/download/Documents/MDE2902662019ENGLISH.pdf</a></p>
</div>
<div class="footnote-definition" id="hNT-Wb"><sup class="footnote-definition-label">264</sup>
<p>Uriarte, M. (2002). Cuba, social policy at a crossroads: Maintaining priorities, transforming practice.</p>
</div>
<div class="footnote-definition" id="lStjEq"><sup class="footnote-definition-label">39</sup>
<p>USDA Squeezes the Food Industry with Outdated Subsidies. Mark A Perelman. May 14, 2018. Retrieved from <a href="https://cbey.yale.edu/our-stories/usda-squeezes-the-food-industry-with-outdated-subsidies">https://cbey.yale.edu/our-stories/usda-squeezes-the-food-industry-with-outdated-subsidies</a></p>
</div>
<div class="footnote-definition" id="XqfIyA"><sup class="footnote-definition-label">90</sup>
<p>van der Werf, H. M., Knudsen, M. T., &amp; Cederberg, C. (2020). Towards better representation of organic agriculture in life cycle assessment. Nature Sustainability, 1-7.</p>
</div>
<div class="footnote-definition" id="UAunoy"><sup class="footnote-definition-label">16</sup>
<p>Van Ginkel, S. W., Igou, T., &amp; Chen, Y. (2017). Energy, water and nutrient impacts of California-grown vegetables compared to controlled environmental agriculture systems in Atlanta, GA. Resources, Conservation and Recycling, 122, 319-325.</p>
</div>
<div class="footnote-definition" id="-TlPys"><sup class="footnote-definition-label">56</sup>
<p>Van Kauwenbergh, S. J. (2010). World phosphate rock reserves and resources (p. 48). Muscle Shoals: IFDC.</p>
</div>
<div class="footnote-definition" id="N9vj7r"><sup class="footnote-definition-label">102</sup>
<p>Vertical farming and hydroponics on the spectrum of sustainability. Alicia Miller. April 5, 2018. Retrieved from <a href="https://sustainablefoodtrust.org/articles/vertical-farming-and-hydroponics-on-the-spectrum-of-sustainability/">https://sustainablefoodtrust.org/articles/vertical-farming-and-hydroponics-on-the-spectrum-of-sustainability/</a></p>
</div>
<div class="footnote-definition" id="K-CbWR"><sup class="footnote-definition-label">291</sup>
<p>Vietnam’s Low-tech Food System Takes Advantage of Decay. Aaron Vansintjan. February 23, 2017. <a href="https://www.resilience.org/stories/2017-02-23/vietnams-low-tech-food-system-takes-advantage-of-decay/">https://www.resilience.org/stories/2017-02-23/vietnams-low-tech-food-system-takes-advantage-of-decay/</a></p>
</div>
<div class="footnote-definition" id="aw_WOY"><sup class="footnote-definition-label">132</sup>
<p>Vishwakarma, K., Upadhyay, N., Kumar, N., Tripathi, D. K., Chauhan, D. K., Sharma, S., &amp; Sahi, S. (2018). Potential Applications and Avenues of Nanotechnology in Sustainable Agriculture. In Nanomaterials in Plants, Algae, and Microorganisms (pp. 473-500). Academic Press.</p>
</div>
<div class="footnote-definition" id="z_RsHF"><sup class="footnote-definition-label">220</sup>
<p>von Braun, J., &amp; Tadesse, G. (2012). Global food price volatility and spikes: an overview of costs, causes, and solutions. ZEF-Discussion Papers on Development Policy, (161).</p>
</div>
<div class="footnote-definition" id="seYruI"><sup class="footnote-definition-label">292</sup>
<p>Warnock, J. W. (2011). Exploiting Saskatchewan’s Potash: Who Benefits?. CCPA-Saskatchewan Office.</p>
</div>
<div class="footnote-definition" id="wjZLBF"><sup class="footnote-definition-label">41</sup>
<p>Weber, J. G., Key, N., &amp; O’Donoghue, E. (2016). Does federal crop insurance make environmental externalities from agriculture worse?. Journal of the Association of Environmental and Resource Economists, 3(3), 707-742.</p>
</div>
<div class="footnote-definition" id="89_Ari"><sup class="footnote-definition-label">165</sup>
<p>What is parity? (And why you should care). Eric Holt-Giménez, Heidi Kleiner. May 20, 2019. Retrieved from <a href="https://foodfirst.org/what-is-parity-and-why-you-should-care/">https://foodfirst.org/what-is-parity-and-why-you-should-care/</a></p>
</div>
<div class="footnote-definition" id="GfNxkv"><sup class="footnote-definition-label">69</sup>
<p>White, N. (2015). Conflict stalemate in Morocco and Western Sahara: Natural resources, legitimacy and political recognition. British Journal of Middle Eastern Studies, 42(3), 339-357.</p>
</div>
<div class="footnote-definition" id="X5W5JY"><sup class="footnote-definition-label">293</sup>
<p>Why Rising Lithium Production Could Crush Fertilizer Stocks. Maxx Chatsko. August 9, 2017. <a href="https://www.fool.com/investing/2017/08/09/why-rising-lithium-production-could-crush-fertiliz.aspx">https://www.fool.com/investing/2017/08/09/why-rising-lithium-production-could-crush-fertiliz.aspx</a></p>
</div>
<div class="footnote-definition" id="rWAaaf"><sup class="footnote-definition-label">294</sup>
<p>Why Soil Matters. Renee Cho. April 12, 2012. <a href="https://blogs.ei.columbia.edu/2012/04/12/why-soil-matters/">https://blogs.ei.columbia.edu/2012/04/12/why-soil-matters/</a></p>
</div>
<div class="footnote-definition" id="bkCrje"><sup class="footnote-definition-label">160</sup>
<p>Williams, H., Wikström, F., Otterbring, T., Löfgren, M., &amp; Gustafsson, A. (2012). Reasons for household food waste with special attention to packaging. Journal of cleaner production, 24, 141-148.</p>
</div>
<div class="footnote-definition" id="7rwDL2"><sup class="footnote-definition-label">214</sup>
<p>Wolford, W. (2019). The colonial roots of agricultural modernization in Mozambique: the role of research from Portugal to ProSavana. The Journal of Peasant Studies, 1-20.</p>
</div>
<div class="footnote-definition" id="H3xYUs"><sup class="footnote-definition-label">295</sup>
<p>World Food Situation: FAO Food Price Index. October 22, 2020. Retrieved from <a href="http://www.fao.org/worldfoodsituation/foodpricesindex/en/">http://www.fao.org/worldfoodsituation/foodpricesindex/en/</a></p>
</div>
<div class="footnote-definition" id="NuvFC7"><sup class="footnote-definition-label">57</sup>
<p>World Phosphate Rock Reserves and Resources. S. Van Kauwenbergh. IFDC. November 2010. <a href="http://www.firt.org/sites/default/files/SteveVanKauwenbergh_World_Phosphate_Rock_Reserve.pdf">http://www.firt.org/sites/default/files/SteveVanKauwenbergh_World_Phosphate_Rock_Reserve.pdf</a></p>
</div>
<div class="footnote-definition" id="t83ZrN"><sup class="footnote-definition-label">48</sup>
<p>Zhou, X., Passow, F. H., Rudek, J., von Fisher, J. C., Hamburg, S. P., &amp; Albertson, J. D. (2019). Estimation of methane emissions from the US ammonia fertilizer industry using a mobile sensing approach. Elem Sci Anth, 7(1).</p>
</div>
<div class="footnote-definition" id="n1iP7n"><sup class="footnote-definition-label">196</sup>
<p>Zimbabwe’s food security in crisis—but not for reasons you might think. Anna Brazier. December 17, 2019. Retrieved from <a href="https://africasacountry.com/2019/12/zimbabwes-food-security-in-crisis-but-not-for-reasons-you-might-think/">https://africasacountry.com/2019/12/zimbabwes-food-security-in-crisis-but-not-for-reasons-you-might-think/</a></p>
</div>
<div class="footnote-definition" id="NGRjMm"><sup class="footnote-definition-label">127</sup>
<p>Tarayre, C., De Clercq, L., Charlier, R., Michels, E., Meers, E., Camargo-Valero, M., &amp; Delvigne, F. (2016). New perspectives for the design of sustainable bioprocesses for phosphorus recovery from waste. Bioresource Technology, 206, 264-274.</p>
</div>
<div class="footnote-definition" id="NWY5MW"><sup class="footnote-definition-label">76</sup>
<p>Rowe, H., Withers, P. J., Baas, P., Chan, N. I., Doody, D., Holiman, J., … &amp; Sharpley, A. N. (2016). Integrating legacy soil phosphorus into sustainable nutrient management strategies for future food, bioenergy and water security. Nutrient Cycling in Agroecosystems, 104(3), 393-412.</p>
</div>
<div class="footnote-definition" id="MTY2Nz"><sup class="footnote-definition-label">231</sup>
<p>Ouma, S. (2016). From financialization to operations of capital: Historicizing and disentangling the finance–farmland-nexus. Geoforum, 72, 82-93.</p>
</div>
<div class="footnote-definition" id="Mjg2OT"><sup class="footnote-definition-label">229</sup>
<p>Henderson, C. (2020). Land grabs reexamined: Gulf Arab agro-commodity chains and spaces of extraction. Environment and Planning A: Economy and Space, 0308518X20956657.</p>
</div>
<div class="footnote-definition" id="M2JiNG"><sup class="footnote-definition-label">148</sup>
<p>Shaw, A., &amp; Wilson, K. (2020). The Bill and Melinda Gates Foundation and the necro-populationism of ‘climate-smart’ agriculture. Gender, Place &amp; Culture, 27(3), 370-393.</p>
</div>
<div class="footnote-definition" id="OWZmZG"><sup class="footnote-definition-label">116</sup>
<p>Comer, B. M., Fuentes, P., Dimkpa, C. O., Liu, Y. H., Fernandez, C. A., Arora, P., … &amp; Medford, A. J. (2019). Prospects and challenges for solar fertilizers. Joule, 3(7), 1578-1605.</p>
</div>
<div class="footnote-definition" id="NDRlNz"><sup class="footnote-definition-label">259</sup>
<p>After Agroecology. Nassib Mugwanya. February 4, 2019. Retrieved from <a href="https://thebreakthrough.org/journal/no-10-winter-2019/after-agroecology">https://thebreakthrough.org/journal/no-10-winter-2019/after-agroecology</a></p>
</div>
<div class="footnote-definition" id="NTAxNG"><sup class="footnote-definition-label">256</sup>
<p>Mugwanya, N. (2019). Why agroecology is a dead end for Africa. Outlook on Agriculture, 48(2), 113-116.</p>
</div>
<div class="footnote-definition" id="NzY5M2"><sup class="footnote-definition-label">107</sup>
<p>Graamans, L., Baeza, E., Van Den Dobbelsteen, A., Tsafaras, I., &amp; Stanghellini, C. (2018). Plant factories versus greenhouses: Comparison of resource use efficiency. Agricultural Systems, 160, 31-43.</p>
</div>
<div class="footnote-definition" id="Njg3MG"><sup class="footnote-definition-label">109</sup>
<p>Razon, L. F. (2015). Is nitrogen fixation (once again) “vital to the progress of civilized humanity”?. Clean Technologies and Environmental Policy, 17(2), 301-307.</p>
</div>
<div class="footnote-definition" id="NjhhZG"><sup class="footnote-definition-label">119</sup>
<p>The U.S. Fertilizer Industry and Climate Change Policy. The Fertilizer Institute. <a href="https://kochfertilizer.com/pdf/TFI2009ClimateChange.pdf">https://kochfertilizer.com/pdf/TFI2009ClimateChange.pdf</a></p>
</div>
<div class="footnote-definition" id="ZDdmZm"><sup class="footnote-definition-label">113</sup>
<p>Brown, K. A., Harris, D. F., Wilker, M. B., Rasmussen, A., Khadka, N., Hamby, H., … &amp; King, P. W. (2016). Light-driven dinitrogen reduction catalyzed by a CdS: nitrogenase MoFe protein biohybrid. Science, 352(6284), 448-450.</p>
</div>
<div class="footnote-definition" id="NjI3ZT"><sup class="footnote-definition-label">117</sup>
<p>Martín, A. J., &amp; Pérez-Ramírez, J. (2019). Heading to distributed electrocatalytic conversion of small abundant molecules into fuels, chemicals, and fertilizers. Joule, 3(11), 2602-2621.</p>
</div>
<div class="footnote-definition" id="YjAwYz"><sup class="footnote-definition-label">235</sup>
<p>Cotula, L., Dyer, N., &amp; Vermeulen, S. (2008). Bioenergy and land tenure: The implications of Biofuels for land tenure and land policy. International Institute for Environment and Development, London.</p>
</div>
<div class="footnote-definition" id="YzcxZm"><sup class="footnote-definition-label">260</sup>
<p>How to Make Biomass Energy Sustainable Again. Kris De Decker. <a href="https://www.lowtechmagazine.com/2020/09/how-to-make-biomass-energy-sustainable-again.html">https://www.lowtechmagazine.com/2020/09/how-to-make-biomass-energy-sustainable-again.html</a></p>
</div>
<div class="footnote-definition" id="ZmFlM2"><sup class="footnote-definition-label">271</sup>
<p>Pachauri, R. K., Allen, M. R., Barros, V. R., Broome, J., Cramer, W., Christ, R., … &amp; Dubash, N. K. (2014). Climate change 2014: synthesis report. Contribution of Working Groups I, II and III to the fifth assessment report of the Intergovernmental Panel on Climate Change (p. 151). IPCC.</p>
</div>
<div class="footnote-definition" id="NzA0ND"><sup class="footnote-definition-label">250</sup>
<p>De Schutter, O. (2010). Report Submitted by the Special Rapporteur on the Right to Food: Human Rigths Council Sixteenth Session: Agenda Item 3: Promotion and Protection of All Human Rights, Civil, Political, Economic, Social and Cultural Rights, Including the Right to Develop. United Nations (UN).</p>
</div>
<div class="footnote-definition" id="MDI5YW"><sup class="footnote-definition-label">261</sup>
<p>Perennial Crops: New Hardware for Agriculture. The Land Institute. <a href="https://landinstitute.org/our-work/perennial-crops/">https://landinstitute.org/our-work/perennial-crops/</a></p>
</div>
<div class="footnote-definition" id="MDJhOG"><sup class="footnote-definition-label">247</sup>
<p>Glover, J. D., Reganold, J. P., &amp; Cox, C. M. (2012). Plant perennials to save Africa’s soils. Nature, 489(7416), 359-361.</p>
</div>
<div class="footnote-definition" id="MzFjM2"><sup class="footnote-definition-label">248</sup>
<p>Ajayi, O. C., Place, F., Akinnifesi, F. K., &amp; Sileshi, G. W. (2011). Agricultural success from Africa: the case of fertilizer tree systems in southern Africa (Malawi, Tanzania, Mozambique, Zambia and Zimbabwe). International journal of agricultural sustainability, 9(1), 129-136.</p>
</div>
<div class="footnote-definition" id="OWYzOT"><sup class="footnote-definition-label">245</sup>
<p>‘Junk Agroecology’: The corporate capture of agroecology for a partial ecological transition without social justice. April 2020. Transnational Institute, Friends of the Earth International, Crocevia.</p>
</div>
<div class="footnote-definition" id="farm-calc"><sup class="footnote-definition-label">238</sup>
<p>Large-scale family farms represent 2.8% of farms, but encompass 39.0% of the value of production. Large-scale family farms are defined as those with $1 million or more in gross cash farm income (GCFI) (“a measure of the farm’s revenue that includes sales of crops and livestock, government payments, and other farm-related income, including fees from production contracts”). This includes farms with with a GCFI of $5 million or more (0.3% of all US farms). 2% of farms (and 13% of production) are “nonfamily farms” which include “partnerships of unrelated partners, closely held nonfamily corporations, farms with a hired operator unrelated to the owners, and (relatively few) publicly held corporations.”. 15% of these nonfamily farms (0.3% of all farms) have a GCFI of $1 million or more and account for 89% of the nonfamily farm production (so 11.6% of total production). So altogether, farms with a GCFI of $1 million or more account for 11.6+39=50.6% of the value of all production while representing only 2.8+0.3=3.1% of all farms.<sup class="footnote-reference"><a href="#_D3qLb">173</a></sup></p>
</div>
<div class="footnote-definition" id="cornflakes-calc"><sup class="footnote-definition-label">181</sup>
<p>At the time of writing (November 28, 2019), the <a href="https://markets.businessinsider.com/commodities/corn-price">price of corn is about $3.63/bushel</a>, and <a href="https://www.walmart.com/ip/Kellogg-s-Corn-Flakes-Breakfast-Cereal-Original-18-oz/10818608?athcpid=10818608&amp;athpgid=athenaItemPage&amp;athcgid=null&amp;athznid=PWVUB&amp;athieid=v0&amp;athstid=CS004&amp;athguid=35720d11-b54-16eb3458867a76&amp;athancid=null&amp;athena=true">an 18oz box of corn flakes is $3.28 at Walmart</a>. In <a href="http://smartlabel.kelloggs.com/Product/Index/00038000001208#ingredients">the ingredients list for corn flakes</a>, milled corn is listed as the first ingredient, followed by sugar; there are 4g of added sugar per serving size and 12 servings in an 18oz box, so 48g (1.7oz) added sugar total, so we can assume the corn contents are closer to <code>18 - 1.7 = 16.3oz</code>. One bushel of corn is 56lbs or 896oz. <code>16.3/896 * 3.63</code> means a 18oz box of corn flakes has about 6.6c of corn in it. The <a href="https://markets.businessinsider.com/commodities/sugar-price">price of sugar is today is $0.13/lb</a>, so 1.7oz of sugar costs 1.4c. The main ingredients then cost 8 cents, representing 2.4% of the retail price (there is intermediary processing, i.e. corn milling, but safe to say this does not introduce enough of a price increase to explain the remaining retail price).</p>
</div>
<div class="footnote-definition" id="farmer-death-dispute"><sup class="footnote-definition-label">225</sup>
<p>There is some dispute over the relationship between farmer suicides and the dynamics described here, but these tend to ignore that many farmers, when struggling with income, take on other work and thus may not be categorized as farmers in data<sup class="footnote-reference"><a href="#fFH_WZ">223</a></sup>. Similarly, that the most common stated reasons for suicide are not economic, but personal or family related, neglects that economic problems may manifest as these other types of problems<sup class="footnote-reference"><a href="#5RuiK0">224</a></sup>. It fails to examine the relational aspects that might be driving suicides—if someone is dependent on someone who farms for the primary income, but may do other work (this might be true for the “housewives” category, who fall under the “non-working population” definition by the Census of India), their suicide may relate to agriculture work even if they themselves do not fall under that category. Even for those instances where agrarian suicide is not directly attributed to financial reasons (e.g. alcoholism), that still may be the indirect cause.</p>
</div>
<div class="footnote-definition" id="ZTliM2"><sup class="footnote-definition-label">175</sup>
<p>Ag. Canada Tells Ontario Farmers to Expect The Worst Year Ever. May 06, 2010. Retrieved from <a href="https://www.farms.com/news/ag-canada-tells-ontario-farmers-to-expect-the-worst-year-ever-30219.aspx">https://www.farms.com/news/ag-canada-tells-ontario-farmers-to-expect-the-worst-year-ever-30219.aspx</a></p>
</div>
<div class="footnote-definition" id="MDY1MW"><sup class="footnote-definition-label">255</sup>
<p>US academics feel the invisible hand of politicians and big agriculture. Kate Cox, Claire Brown. January 31, 2019. <a href="https://www.theguardian.com/environment/2019/jan/31/us-academics-feel-the-invisible-hand-of-politicians-and-big-agriculture">https://www.theguardian.com/environment/2019/jan/31/us-academics-feel-the-invisible-hand-of-politicians-and-big-agriculture</a></p>
</div>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 15: Divine Demons, In-Game Game, and Seamless Textures</title><link>projects/fugue/15</link><description><![CDATA[Modeling demonic divinitiesGrowing up I was very fond of Buddhist art and I would make an effort to visit various Buddhist temples whenever…]]></description><category>projects/fugue</category><pubDate>Tue, 21 Jun 2022 20:47:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<h2>Modeling demonic divinities</h2>
<p>Growing up I was very fond of Buddhist art and I would make an effort to visit various Buddhist temples whenever my family would go to China to see my grandparents. I found the paintings and sculptures of terrifying figures to be strangely calming, and only later did I learn that these fearsome beings are in fact benevolent, wrathful “protectors”.</p>
<p><figure>
            <a href="/assets/uploads/fugue/demonic_divine.jpg" title="">
            <img src="/assets/uploads/fugue/demonic_divine.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure></em>, Rob Linrothe, Jeff Watt</p>
<p>While visiting Kira’s parents last week I had the opportunity to read through <a href="https://www.goodreads.com/book/show/343219.Demonic_Divine">the catalogue</a> for one of the Rubin Museum’s opening exhibitions, “<a href="https://rubinmuseum.org/blog/10-years-ago-today">Demonic Divine</a>” which was exactly on this topic. I’ve wanted to find some way to draw from this tradition of “divine demons” for <em>Fugue</em> and reading through the catalogue helped me figure out how I could do that.</p>
<p>Without going into too much detail, one fundamental <em>Fugue</em> world-element is the phenomenon of “hauntings”, which are mental blocks and fears that characters experience. The character progression system is based around confronting and resolving these hauntings (perhaps in addition to a simpler experience-based system, not really sure yet). The way I’ve pictured this is that progression happens along a path (the character’s “道”/“way” in a sense) and these hauntings are literal roadblocks, represented by these demons, along this path. So a key question is how exactly does this process of resolving hauntings<sup class="footnote-reference"><a href="#1">1</a></sup> work?</p>
<p>One other feature I want to include is an in-game game (tentatively called “<em>Gem</em>”), sort of like <a href="https://finalfantasy.fandom.com/wiki/Triple_Triad_(Final_Fantasy_VIII)"><em>Triple Triad</em> in Final Fantasy VIII</a>. Including something like that lets you do a lot of interesting things: explore its cultural significance, show how different places and people interpret the game (perhaps with different house rules and variations), explore all the infrastructure that comes up around a relatively simple game once it becomes a major phenomenon (rules committees, judges, player associations, its role in national conflict, etc), and in general be a means of showing different value systems, thought processes, philosophies, etc, like <a href="https://en.wikipedia.org/wiki/The_Player_of_Games#Azad">Azad in Iain M. Banks’ <em>The Player of Games</em></a>. I’m still working out <em>Gem</em>’s design, but so far it’s like some combination of chess, checkers, and Chinese checkers, with the variability of a card game–i.e. many different pieces with different abilities, and players can build a “deck” of pieces to play with like they might build a deck in <em>Magic: The Gathering</em>.</p>
<p>My current thinking is that to get through a demonic roadblock you challenge the demon to a game of <em>Gem</em>, in a “<a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/ChessWithDeath">chess with death</a>” style. The demon itself is represented as a piece on the game board that you need to remove, sort of like the king in chess. However the goal of the game is not necessarily to “defeat” the demon. Each demon represents a mental block/fear that has a complementary virtue; the point is not to excise the demon from your mind but to recognize its value as an ally. In the context of <em>Gem</em>, this means capturing the demon instead of destroying it. If I design <em>Gem</em> right, then capturing the demon will be comparatively difficult to destroying it. If you’re able to capture it (maybe “convert” is a better term) then you have access to that piece for future games of <em>Gem</em> and perhaps some kind of bonus “blessing” for the character outside of <em>Gem</em>.</p>
<p>I’ve been working on modeling the first demon, based on <a href="https://en.wikipedia.org/wiki/Citipati_(Buddhism)">Chitipati</a>. Chitipati is two skeletons depicted with a frame of flames which acts as a <em>memento mori</em> and more generally represent endless change:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chitipati_art.jpg" title="">
            <img src="/assets/uploads/fugue/chitipati_art.jpg" title="">
            </a>
            <figcaption>Chitipati, from </figcaption>
            </figure></a></p>
<p>The first part I tried to model is the flame halo. Similar features are common in wrathful diety iconography so this model would be useful for other demons too. I made several attempts at modeling these flames using only Blender’s geometry nodes with the hope of generating them procedurally, but they never came out well (maybe because of my inexperience with geometry nodes). In the end I hand-modeled five flames and use geometry nodes to distribute them in an arch, which I’m happy with:</p>
<p><figure>
            <a href="/assets/uploads/fugue/flame_arch.jpg" title="">
            <img src="/assets/uploads/fugue/flame_arch.jpg" title="">
            </a>
            <figcaption>Flame arch</figcaption>
            </figure>
<p>When I moved on to modeling Chitipati I started with a fair amount of detail. It did not look very good, so I gave it another shot from scratch using a rougher approach, and it looked a lot better (though the hands look TERRIBLE…I’ll give them more attention later maybe, to organize them as particular <em>mudras</em>). Relying on textures for detail rather than capturing it in the mesh makes a lot more sense for this game, especially if I’m using photo-textures. And because I’m rendering out at a lower resolution, finer mesh detail won’t really show up anyways.</p>
<p>A side note: I’m modeling this demon as only one skeleton, rather than Chitipati’s two.</p>
<p><figure>
            <a href="/assets/uploads/fugue/chitipati.jpg" title="">
            <img src="/assets/uploads/fugue/chitipati.jpg" title="">
            </a>
            <figcaption>Test render</figcaption>
            </figure>
<p>This test render’s resolution is high enough where the lack of mesh detail is apparent (pretty boxy looking in some parts). When rendered in-game the low detail looks more appropriate:</p>
<p><figure>
            <a href="/assets/uploads/fugue/chitipati_in_game.png" title="">
            <img src="/assets/uploads/fugue/chitipati_in_game.png" title="">
            </a>
            <figcaption>In-game</figcaption>
            </figure>
<h2>Infilling and seamless tiling with GIMP</h2>
<p>One idea for the flame halo was to use content-aware fill or a similar infilling algorithm to generate a full image of the flame background and then some how turn that into a 3d model. That route didn’t really work–I couldn’t make it look good; it just looked flat and janky–but I did find an infilling plugin for GIMP called <a href="https://github.com/bootchk/resynthesizer">Resynthesizer</a> that is really promising. It didn’t work very well for the flame frame (perhaps because it’s an illustration or because there isn’t a lot of content to reference for the infilling) but it works much better with texture photography. Here’s an example using an image of some overgrowth:</p>
<p><figure>
            <a href="/assets/uploads/fugue/tiling/bush_source.jpg" title="">
            <img src="/assets/uploads/fugue/tiling/bush_source.jpg" title="">
            </a>
            <figcaption>The original image</figcaption>
            </figure>
<p>After applying the Resynthesis plugin (using <code>Filters &gt; Map &gt; Resynthesize</code>) and checking “Make horizontally tileable” and “Make vertically tileable”:</p>
<p><figure>
            <a href="/assets/uploads/fugue/tiling/bush_filled.jpg" title="">
            <img src="/assets/uploads/fugue/tiling/bush_filled.jpg" title="">
            </a>
            <figcaption>The filled-in/resynthesized image</figcaption>
            </figure>
<p>That result looks great, but it wasn’t actually seamlessly tileable. Fortunately there is another filter, <code>Filters &gt; Map &gt; Tile Seamless</code>, that handles that:</p>
<p><figure>
            <a href="/assets/uploads/fugue/tiling/bush_tile.jpg" title="">
            <img src="/assets/uploads/fugue/tiling/bush_tile.jpg" title="">
            </a>
            <figcaption>The seamless tiling image</figcaption>
            </figure>
<p>It looks really good tiled:</p>
<p><figure>
            <a href="/assets/uploads/fugue/tiling/bush_seamless.jpg" title="">
            <img src="/assets/uploads/fugue/tiling/bush_seamless.jpg" title="">
            </a>
            <figcaption>The seamless tile in use (2x2)</figcaption>
            </figure>
<p>This texture has a lot going on so it may be an easier example. If you look closely at the seamless tile version you can see some ghost leaves overlapping other leaves, which might be more noticeable in a sparser texture.</p>
<p>It’s more apparent in these textures:</p>
<p><figure>
            <a href="/assets/uploads/fugue/tiling/cobblestone_tiled_sm.jpg" title="">
            <img src="/assets/uploads/fugue/tiling/cobblestone_tiled_sm.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/tiling/bricks_tiled_sm.jpg" title="">
            <img src="/assets/uploads/fugue/tiling/bricks_tiled_sm.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>You can see some mushiness/blurriness/choppiness in the patterns from the overlapping areas. It’s not terrible, especially for textures you won’t look closely at and in the context of the game’s downsampled resolution. Again, part of the game’s aesthetic is about giving a big margin of error for quick-and-dirty assets, whether through low poly modeling or iffy automated tools.</p>
<p>When I have more time I want to see about integrating this directly into the <a href="/projects/fugue/14/">Texture Editor</a> from the last post; it would be nice to not have to open up GIMP every time to process images this way.</p>
<p>As a side note, it’s been awhile since I’ve used GIMP and I’m impressed by this latest version! Feels like it had a big glow up like Blender did.</p>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
<p>“Exorcisms”, sort of line with how <a href="https://www.tandfonline.com/doi/full/10.1080/15426432.2014.873648">they work in Buddhism</a>, though I don’t know that I will call them that in-game.</p>
</div>
]]></content:encoded></item><item><title>&lt;em&gt;Half-Earth Socialism&lt;/em&gt; (The Game)</title><link>projects/half_earth_socialism</link><description><![CDATA[For the past year I worked on Half-Earth Socialism, an online game accompanying the book of the same name by Drew Pendergrass and Troy Vett…]]></description><category>projects</category><pubDate>Tue, 07 Jun 2022 17:26:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p><figure>
            <a href="/assets/uploads/half_earth/intro.jpg" title="">
            <img src="/assets/uploads/half_earth/intro.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>For the past year I worked on <a href="https://play.half.earth/"><em>Half-Earth Socialism</em></a>, an online game accompanying <a href="https://www.versobooks.com/books/3818-half-earth-socialism">the book of the same name</a> by Drew Pendergrass and Troy Vettese (Verso 2022). The game launched at the beginning of May; you can <a href="https://play.half.earth/">play it here</a>. This post will make more sense after you’ve played the game!</p>
<p>This post is adapted from a talk I gave at <a href="https://trust.support/">Trust</a> (who organized the project) and goes a bit into the design and development process of the game.</p>
<h2>Genesis</h2>
<p>Trust was approached early in 2021 about developing a website to accompany the forthcoming book <em>Half-Earth Socialism</em>, which would be published a little more than a year later. To very, very briefly summarize the book (the book itself is a quick read so I encourage you to give it a look!): the authors focus on land use as the central variable of concern for the health of the planet (hence the name “Half-Earth” socialism, building off of <a href="https://en.wikipedia.org/wiki/Half-Earth">E.O. Wilson’s idea of the same name</a>) and emphasize the need for rational democratic planning to make decisions around the future of the world. For example: how much land should be devoted to energy production, and how much to food?</p>
<p>Democratic planning requires some way for people to meaningfully engage with plans: to understand them, evaluate them, and make their own plans. The original proposal for the site was based around a linear programming calculator where people could play with the parameters of a model that Drew wrote. I imagined it as something akin to Chris Crawford’s <a href="https://www.youtube.com/watch?v=CnRJE-7ZC3I"><em>Balance of the Planet</em></a> (1990), where the player is similarly adjusting parameters of a global model to influence planetary health.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/drews_model.jpg" title="">
            <img src="/assets/uploads/half_earth/drews_model.jpg" title="">
            </a>
            <figcaption>Drew’s model and a screenshot of Chris Crawford’s </figcaption>
            </figure></em> (1990)</p>
<p>In this original version you could choose your energy mix, energy use levels, meat consumption, and so on. The model would figure out the allocation of land, emissions, and so on that were required. Using this model you can easily compare results and see, for example, that veganism opens up quite a lot of land for energy production. But part of the book’s appeal is the vignettes throughout that imagine what life might be like under Half-Earth socialism or what it might be like were it not to happen. We wanted to take this model and build a richer, more narrative experience around it to reflect some of the feeling those vignettes evoked: the pacing of such a world, people’s concerns and values, and the social fabric of their lives.</p>
<h2>Reading Group</h2>
<p><figure>
            <a href="/assets/uploads/half_earth/reading_group.jpg" title="">
            <img src="/assets/uploads/half_earth/reading_group.jpg" title="">
            </a>
            <figcaption>A sample of the reading group</figcaption>
            </figure>
<p>Before any development began we first participated in a reading group, organized by Chiara Di Leone, covering topics like: socialist cybernetics, cybernetic planning, complex systems management interface design, climate modeling, and games that we found interesting or related to the these topics. These helped us coalesce on a set of mechanics, design elements, constraints, and feelings to develop the game around.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/frostpunk.jpg" title="">
            <img src="/assets/uploads/half_earth/frostpunk.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure></em>, 11 Bit Studios</p>
<p>Two games that we looked closely at were 11 Bit Studio’s <a href="https://www.frostpunkgame.com/"><em>Frostpunk</em></a> and Nerial’s <a href="https://reignsgame.com/"><em>Reigns</em></a>. <em>Frostpunk</em>’s gameplay is centered around one primary variable (heat) and is filled with many brutal, no-win policy decisions around managing morale. The game is really well organized around its primary variable–it’s very easy to see how heat is distributed, what’s producing it, how it decays, and so on, so even though the decisions can be difficult, you’re seldom disoriented or confused about what your priorities are. The game is, however, very dark and depressing. In contrast to <em>Half-Earth Socialism</em>’s more utopian outlook, <em>Frostpunk</em> is a never-ending crisis. We knew that we wanted our game’s arc to be different: the beginning is a difficult struggle to get through, but if you do well the game opens up into a world better than the pre-crisis past. There’s light on the other side!</p>
<p><figure>
            <a href="/assets/uploads/half_earth/reigns.gif" title="">
            <img src="/assets/uploads/half_earth/reigns.gif" title="">
            </a>
            <figcaption></figcaption>
            </figure></em>, Nerial</p>
<p>We knew early on that we wanted the game to be a web game, keeping in line with the original website idea and making sure that it’s easy to access. If you’re making a web game then you really need to consider mobile usage. We expected that most people would share the game on Twitter and thus others would likely encounter it on their phones and want to give it a try right there. That assumption’s held: the majority of plays so far have been on mobile resolutions. <em>Reigns</em> was a main inspiration of how you could make a simple yet deeply engaging game for mobile. It has one main interaction–swiping left or right–but it’s enough to support a great branching narrative. It’s also very flexible in terms of time commitment: you can play a session for a few minutes or an hour if you want. That’s something we wanted to replicate in our game–players could finish a run in 5 to 10 minutes, do something else, and come back and try a different approach later. That isn’t how things turned out (people have spent 30 minutes just reading the starting cards) and in the end the scope of our game was just too complex to really reproduce these elements of <em>Reigns</em>.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/build_triad.png" title="">
            <img src="/assets/uploads/half_earth/build_triad.png" title="">
            </a>
            <figcaption>Three key builds</figcaption>
            </figure>
<p>From the whole reading group process came a few orienting values:</p>
<ul>
<li><em>Accuracy</em>: Most games prioritize a fun and engaging experience, and often systems that have real-world correlates are simplified in service of this priority. But because of the nature of the book and the weight of the subject, we wanted to prioritize rigor and accuracy a bit more than a typical game would. This was a huge challenge because representing something as complicated as the planet and human economic activity requires a great deal of simplification regardless of commitment to accuracy, and with the complexity of the planet and the global economy, details matter a lot. And often details that don’t seem to matter end up becoming quite important later on.</li>
<li><em>Amusing</em>: Climate change and ecological disaster are already very weighty topics without us needing to exaggerate it. We wanted to bring some levity to the game so that the player doesn’t feel pummeled by depressing thing after depressing thing (although it does kind of happen because of the subject matter). So using dialogue, character design, etc, as outlets to lower the “seriousness” of the game and leave plenty of space for the content to do that.</li>
<li><em>Expressive</em>: Another goal was for the game to play like a political compass quiz, in a way. We had a few player “builds” (above) in mind that made play feel expressive.</li>
<li><em>Quick</em>: Shorter games that you play in rapid succession, to try different things. I think originally we wanted a session to be 5-10min…but sessions last far longer now. It takes at least 5 minutes just to soak in the game’s starting content!</li>
</ul>
<p>As mentioned above, take a cue from the book and convey the feeling of living under HES through dialogue and other narrative elements.</p>
<p>Development proceeded in roughly five categories:</p>
<ul>
<li><em>Story</em>: the main beats of the game and game dialogue.</li>
<li><em>Art Direction</em>: character design, graphics, game feel, and so on.</li>
<li><em>Game Design</em>: the game’s primary mechanics and interactions.</li>
<li><em>Legibility</em>: the game’s information design, how players access/read the information they need to make decisions and how they make those decisions.</li>
<li><em>Technical Requirements</em>: various constraints around the game’s technical infrastructure and architecture</li>
</ul>
<h2>Story</h2>
<p><figure>
            <a href="/assets/uploads/half_earth/events.jpg" title="">
            <img src="/assets/uploads/half_earth/events.jpg" title="">
            </a>
            <figcaption>A story event</figcaption>
            </figure>
<p>We wanted to give the game world a richer feel through events, which give us opportunities to world-build and develop character personalities. They’re also one main way players get feedback about their plans. More importantly they allow us to represent way more than we could with the core game model alone, which focuses on a relatively limited set of variables (water usage, land usage, electricity production, fuel production, etc). With a very simple probability system we can represent a much wider range of events like mass coral bleaching events or cultural changes like a new cuisine trend of eating invasive jellyfish, without needing to make the model itself much more complex.</p>
<p>Of course, the events we have in the game pale in comparison to all the possible events one might think of for the future. They allow us to represent more detail than we could otherwise but open up an overwhelming amount of things we could represent. It’s one of those areas where we had to just stop adding things at some point, even though we probably could have added hundreds more.</p>
<h2>Technical Requirements</h2>
<p>Mobile and web support were the primary technical constraints, and those came with their usual challenges (mostly cross-browser compatibility). The more interesting technical requirements were related to the models and data that we needed.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/hector.png" title="">
            <img src="/assets/uploads/half_earth/hector.png" title="">
            </a>
            <figcaption>Hartin, C. A., Patel, P., Schwarber, A., Link, R. P., and Bond-Lamberty, B. P.: A simple object-oriented and open-source model for scientific and policy analyses of the global climate system – Hector v1.0, Geosci. Model Dev., 8, 939-955, doi:10.5194/gmd-8-939-2015, 2015.</figcaption>
            </figure>
<p>Early on we knew we wanted to have some kind of climate model running, but climate models are usually huge, requiring supercomputers long periods to run. Drew suggested <a href="https://github.com/JGCRI/hector">Hector</a>, which is a “simple climate model”. It runs quickly on commodity hardware, but of course lacks the depth and detail of its massive counterparts. From a technical standpoint I didn’t really want to have a server crunching a climate model for several players at once, even if it’s a relatively simple one. We managed to get it <a href="https://github.com/frnsys/hector-wasm">to run directly in the browser</a> so that each player runs their own model independently.</p>
<p>We have some other models running too:</p>
<ul>
<li>a biome model, not running on mobile but on desktop, which colors the world according to temperature and precipitation changes over time.</li>
<li>a linear programming model for determining production resource allocation and guided assistance in planning. This ended up being reduced to a much simpler form because there weren’t models available for the browser that handled the kind of optimization we needed.</li>
</ul>
<p><figure>
            <a href="/assets/uploads/half_earth/process_data.jpg" title="">
            <img src="/assets/uploads/half_earth/process_data.jpg" title="">
            </a>
            <figcaption>Process data example</figcaption>
            </figure>
<p>The other major set of requirements were data requirements. For processes there were input requirements per unit output, impacts (e.g. CO2 emissions) per unit output, and current global process mixes. We also needed current emissions, current biodiversity loss, population projections aggregated for each region, global per-capita demand for each of our outputs, estimate per-capita impacts based on regional income levels, and impacts and inputs for different sectors/industries.</p>
<p>It’s often very difficult to track down good numbers for these. Data may be available at regional or national levels, but not globally. Or there may be a lot of variability in estimates. Some technologies like vertical farming and cellular agriculture are very new, so there are only estimates for very limited cases, if at all. For example with vertical farming we could only find a couple sources that on a one or two crops published by vertical farming startups (so very unclear how trustworthy the numbers are), and instead relied more on values from more general indoor greenhouse farming.</p>
<h2>Art Direction</h2>
<p><figure>
            <a href="/assets/uploads/half_earth/character_design.png" title="">
            <img src="/assets/uploads/half_earth/character_design.png" title="">
            </a>
            <figcaption>Character design</figcaption>
            </figure>
<p>The game’s art direction is mostly <a href="https://www.son-la.co/">Son La</a>’s department but I’ll briefly mention my two main contributions.</p>
<p>The first is the globe’s design, which took an embarrassingly long time (I’m really inexperienced with shaders). Our main aesthetic reference was a sort of retro-computing, so we played a lot with poorer color representation (dithering) and lower resolutions (pixelation).</p>
<p><figure>
            <a href="/assets/uploads/half_earth/globes.jpg" title="">
            <img src="/assets/uploads/half_earth/globes.jpg" title="">
            </a>
            <figcaption>Some early globe attempts</figcaption>
            </figure>
<p>The final version drew from this graphic that was produced for an article about the book:</p>
<p><figure>
            <a href="/assets/uploads/half_earth/half_earth_illustration.jpg" title="">
            <img src="/assets/uploads/half_earth/half_earth_illustration.jpg" title="">
            </a>
            <figcaption>Illustration by Lukas Eigler-Harding and Ariel Noltimier-Strauss</figcaption>
            </figure>
<p>And here’s the final version:</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/half_earth/globe.mp4" title="" />
            <figcaption>The final globe design</figcaption>
            </figure></p>
<p>One major element of the game’s feel was the imagery we used to represent projects, processes, and events. We had a very small team, and it was really only Son La creating visual content (and also working on the UI development). We ended up with 238 events, 123 projects, 29 processes, 9 industries, and 20 regions, all of which needed images, so ~420 images total. There was no way we could create all of that on our own, so we looked at CC-licensed and public domain imagery. The problem with sourcing images that way is that they vary a lot in quality and style, and they kind of just look like digital photos. We played around with ways to process them so that they were more interesting and consistent and ended up with the following line:</p>
<p><figure>
            <a href="/assets/uploads/half_earth/forest_dither_overlay.jpg" title="">
            <img src="/assets/uploads/half_earth/forest_dither_overlay.jpg" title="">
            </a>
            <figcaption>Image processing</figcaption>
            </figure>
<h2>Legibility</h2>
<p><figure>
            <a href="/assets/uploads/half_earth/emissions_factors.jpg" title="">
            <img src="/assets/uploads/half_earth/emissions_factors.jpg" title="">
            </a>
            <figcaption>An example of a factors card</figcaption>
            </figure>
<p>There is a lot to consider when assembling your plan and so a major challenge was making information available and clear to the player. All throughout the interface are tooltips and “factors” cards that breakdown what’s contributing to whatever variable you clicked on. The hope is that whatever info you need to make a decision is available quickly, but it still is and feels like a lot of information!</p>
<h2>Game Design</h2>
<p><figure>
            <a href="/assets/uploads/half_earth/flow_sketch.jpg" title="">
            <img src="/assets/uploads/half_earth/flow_sketch.jpg" title="">
            </a>
            <figcaption>An earlier sketch of the gameplay flow</figcaption>
            </figure>
<p>The most challenging part of the project was the game design. There were a lot of different things we wanted to communicate, different feelings we wanted to evoke, and so that led us down a few different design paths. But the biggest difficult was that the game is meant to somewhat accurately represent a set of very complex systems–we wanted some legitimacy and rhetorical weight behind what happens in the game. This commitment to accuracy of complexity is directly at odds with making an entertaining and accessible game. Most games are not complex in terms of their mechanics. Even games that are very deep do not have to be complex, and they often aren’t. Truly complex systems make for unfun games because they in their very nature inscrutable, so they become a very frustrating experience. You never quite know why something is happening: is it because of something you did, is it because of something you didn’t do, or did it have nothing to do with you at all? Part of what makes a game fun is learning its rules and systems, and one reasonably expects consistency, predictability, and legibility in how the game responds to your actions. Complex systems don’t care.</p>
<p>Balancing was also very difficult to do with such a complex game. We couldn’t anticipate all the paths or strategies a player might try. Ultimately we hoped to avoid players finding a strategy that works in the game that wouldn’t work in the real world because of some detail we left unmodeled, but it would require a lot more testing to have some assurance that we succeeded.</p>
<p>I’ll briefly describe two sets of ideas we had that I really liked but got cut for one reason or another.</p>
<h3>Regional System</h3>
<p><figure>
            <a href="/assets/uploads/half_earth/region_sketch_composite.jpg" title="">
            <img src="/assets/uploads/half_earth/region_sketch_composite.jpg" title="">
            </a>
            <figcaption>Some sketches of the regional system</figcaption>
            </figure>
<p>I remember “space” being a big concern. Given the book’s focus on land use, how we deal with space is really important. But it came in conflict with priorities like accuracy. Games might abstract space to make it more manageable, like using larger units of space which then reduces the level of detail you can represent spatially; or they might limit their focus e.g. to a single region or map or level. The earth is really big. We can’t really represent it in great detail without just blasting the player with stuff to manage. So we could limit the player’s focus at a given time to a single region. That’s basically where this design came from.</p>
<p>One bonus was the opportunity for more visual feedback/eye candy: you could zoom into a region and see wildlife return, to make your impacts on the world feel rewarding and more obvious.</p>
<p>But there was a more important game design element to this regional system. We wanted to avoid was the “god view” in games, where the player unilaterally makes decisions of all kinds, which is contra the democratic planning that’s emphasized in the book. It’s very challenging to design a game about global planning without making it a god game! Games are often fantasies of control…representing democracy in a game very difficult because it can disrupt that fantasy and make the game a frustrating experience. It’s interesting how certain kinds of friction are expected in a game, like a hard boss fight being difficult, but others, like having your decisions questioned or ignored, are not.</p>
<p>I don’t think we succeeded in avoiding the god view. The parliamentary system is supposed to represent that to some degree, and you can be ousted from power if you’re too unpopular. But that’s not quite the same as democratic planning. One iteration of this regional system idea had a greater and more autonomous role for individual regions (in the current game they mostly just exist to spatialize the game a bit, but they don’t really do much on their own). The player would set targets and maybe some specific policies/projects but regions would go and figure out how to achieve those targets on their own. There would be more bargaining with regions to accept targets or to achieve them in a particular way.</p>
<p>A further iteration on this idea–which was definitely out of reach given our constraints–was a multiplayer regional system. Different people play different regions, and perhaps elect one player to be a global planner for a term. The global planner mediates regional relationships: regions have to negotiate with one another, like if I’m representing East Asia I want North America to reduce their energy usage in exchange for reducing my coal usage or something.</p>
<h3>Turn-based System</h3>
<p><figure>
            <a href="/assets/uploads/half_earth/into_the_breach.jpg" title="">
            <img src="/assets/uploads/half_earth/into_the_breach.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure></em>, Subset Games</p>
<p>The other major concept was a turn-based game, similar to <em>Into the Breach</em>. Each turn is some fixed time amount, and you have a preview of everything that will happen in the next turn or next <code>n</code> turns. For example: this natural gas plant will emit this much methane next turn, this patch of permafrost has 50% chance of melting by next turn, this hurricane will move left 2 tiles next turn, etc. It doesn’t really work for the global scale, since you can’t deal with things like an individual power plant, but I still think you could make a fun and interesting game this way if you could get away with more simplifications. And it’s not clear what amount of time a turn should represent. The hurricane movement, for example, requires a much shorter turn time, but other decisions like building new power plants are better suited to turns of a year or more. Similarly, it’s not clear what the spatial resolution should be. How many hexagons should the globe be divided into? A hurricane and a power plant are on two different scales.</p>
<p>One advantage of this design was that scientific uncertainty can more easily be a bigger part of the game. That natural gas plant <em>might</em> emit this much methane, but you don’t really know without better sensors. That 50% estimate for that patch of permafrost is based on your best climate models, but if you invest in improving them and training more climate scientists you’d have a better estimate. In this way the benefits of good long-term planning manifest as “powerups” in a sense that make the shorter game loop easier.</p>
<h3>Card System</h3>
<p>We ended up settling on a card-based system. It felt more familiar and easier conceptually, giving players something to hold on to while we barraged them with other new information to absorb. Cards also provide a convenient way to compartmentalize “abilities” and a give players a discrete object to think with. Basically all player actions are expressed through manipulating cards in some way.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/policy_slots.jpg" title="">
            <img src="/assets/uploads/half_earth/policy_slots.jpg" title="">
            </a>
            <figcaption>Diablo equipment slots and Civilization 6 policy slots</figcaption>
            </figure>
<p>There are still a lot of ways to use cards. One idea was to have your plan be something like equipment slots in an RPG, like Diablo (on the left here). But instead of a head slot for your helmet you’d have a concrete slot for your concrete production technology, and another one for your transport policy, and so on.</p>
<p>This is kind of how it works in Civilization 6 (on the right). This form ended up being too limiting because there are many projects we wanted to include that don’t fit neatly into an existing slot, thus requiring many single-purpose slots, and just making the whole thing clunky and confusing.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/card_wireframes.png" title="">
            <img src="/assets/uploads/half_earth/card_wireframes.png" title="">
            </a>
            <figcaption>Card wireframes</figcaption>
            </figure>
<p>Above are a couple other ideas—on the left we have something based around a deck. One idea was that your “plan” is a deck of cards that you assemble and use to react to events, under the idea that a good plan prepares you for the future. So if your scientists are telling you a major heatwave is likely, you’d have a mass cooling center policy prepared to respond to that heatwave, if it does happen.</p>
<p>This ended up not really working because it feels like busywork for the player—you’re making two redundant decisions, the decision to establish the cooling centers, and the decision to use them when the heatwaves occurs. In trying to minimize extra actions, we’d assume that if you have the cooling centers in place, you’d want to use them.</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/half_earth/card_prototype2.sm.mp4" title="" />
            <figcaption>Card prototypes</figcaption>
            </figure></p>
<p>Above is one of our prototypes for card interactions. This one is a Reigns-like interface, with four directions instead of two. We ditched it because as I mentioned the Reigns reactive playstyle didn’t quite fit what we needed.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/card_interaction.opt.gif" title="">
            <img src="/assets/uploads/half_earth/card_interaction.opt.gif" title="">
            </a>
            <figcaption>Card scanning interaction</figcaption>
            </figure>
<p>We settled on this “scanning” interaction, which has a retro computing punchcard-like vibe. Conceptually this is like the deck idea without the redundancy: in a way you’re scanning cards to add them to your deck (plan) so they make bad future events less likely.</p>
<p><figure>
            <a href="/assets/uploads/half_earth/parliament_with_card.jpg" title="">
            <img src="/assets/uploads/half_earth/parliament_with_card.jpg" title="">
            </a>
            <figcaption>Parliament</figcaption>
            </figure>
<p>We also wanted to add a political aspect to the game, in part to make gameplay more interesting (the player can’t just do everything they want to do–to lessen the “god view” problem) and also add some drama and an opportunity to develop the world through some strong personalities. They also give players some scaffolding to develop playstyles. There’s more clear guidance on what an accelerationist might want, for example, to nudge the player towards using those cards. The parliament system was also conceived to bring some of the “democratic” side of “democratic planning”, but I don’t think we succeeded in that. It’s my main regret of the game. I feel that we would have needed to design the game very differently for that to have worked, and at that point it was too late to make such major changes.</p>
<h2>Tooling</h2>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/half_earth/editor_demo.sm.mp4" title="" />
            <figcaption>The editor</figcaption>
            </figure></p>
<p>One last thing I want to show off is the Half-Earth editor, where all the content (dialogue, events, regions, projects, processes, and so on) and model parameters are written. Whenever I embark on a project like this, one of the first things I do (once the main architecture/schemas are sorted out) is build content authoring tools. It makes later work much quicker, makes it easier to experiment with the content, helps me think through more ideas and possible conflicts in that level of the design, and makes it much easier to bring on others (like writers/researchers Lucy Chinen and Spencer Roberts) to contribute without needing to muck about in the code.</p>
<h2>Final note</h2>
<p><em>Half-Earth Socialism</em> was one of the bigger projects I’ve worked on, and I’m proud of what we accomplished with such a small team. Our ultimate ambition was way beyond our capacity and resources, but we managed to achieve quite a lot of it. The game was made possible because of these people:</p>
<p><figure>
            <a href="/assets/uploads/half_earth/credits.jpg" title="">
            <img src="/assets/uploads/half_earth/credits.jpg" title="">
            </a>
            <figcaption>The people behind </figcaption>
            </figure></em>.</p>
]]></content:encoded></item><item><title>&lt;em&gt;Fugue&lt;/em&gt; Devlog 14: Authoring Tools</title><link>projects/fugue/14</link><description><![CDATA[Wow, it’s been almost a year since I last updated this blog.
I haven’t had time to work on Fugue until a month or so ago. Since then I’ve b…]]></description><category>projects/fugue</category><pubDate>Sun, 05 Jun 2022 18:47:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p>Wow, it’s been almost a year since I last updated this blog.</p>
<p>I haven’t had time to work on <em>Fugue</em> until a month or so ago. Since then I’ve been chipping away at more tooling. Once the core game mechanics/systems are in place, I’m expecting that most of the time will be spent creating content for the game: writing, modeling, environment design, etc. So I’m building out tooling and figuring out strategies to streamline all of these processes.</p>
<p>Godot makes it easy to develop editor plugins that integrate relatively seamlessly. It’s not without its challenges and frustrations but those are more to do with Godot in general than specifically about their plugin development process (see below).</p>
<h2>Writing</h2>
<p>The game will play out mostly through characters saying and doing things, and these actions need to be specified in a way where I don’t need to meticulously program each one. Previously the game’s narrative elements used “Dialogue” as the main organizing element, focusing on spoken dialogue, and let me write “scripts” of spoken dialogue lines with a playback system to have the appropriate characters say their lines in order. That ended up being too limiting because I want to write not only dialogue but to specify various actions/stage directions to write scripts that basically describe entire scenes, including character movement and animation, sound and environmental cues, and so on. So I restructured that whole system around “Sequence” as the main organizing element, with “Dialogue” as a sub-component.</p>
<p>A Sequence is composed of “Actions”, which include dialogue lines, choice prompts, animation triggers, game variable setting, character movement and rotation, etc. At the time of writing the following actions are available:</p>
<ul>
<li><code>Line</code> (<code>L</code>): A line of dialogue, spoken by a single Actor.</li>
<li><code>Decision</code> (<code>%</code>): A set of choices that the player must choose from.</li>
<li><code>VoiceOver</code> (<code>V</code>): A line of voice-over dialogue. The difference between this and <code>Line</code> is that it does not require the speaking actor to be present and shows in a fixed position on screen.</li>
<li><code>Prompt</code> (<code>?</code>): Basically a combination of <code>Line</code> and <code>Decision</code>. A line of dialogue is displayed with the decision’s choices.</li>
<li><code>Pause</code> (<code>#</code>): A blocking pause in the sequence</li>
<li><code>SetVar</code> (<code>=</code>): Set a state variable to the specified value (strings only). There are a number of targets
<ul>
<li><code>Global</code>: Set it on the global state</li>
<li><code>Sequence</code>: Set it on the local state (local to the current sequence). These values persist through multiple executions of the same sequence (i.e. they aren’t reset whenever the sequence is run again).</li>
<li>An <code>Actor</code>: Set it on the local state (local to a specific actor).</li>
</ul>
</li>
<li><code>PlayAnimation</code> (<code>&gt;</code>): Play an animation with the specified for the specified Actor</li>
<li><code>MoveTo</code> (<code>-&gt;</code>): Move the Actor to the specified target
<ul>
<li>You can use this to “bounce” the player character if they enter somewhere they aren’t supposed to.</li>
</ul>
</li>
<li><code>LookAt</code> (<code>@</code>): Have the Actor look at the specified target</li>
<li><code>ToggleNode</code> (<code>N</code>): Toggle the visibility of the specified node. Can fade it in/out (but looks quite janky)</li>
<li><code>RepositionNode</code> (<code>&gt;N</code>): Move a node to the position and rotation of the specified target. This happens instantaneously…so you could use it for teleportation; but more likely you’d use it to rearrange a scene while it’s faded out.</li>
<li><code>TogglePortal</code> (<code>P</code>): Enable/disable the specified portal.</li>
<li><code>AddItem</code> (<code>+</code>): Add an item to the player’s inventory</li>
<li><code>PlaySound</code> (<code>))</code>): Play a sound</li>
<li><code>Parable</code> (<code>~</code>): Start or end a Parable (Quest)</li>
<li><code>Fade</code> (<code>F</code>): Complete fade the scene in or out</li>
<li><code>ChangeScene</code> (<code>&gt;S</code>): Change the scene. Because sequences are associated with one scene, this will end the sequence!</li>
</ul>
<p>Sequences may be triggered in one of three ways: the player interacting with an object (such as talking to an NPC), the player entering a zone/area, or they automatically start when a scene loads (“ambient” sequences).</p>
<p>A “Sequence Script” is a graph of two types of nodes: “Verses”, which are lists of actions, and “Forks”, which include one or more “Branches” that each have a set of conditions. If a branch’s conditions are true then its child verses are executed.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/sequence_editor.png" title="">
            <img src="/assets/uploads/fugue/tools/sequence_editor.png" title="">
            </a>
            <figcaption>Sequence Editor</figcaption>
            </figure>
<p>Sequences are associated with only one scene. Generally multiple sequences will be related in some way: the might be part of the same narrative arc, for example. So Sequences can be further organized into “Stories” which is basically just a grouping of Sequences, without any significant additional functionality.</p>
<p>The Sequence and Story Editors both make it very easy to quickly sketch out scripts and later refine them. They both have built-in validators to ensure that scripts are correctly specified, i.e. they don’t refer to any objects that aren’t in the scene, aren’t missing any required data, etc.</p>
<p>Sequences and Stories are just stored as relatively simple JSON so they can be further processed/analyzed outside of Godot easily.</p>
<p>I expect that as the game’s writing and development continues more actions will be needed. But for now this set has been comprehensive enough.</p>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/tools/sequence_example.mp4" title="" />
            <figcaption>Example script showing different sequence actions</figcaption>
            </figure></p>
<h2>Textures</h2>
<p>Finding source images that fit my licensing requirements and then editing them into textures is a very tedious process. I built a web tool that makes it much easier to find public domain and CC source images (vastly simplified by <a href="https://wordpress.org/openverse/">Openverse</a>), cut out clippings from them and pack those clippings into textures or generate seamless textures by wrapping and blending their edges. It tracks where the clips were sourced from so that attribution is much easier to manage.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/texture_editor__search.png" title="">
            <img src="/assets/uploads/fugue/tools/texture_editor__search.png" title="">
            </a>
            <figcaption>Texture Editor: Search</figcaption>
            </figure>
<p><figure>
            <a href="/assets/uploads/fugue/tools/texture_editor__clipping.png" title="">
            <img src="/assets/uploads/fugue/tools/texture_editor__clipping.png" title="">
            </a>
            <figcaption>Texture Editor: Clipping</figcaption>
            </figure>
<p><figure>
            <video autoplay loop muted src="/assets/uploads/fugue/tools/texture_editor__workflow.mp4" title="" />
            <figcaption>Texture Editor workflow</figcaption>
            </figure></p>
<h2>Music</h2>
<p>I’m not at the point where I’ve given a ton of thought to the game’s music, but I do have one tool, <a href="https://github.com/frnsys/dust"><code>dust</code></a>, that I developed to help sketch out musical ideas. I didn’t develop it specifically for this game but it’ll be useful here too. It’s a chord progression generator/jammer that outputs MIDI so it can be used as an input to most DAWs (tested with Bitwig Studio and Live 11). It helps to get around blank-canvas-syndrome by giving you a chord base to start working with.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/dust.png" title="">
            <img src="/assets/uploads/fugue/tools/dust.png" title="">
            </a>
            <figcaption></figcaption>
            </figure></p>
<h2>Miscellaneous</h2>
<h3>Items</h3>
<p>I’ve started working on the item system, which is very simple at the moment (and hopefully will stay that way). To manage the items I created an Item Editor, which, though a lot simpler than the Sequence Editor, is just as useful.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/item_editor.png" title="">
            <img src="/assets/uploads/fugue/tools/item_editor.png" title="">
            </a>
            <figcaption>Item Editor</figcaption>
            </figure>
<h3>Blender scripts and templates</h3>
<p>Blender’s also been nice to work with because of its support for Python scripts. It’s a little clunky to get things integrated, but can be powerful once you’re going. In my case I’m mostly using a “quick export” script that helps me avoid the tedious work of keeping exported files organized (navigating to the correct folder, setting the filename, etc) and double-checking my export settings are correct. In the case of items, which require a static icon to show in the UI, the export script automatically exports a properly-cropped render of the item to the item icons folder so I don’t have to bother with that at all.</p>
<p>Another small but immensely helpful thing is having a specific template for <em>Fugue</em> modeling work, with materials, cameras, and what not preconfigured. My material settings change very infrequently; I’m usually just swapping out textures, so this saves me a lot of time configuring materials over and over again.</p>
<h3>Dialogue Layout System</h3>
<p>Not really a tool, but something I’ve been refining for awhile now. This is the system that determines where dialogue boxes are placed on screen. Many games have a fixed dialogue box, e.g. at the center bottom of the screen, but I want it to feel more spatial, especially as there won’t be any voiced lines in the game (too expensive/too much work/difficult to change and iterate on) so there won’t be any 3d audio to offer that auditory depth.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/dialogue_example.png" title="">
            <img src="/assets/uploads/fugue/tools/dialogue_example.png" title="">
            </a>
            <figcaption>Dialogue from </figcaption>
            </figure></em></p>
<p>As far as I know there is no easy or reliable way to layout rectangles in a 2d space to guarantee that there are no overlaps. Not only should there be no overlaps, but each dialogue box should be reasonably close to its “host” (the actor that’s speaking) so that it’s clear who’s speaking. I have a reasonable expectation/constraint for myself that something like five at most actors should be speaking at once and the game has a minimum viewport size to ensure there’s a reasonable amount of space. That is, I’m not expecting that overlaps will be impossible, only that they are unlikely given these constraints.</p>
<p>The approach I’m using now is using a fixed set of anchors for each object and a quadtree to detect collisions. We just try placing a box at one of an object’s anchors, and if it collides with an existing dialogue box or object, try the next anchor.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/dialogue_layout_prototype.png" title="">
            <img src="/assets/uploads/fugue/tools/dialogue_layout_prototype.png" title="">
            </a>
            <figcaption>Dialogue layout prototype</figcaption>
            </figure>
<p>As you can see from the prototype above (on-screen objects are beige, off-screen objects are grey, and dialogue boxes are black), it’s not perfect. The box <code>8</code> at the top overlaps a bit with object <code>2</code> – this is due to how dialogue boxes for off-screen objects are handled, which could be refined, but I’m treating as an acceptable edge case for now.</p>
<p>Another shortcoming is how 2d bounding boxes are calculated from 3d objects. Basically I compute the bounding rectangular prism around the object and project that to 2d space. Depending on the shape of the object that may work well or it may end up placing an anchor far-ish from the object’s mesh. You can kind of see it in the screenshot below, the “I’m on the move” dialogue box is meant to accompany the smaller NPC, but it’s kind of far away. Tighter bounding boxes might be possible but I’m worried about the overhead they’d require. Something to look more into.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/dialogue_layout_system.png" title="">
            <img src="/assets/uploads/fugue/tools/dialogue_layout_system.png" title="">
            </a>
            <figcaption>Dialogue layout system in action</figcaption>
            </figure>
<h3>Unit Testing</h3>
<p>Godot doesn’t have its own unit testing framework but there are two popular third-party options: <a href="https://github.com/MikeSchulze/gdUnit3"><code>gdUnit3</code></a> and <a href="https://github.com/bitwes/gut"><code>Gut</code></a>. They both seem fairly powerful but <code>Gut</code> felt a bit clunky and I couldn’t get <code>gdUnit3</code> to work properly (compile errors, which I chalk up to Godot’s weird stochastic-feeling nature, more on that below). I ended up writing my own very simple testing framework instead. It lacks basically all of the advanced features present in other testing frameworks (spies, mocks, etc), but for my needs it’s working great.</p>
<p><figure>
            <a href="/assets/uploads/fugue/tools/tester.png" title="">
            <img src="/assets/uploads/fugue/tools/tester.png" title="">
            </a>
            <figcaption>Tester</figcaption>
            </figure>
<h2>Things not covered here</h2>
<p>There are still a few key content areas that I don’t have a good approach for:</p>
<ul>
<li><em>Character animation</em>. This is something I’m not very good at and a huge factor in the visual quality of the game. Crunchy textures and low-poly models are a lot more forgiving than terrible animations. There are now deep learning motion capture tools that might work with a commodity web camera, but I haven’t tried them yet so I don’t know if their output is good and what the workflow is like.</li>
<li><em>Mapping textures</em>. Taking a texture and then adjusting a model’s UV map so that it doesn’t look warped is also really, really tedious. No idea how to streamline that.</li>
<li><em>Object modeling</em>. This is harder to streamline/automate because there’s so much variation. Some categories like buildings and plants could be streamlined through procedural generation via Blender’s geometry node system. Fortunately I enjoy modeling so I don’t really mind doing this, it’ll just be very time consuming. One more general possibility is to figure out a decent processing pipeline for taking free models and converting them into an polygon count that matches everything else. But finding an approach that is robust enough seems unlikely.</li>
<li><em>Character modeling</em>. To make the world feel lively I’d like to have many, many background characters and a fair amount of more important NPCs. This might be doable with some kind of procedural/parameter character variation system (i.e. creating a few key archetype models, then having a script to vary some vertices, scales, etc) alongside with a procedural texture generation system (for clothing, etc). Again, this might be doable with Blender’s geometry node system.</li>
</ul>
<h2>Thoughts on working with Godot</h2>
<p>I’ve spent a far amount of time with Godot while working on all of this. My only reference point is Unity, which was very unpleasant to work with. Everything felt so fragile. Small changes can break tons of other things, with no easy way to undo the damage. Kind of like how in Microsoft Word adding a space can mess up your whole document’s layout.</p>
<p>Godot has overall felt better than this, but it still has a similar, if reduced, fragility. I’ve felt discouraged to experiment with new ideas out of the fear that I will just break a bunch of existing code/scenes and have to manually fix everything. I’ve found that even just opening a scene file can alter its contents–not yet in a way that has caused me trouble, but it’s still very different than other programming work I’ve done, where things really only change if you change them. It’s like trying to build a house on moving ground. Version control is a bit of a safety blanket but its effectiveness depends on what changes I can revert to.</p>
<p>GDScript has been a surprisingly pleasant language. It still lacks many features I’d like like sets, first class functions, and iterators (all of which I believe are coming in Godot 4) but usually those haven’t been an issue. What has been very frustrating is how Godot parses/compiles scripts. If you have a syntax error in one file it ends up breaking a bunch of other files that depend on it (which is to be expected) but it reports these issues as obscure errors that don’t point to the originating error. I’ll be inundated with messages like <code>The class "YourClass" couldn't be fully loaded (script error or cyclic dependency).</code> (it will not point you to what this error might be) or mysterious errors like <code>Cannot get class '_'.</code> repeating several times. Then it requires a painful process of trying to figure out where the syntax error actually is by opening scripts one-by-one until I stumble upon it.</p>
<p>This is less likely to happen if you’re using Godot’s built-in script editor because you’re more likely to catch the syntax error before it causes too much trouble. However Godot’s built-in editor is really lacking, mainly because you can only have one script open at a time and if you need to edit multiple files at once it requires a very tedious process of manually jumping between files one at a time. So I use an external editor, which does have a language server integration with Godot–so it does catch syntax errors, but sometimes I don’t catch them in time, and then these dizzying cascading errors happen.</p>
<p>I’ve also noticed that sometimes there will be compile errors that are fixed by reloading the project. It feels like these happen because of an unusual (sometimes seemingly random) parse order for scripts, like classes are found as undeclared when in fact they are. I haven’t looked into it too much.</p>
<p>That all being said, Godot has been wonderful to work with overall. These frustrating experiences are infrequent, and it sounds like many of them are being addressed in Godot 4. I’ve enjoyed it way more than Unity and it’s an amazing privilege to have access to such a powerful open-source project!</p>
]]></content:encoded></item><item><title>Log: 7/16/2021</title><link>log/2021_07_16</link><description><![CDATA[This week: low-density ancient urbanism, an extraction-free Atacama Desert, AI and climate change, and Wakanda.
)
The real urban jungle: ho…]]></description><category>log</category><pubDate>Fri, 16 Jul 2021 12:00:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p><strong>This week</strong>: low-density ancient urbanism, an extraction-free Atacama Desert, AI and climate change, and Wakanda.</p>
<p><figure>
            <a href="/assets/uploads/tikal_lidar.webp" title="">
            <img src="/assets/uploads/tikal_lidar.webp" title="">
            </a>
            <figcaption>3d view of Tikal (PACUNAM/Marcello Canuto & Luke Auld-Thomas, </figcaption>
            </figure></a>)</p>
<h2><a href="https://www.theguardian.com/news/2021/jun/22/the-real-urban-jungle-how-ancient-societies-reimagined-what-cities-could-be">The real urban jungle: how ancient societies reimagined what cities could be</a>, Patrick Roberts</h2>
<p>Most cities around the world, while still considerably varied, seem to have comparable density, layout, and land-use. The ancient tropical cities of the Khmer and Classic Maya empires were more sprawled and interspersed with agricultural plots and “forest gardens”. In general they sound more integrated with the environment–perhaps easier because unlike the cities that would come later they were not yet inundated with toxic industry. Whether or not the impact of urban living shakes out to be an environmental net positive or negative is something I’ve meant to read more about but yet haven’t gotten around to. But these examples of different forms of urban life are nice to think about, even if they occurred under tremendously different circumstances.</p>
<h2><a href="http://mediafieldsjournal.org/lithium-landscapes/2021/5/21/lithium-landscapes-from-abstract-imaginaries-to-deep-time-an.html">Lithium Landscapes: From Abstract Imaginaries to Deep Time and Multi-Scalar Topologies</a>, Samir Bhowmik</h2>
<p>A reflection on the vast timescales that give rise to lithium and the earthbound terraforming (human extraction of) lithium gives rise to. I especially like this painting:</p>
<p><figure>
            <a href="/assets/uploads/lithium_fields.jpg" title="">
            <img src="/assets/uploads/lithium_fields.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure></em> by Mafalda Paiva. (Image copyrights belong to Mafalda Paiva)</p>
<blockquote>
<p>Portuguese artist Mafalda Paiva’s painting Lithium Fields, which depicts the Atacama Desert reminds us of what could have been—a paradise instead of an extractive landscape. In the artist’s vision, “the salt flats hum with a preternatural vibrancy, an effect produced by the exaggerated density of species and radically foreshortened topography.”</p>
</blockquote>
<h2><a href="https://www.forbes.com/sites/robtoews/2021/06/20/these-are-the-startups-applying-ai-to-tackle-climate-change/">These Are The Startups Applying AI To Tackle Climate Change</a>, Rob Toews</h2>
<p>I’m skeptical that AI can be applied to substantially help mitigate climate change. There are specific applications that seem to be useful, e.g. around power efficiency, the development of new materials, etc. It probably has a role to play but hard to say whether it will be much more than other technologies treated with far less fervor–this article breathlessly states: “Artificial intelligence is the most powerful tool that humanity has at its disposal in the twenty-first century.”</p>
<p>I wonder if the wide proliferation of AI that many of its proponents either foretell or actively try to engineer through their own companies/investments will net out positive or negative in terms of carbon, given the intense energy requirements to train the largest, most sophisticated models. If AI is commodified and so as <a href="https://www.technologyreview.com/2021/06/30/1026438/global-microchip-shortage-problem-m1-apple-tsmc-intel/">unnecessarily ubiquitous as microchips</a> then perhaps it’ll come out net positive emissions.</p>
<p>This list of companies claiming to use AI against climate change is interesting, especially because it reveals what it means to publications like Forbes to “tackle” climate change. Several of the companies are focused on identifying climate risks or managing climate insurance for businesses. A great deal of time is spent companies applying AI to carbon offsets, which looks more like companies bending over backwards to legitimize <a href="https://www.propublica.org/article/the-climate-solution-actually-adding-millions-of-tons-of-co2-into-the-atmosphere">a completely ineffective/actively harmful way of “addressing” climate change</a> rather than actually working to reduce their emissions. The “solution” to offsets sounds like more surveillance infrastructure.</p>
<h2>Wakanda</h2>
<p>I’m not a big fan of the MCU, but the creation of a cinematic universe opens up a lot of storytelling and character possibilities so I reluctantly follow along every so often to see what they’re doing with that capacity. I wish it were some other more interesting, less indulgently militaristic fictional universe that had the resources to do something like that. Instead we get Marvel and soon <a href="https://www.nytimes.com/2021/07/09/business/media/barbie-movie-mattel.html">the Mattel Cinematic Universe</a>.</p>
<p>Ever since I <a href="https://www.nytimes.com/2019/12/19/us/wakanda-usda.html">found Wakanda listed as a US free trade partner</a> I wondered how Wakanda might relate to other countries and how people outside perceive it. While reading <a href="https://en.wikipedia.org/wiki/Doomwar"><em>Doomwar</em></a> I came across this off-handed mention from Shuri:</p>
<p><figure>
            <a href="/assets/uploads/black_panther_debt.png" title="">
            <img src="/assets/uploads/black_panther_debt.png" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<p>I’m so curious about the terms of that loan. The first Black Panther movie wrestled a bit with Wakanda’s responsibility towards its neighboring nations or developing nations (as it used to posture as) but if I recall it never really answered that question. I haven’t watched <em>Black Panther</em> recently so forgive any misremembering, but I believe Killmonger was just defeated without any satisfying resolution to his analysis/proposals about spreading Wakanda’s wealth. IIRC he proposed distributing vibranium for uprisings across the world–even if T’Challa disagreed with violent uprisings, maybe the spreading of that wealth is worth considering. Although given what Shuri says here, maybe that’s exactly what they’re doing. But again, I wonder on what terms?</p>
<p>I wonder if in some ways the now-opened Wakanda is perceived in similar ways to how China is perceived in our world. I don’t know what it takes to qualify as a “superpower” but I imagine Wakanda checks off many of those boxes. Surely many people in the MCU pin their hopes on Wakanda to usurp the planetary hegemons…sadly, they’ll probably be disappointed.</p>
<hr />
<p><figure>
            <a href="/assets/uploads/endnotes/real.jpg" title="">
            <img src="/assets/uploads/endnotes/real.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>]]></content:encoded></item><item><title>Log: 6/05/2021</title><link>log/2021_06_05</link><description><![CDATA[This week: Comfort with contradictions, anime and Gen Z
Dialetheism and Eastern PhilosophyWe recently finished watching The Good Place, whi…]]></description><category>log</category><pubDate>Sat, 05 Jun 2021 12:00:00 +0002</pubDate><content:encoded><![CDATA[</h1>
<p><strong>This week</strong>: Comfort with contradictions, anime and Gen Z</p>
<h2>Dialetheism and Eastern Philosophy</h2>
<p>We recently finished watching <em>The Good Place</em>, which was very sweet. Overall I enjoyed it, but there was one plot hole that I was disappointed to see left unaddressed, I’ll leave it in the footnotes to avoid spoilers<sup class="footnote-reference"><a href="#1">1</a></sup>.</p>
<p>The other disappointment is the show’s heavy (maybe exclusive) reliance on Western philosophy<sup class="footnote-reference"><a href="#2">2</a></sup> I don’t really blame the show for this because it’s just <a href="https://aeon.co/essays/why-the-western-philosophical-canon-is-xenophobic-and-racist">an enormous problem in how philosophy is taught in general</a>. Something else that would have been nice to include is a reckoning with the extraordinary racism of Kant (see the previous link for some examples).</p>
<p>That’s all to say that after the show I wanted to read more on non-Western ethical systems. <a href="https://blog.apaonline.org/2018/03/09/an-interview-with-jay-garfield">This interview</a> introduced me to the idea of “paraconsistency” and I got sidetracked into reading about <a href="https://www.youtube.com/watch?v=fTzcViGm2yY">dialetheism</a>, which is the view that statements can be both true and false (in orthodox logics statements can only be one or the other; such inconsistencies “explode”, i.e. entail <em>everything</em> to be true). The simplest example is the Liar’s Paradox, which in one sentence is “this statement is false”. My understanding is that under dialetheism this statement is not a paradox and to be rejected but accepted as-is.</p>
<p>As the <a href="https://plato.stanford.edu/entries/dialetheism/">SEP entry on dialetheism</a> explains, dialetheism shows up a lot in Eastern philosophies (as well as in Western philosophy: dialectics, for example). The Daodejing and Zhuangzi are riddled with them. <a href="https://scholarworks.smith.edu/cgi/viewcontent.cgi?article=1017&amp;context=phi_facpubs">“The Way of the Dialetheist: Contradictions in Buddhism”</a> (Yasuo, Garfield, Priest) gives an overview of how dialetheism shows up in Buddhism, describe some interpretative possibilities: are they presented as literal/true, or are they used as rhetorical/pedagogical tools for insight (as in Zen)?</p>
<p>My own understanding is usually that these apparent contradictions are not actually the case–for example, a common form is to say that thing X has property Y and Z such that those simultaneously having two properties is inconsistent/impossible, which I often take to mean “thing X” refers to our <em>term</em> for X and not X itself; and that in fact that term refers to two things that are different. For example, “race is real and not real” could refer to how race is not “real” as in it is an immutable part of the universe but is still “real” as social reality–as something that feels total and inescapable in our lives.</p>
<p>But this interpretation doesn’t work in many cases. When Buddha says “the ultimate truth is that there is no ultimate truth”, that seems to be more of a straight-up contradiction.</p>
<h2><a href="https://www.wired.com/story/welcome-to-planet-egirl/">Welcome to Planet Egirl</a>, Cecilia D’Anastasio</h2>
<p>I definitely feel old given how much more I’ve been reading about subcultures through publications like Wired rather than experiencing them. But I’m struck by how much anime has influenced Gen Z and how visible/trendy it is, whereas for my generation it was an almost clandestine activity. Ariel brought up a good question: is this a popularization of Japanophilic culture or is anime being separated out? Anime production is still more or less the exclusive domain of Japan as far as I’m aware.</p>
<hr />
<p><figure>
            <a href="/assets/uploads/endnotes/children_robot.jpg" title="">
            <img src="/assets/uploads/endnotes/children_robot.jpg" title="">
            </a>
            <figcaption></figcaption>
            </figure>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label">1</sup>
<p>To get Michael to understand human ethics they have him confront his own mortality, which I take to mean that human ethics is grounded human mortality. But once you’re in the afterlife, you’re no longer mortal. So why would you still be judged according to an ethical standard that no longer applies to you?</p>
</div>
<div class="footnote-definition" id="2"><sup class="footnote-definition-label">2</sup>
<p>I hoped that the afterlife-ending gateway would actually lead them to be reincarnated; it would have been a nice gesture at non-Western conceptions of the afterlife and set a stage for introducing different ethics systems.</p>
</div>
]]></content:encoded></item></channel></rss>