<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title></title>
    <link rel="self" type="application/atom+xml" href="https://internet.place/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://internet.place"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-10-28T00:00:00+00:00</updated>
    <id>https://internet.place/atom.xml</id>
    <entry xml:lang="en">
        <title>Teddy Bear Trash Compactor</title>
        <published>2025-10-28T00:00:00+00:00</published>
        <updated>2025-10-28T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Miles Silberling-Cook
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://internet.place/content/teddy-bear-trash-compactor/"/>
        <id>https://internet.place/content/teddy-bear-trash-compactor/</id>
        
        <content type="html" xml:base="https://internet.place/content/teddy-bear-trash-compactor/">&lt;blockquote&gt;
&lt;p&gt;That&#x27;s the rule of Chekhov&#x27;s Gun: Have a gun. &lt;&#x2F;BR&gt;
Now it&#x27;s been seen, I will have to shoot someone before the end of the play...&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;If your game includes a teddy bear and a trash compactor, there&#x27;s a good chance one of your players is going to try to put that teddy bear in that trash compactor. Why? Because it’s a tiny, consequence-free act of pure nihilism. Because they want to see what will happen. Because some people just want to watch the world burn. The &lt;em&gt;why&lt;&#x2F;em&gt; isn&#x27;t actually important.&lt;&#x2F;p&gt;
&lt;p&gt;I bring up the Teddy Bear Trash Compactor scenario as an example of players making fun for themselves. These sorts of actions are interesting to me, as a game designer, because they are:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;specific choices, enacted intentionally and often methodically by the player,&lt;&#x2F;li&gt;
&lt;li&gt;the opportunity for which emerged naturally from the existing game world,&lt;&#x2F;li&gt;
&lt;li&gt;perused despite having no mechanical reward, and no expectation of acknowledgment,&lt;&#x2F;li&gt;
&lt;li&gt;which nevertheless makes the player feel something (wicked glee, shame, curiosity).&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I think games should try as hard as they can to recognize and respond to actions like these. When you put the teddy in the compactor and an NPC nearby goes &lt;em&gt;&quot;(gasp) you&#x27;re a monster&quot;&lt;&#x2F;em&gt;, it’s funny and underscores the emotional impact. I love that shit.&lt;&#x2F;p&gt;
&lt;p&gt;At this point, we could go into &lt;em&gt;Theories of Fun&lt;&#x2F;em&gt; and why interactions like these make games special, but I&#x27;m going to save that for another article. This one is about the mechanics: How do you track the state of the game in a way that allows you to respond to stuff like this?&lt;&#x2F;p&gt;
&lt;h1 id=&quot;data-organization-behavior&quot;&gt;Data Organization &amp;amp; Behavior&lt;&#x2F;h1&gt;
&lt;p&gt;Say you&#x27;re making a game: You&#x27;ve got some kind of global state, and then you&#x27;ve got a ton of &quot;Game Objects&quot; that might be bits of the map, or NPCs, or items. How should this data be organized? Well, it depends.&lt;&#x2F;p&gt;
&lt;p&gt;You have to consider how that data is likely to be used. What behavior is it going to drive? As we&#x27;ll see, different types of behavior call for different representations and organizations.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;consistency&quot;&gt;Consistency&lt;&#x2F;h2&gt;
&lt;p&gt;One very common requirement for behavior is &lt;em&gt;consistency&lt;&#x2F;em&gt;. Take physics, for example. The laws of physics, I am given to understand, are pretty much the same everywhere. If you want all your game objects to have the same physics, you generally want to have a single physics implementation. That implementation should probably periodically iterate over your game objects to read and update their physics data.&lt;&#x2F;p&gt;
&lt;p&gt;Following that line of reasoning, we can draw some conclusions about data representation. Storing all the physics data in a big uniform array is probably a good choice. By contrast, giving each game object (or perhaps &lt;em&gt;class of game object&lt;&#x2F;em&gt;) custom physics properties is probably a bad idea. If some of your objects express their inertial moment in different units, or represent their position and orientation using quaternions instead of projective matrices, achieving uniform behavior is going to be harder.&lt;&#x2F;p&gt;
&lt;p&gt;Generally, to get consistent behavior, it&#x27;s best to have consistent data stored in a consistent place. This is all pretty textbook stuff.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;specificity&quot;&gt;Specificity&lt;&#x2F;h2&gt;
&lt;p&gt;Sometimes though &lt;em&gt;specificity&lt;&#x2F;em&gt; matters more than consistency. My teddy bear trash compactor example is hyper-specific; there&#x27;s just one trash compactor and just one teddy bear, so consistency isn&#x27;t a concern at all.&lt;&#x2F;p&gt;
&lt;p&gt;In isolation, you can do whatever you want with inconsistent data. But what if you have several thousand specific state variables? What if they are all different types? At scale, even though it can be wildly inconsistent, highly specific behaviors have their own set of constraints. The main problem is ergonomics. The easier it is to store ad-hoc state, the more you will do so. So highly specific behavior requires effortless data definition and access.&lt;&#x2F;p&gt;
&lt;p&gt;In practice, there is often a trade-off between consistency and specificity. Consistent behavior affects more game objects, so you can afford to use patterns with more boilerplate, which are more complex to set up and maintain. Hyper-specific behaviors have no such luxury, since they may only apply to a single object for a brief moment. They are therefore constrained to patterns that cost next to nothing to set up and use.&lt;&#x2F;p&gt;
&lt;p&gt;Why am I talking about this? Well, over the past few months, I&#x27;ve gradually come to realize that this consistency&#x2F;specificity tradeoff underpins some of the issues I have with the ECS pattern.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;dial-e-for-entity&quot;&gt;Dial E for Entity&lt;&#x2F;h1&gt;
&lt;p&gt;You&#x27;re reading a blog about game engine design, so I assume you&#x27;ve heard of an ECS before. If not, ECS is a data-storage pattern often used in games. It&#x27;s an acronym.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;E&lt;&#x2F;strong&gt; is for Entity: A key that uniquely identifies a game object.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;C&lt;&#x2F;strong&gt; is for Component: A type that each game object may have an instance of.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;S&lt;&#x2F;strong&gt; is for System: A routine that operates on game objects with a certain set of components.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The ECS pattern is great for &lt;em&gt;consistency&lt;&#x2F;em&gt;. Every system defines behavior, and entities can opt in to behavior by adding a specific combination of components. Theoretically, an ECS also provides composition, with multiple isolated systems all working together to create complex emergent behavior across the various entities they operate on.&lt;&#x2F;p&gt;
&lt;p&gt;These benefits generally come at a cost: tracking the components attached to each entity comes with overhead, and setting up new components and systems often has some boilerplate. And, in my opinion, the typical approach to components tends to get in the way when implementing inconsistent or hyper-specific behaviors.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;naive-example&quot;&gt;Naive Example&lt;&#x2F;h2&gt;
&lt;p&gt;Let&#x27;s look at what it takes to implement Teddy Bear Trash Compactor in my ECS of choice (&lt;a href=&quot;https:&#x2F;&#x2F;bevyengine.org&quot;&gt;Bevy&lt;&#x2F;a&gt;).&lt;&#x2F;p&gt;
&lt;p&gt;To start, we&#x27;ll need some way to identify a the teddy bear and trash compactor game objects. An ECS idiom exists for this called &quot;marker components&quot; (which carry no data).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-annotation z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;Component&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-struct z-rust&quot;&gt;struct&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-struct z-rust&quot;&gt;TeddyBear&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-annotation z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;Component&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-struct z-rust&quot;&gt;struct&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-struct z-rust&quot;&gt;TrashCompactor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;We also need a place to store the actual state, which in bevy probably belongs in a &quot;resource&quot; (which are effectively just containers for global data).&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-annotation z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-struct z-rust&quot;&gt;struct&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-struct z-rust&quot;&gt;IsReadyBearInTrashCompactor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;bool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This resource will need to be initialized when the game starts (so that we can persist it&#x27;s state between saves and so on) and that means we&#x27;ll have to register it in a plugin. The game in question probably already has one, so we&#x27;ll add it to that.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-impl z-rust&quot;&gt;impl&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;Plugin &lt;span class=&quot;z-keyword z-other z-rust&quot;&gt;for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt; &lt;span class=&quot;z-entity z-name z-impl z-rust&quot;&gt;MyGame&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-rust&quot;&gt;fn&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-rust&quot;&gt;build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;self&lt;&#x2F;span&gt;, &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;app&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; App&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        app&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;init_resource&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;IsReadyBearInTrashCompactor&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now in a system we can do the actual distance check and update the state resource.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-impl z-rust&quot;&gt;impl&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-impl z-rust&quot;&gt;IsReadyBearInTrashCompactor&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-rust&quot;&gt;fn&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-rust&quot;&gt;update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;        &lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;self&lt;&#x2F;span&gt;: &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;ResMut&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;Self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;        &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;teddy_bear&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;Single&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;Transform, &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;With&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;TeddyBear&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;        &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;trash_compactor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;Single&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;Transform, &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;With&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;TrashCompactor&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; dist &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; teddy_bear&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;translation&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;distance&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;trash_compactor&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;translation&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-rust&quot;&gt;if&lt;&#x2F;span&gt; dist &lt;span class=&quot;z-keyword z-operator z-comparison z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-float z-rust&quot;&gt;1.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-float z-rust&quot;&gt;0&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;            &lt;span class=&quot;z-variable z-language z-rust&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;0&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-rust&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will also have to be schedule for execution within a plugin.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;app&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;init_resource&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;IsReadyBearInTrashCompactor&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;app&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;add_systems&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;PostUpdate&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;IsReadyBearInTrashCompactor&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Taken together you get this.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-annotation z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;Component&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-struct z-rust&quot;&gt;struct&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-struct z-rust&quot;&gt;TeddyBear&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-annotation z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;Component&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-struct z-rust&quot;&gt;struct&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-struct z-rust&quot;&gt;TrashCompactor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-annotation z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-annotation z-rust&quot;&gt;#&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;[&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-annotation z-rust&quot;&gt;derive&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;Resource&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-annotation z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;]&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-struct z-rust&quot;&gt;struct&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-struct z-rust&quot;&gt;IsReadyBearInTrashCompactor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-struct z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;bool&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-impl z-rust&quot;&gt;impl&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-entity z-name z-impl z-rust&quot;&gt;IsReadyBearInTrashCompactor&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-rust&quot;&gt;fn&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-rust&quot;&gt;update&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;        &lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;self&lt;&#x2F;span&gt;: &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;ResMut&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-type z-rust&quot;&gt;Self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;        &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;teddy_bear&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;Single&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;Transform, &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;With&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;TeddyBear&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;        &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;trash_compactor&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;Single&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;Transform, &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;With&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;TrashCompactor&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;,
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; dist &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; teddy_bear&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;translation&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;distance&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;trash_compactor&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;translation&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-control z-rust&quot;&gt;if&lt;&#x2F;span&gt; dist &lt;span class=&quot;z-keyword z-operator z-comparison z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-float z-rust&quot;&gt;1.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-float z-rust&quot;&gt;0&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;            &lt;span class=&quot;z-variable z-language z-rust&quot;&gt;self&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-integer z-decimal z-rust&quot;&gt;0&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-rust&quot;&gt;true&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-impl z-rust&quot;&gt;impl&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;Plugin &lt;span class=&quot;z-keyword z-other z-rust&quot;&gt;for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt; &lt;span class=&quot;z-entity z-name z-impl z-rust&quot;&gt;MyGame&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-rust&quot;&gt;fn&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-rust&quot;&gt;build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;self&lt;&#x2F;span&gt;, &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;app&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; App&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        app&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;init_resource&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;IsReadyBearInTrashCompactor&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        app&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;add_systems&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;PostUpdate&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-path z-rust&quot;&gt;IsReadyBearInTrashCompactor&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;update&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This is a fair amount of code for a comparatively simple feature! It also introduces a lot of types, which, if you have thousands of similar little interactions, means: slower compile times, difficulty finding relevant things, and so on. It&#x27;s just a lot of work to put on the compiler for very little benefit.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-modest-proposal&quot;&gt;A Modest Proposal&lt;&#x2F;h2&gt;
&lt;p&gt;Let me show you another way to write the same thing, from a parallel universe.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-rust&quot;&gt;fn&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-rust&quot;&gt;is_teddy_bear_in_trash_compactor&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;world&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; World&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt; &lt;span class=&quot;z-meta z-function z-return-type z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;-&amp;gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;&lt;span class=&quot;z-support z-type z-rust&quot;&gt;Result&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; teddy_bear &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; world&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;entity_named&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;teddy_bear&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;get&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;Transform&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; trash_compactor &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; world&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;entity_named&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;trash_compactor&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-path z-rust&quot;&gt;get&lt;span class=&quot;z-punctuation z-accessor z-rust&quot;&gt;::&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-generic z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-generic z-begin z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt;Transform&lt;span class=&quot;z-punctuation z-definition z-generic z-end z-rust&quot;&gt;&amp;gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;?&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-storage z-type z-rust&quot;&gt;let&lt;&#x2F;span&gt; dist &lt;span class=&quot;z-keyword z-operator z-assignment z-rust&quot;&gt;=&lt;&#x2F;span&gt; teddy_bear&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;translation&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;distance&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;trash_compactor&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;translation&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-keyword z-control z-rust&quot;&gt;if&lt;&#x2F;span&gt; dist &lt;span class=&quot;z-keyword z-operator z-comparison z-rust&quot;&gt;&amp;lt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-numeric z-float z-rust&quot;&gt;1.&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric z-float z-rust&quot;&gt;0&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        world&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;set_property&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;is_teddy_bear_in_trash_compactor&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-rust&quot;&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-support z-type z-rust&quot;&gt;Ok&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-impl z-rust&quot;&gt;impl&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;Plugin &lt;span class=&quot;z-keyword z-other z-rust&quot;&gt;for&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt; &lt;span class=&quot;z-entity z-name z-impl z-rust&quot;&gt;MyGame&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-storage z-type z-function z-rust&quot;&gt;fn&lt;&#x2F;span&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-entity z-name z-function z-rust&quot;&gt;build&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;self&lt;&#x2F;span&gt;, &lt;span class=&quot;z-variable z-parameter z-rust&quot;&gt;app&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;:&lt;&#x2F;span&gt; &lt;span class=&quot;z-keyword z-operator z-rust&quot;&gt;&amp;amp;&lt;&#x2F;span&gt;&lt;span class=&quot;z-storage z-modifier z-rust&quot;&gt;mut&lt;&#x2F;span&gt; App&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-parameters z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-parameters z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt; &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-begin z-rust&quot;&gt;{&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        app&lt;span class=&quot;z-punctuation z-accessor z-dot z-rust&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-support z-function z-rust&quot;&gt;add_systems&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;PostUpdate&lt;span class=&quot;z-punctuation z-separator z-rust&quot;&gt;,&lt;&#x2F;span&gt; is_teddy_bear_in_trash_compactor&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-terminator z-rust&quot;&gt;;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;        &lt;span class=&quot;z-keyword z-operator z-range z-rust&quot;&gt;...&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-meta z-function z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;    &lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-impl z-rust&quot;&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-block z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-block z-end z-rust&quot;&gt;}&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;I&#x27;ve just done two things here:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Replaced the static marker components with a dynamic name map.&lt;&#x2F;li&gt;
&lt;li&gt;Replaced the static state resource with a dynamic properties map.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;I think this is big improvement. Compared to the previous, this version is more self-contained. It also uses the type system less (which means potentially faster compiles) and fewer macros. Remember the scale here, with a few hundred marker components, things add up. A few hundred flags could be more than a thousand mostly pointless types, which we now have to manage, and wait to compile.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s also more flexibility here. Names could be defined entirely at runtime, if you wanted.&lt;&#x2F;p&gt;
&lt;h1 id=&quot;what-s-the-downside&quot;&gt;What&#x27;s The Downside?&lt;&#x2F;h1&gt;
&lt;p&gt;What we have sacrificed, going from the first implementation to the second? Correctness. Suppose we change it from a teddy bear to a companion cube, or from a trash compactor to an incinerator. For the first version, the compiler is able to ensure that we make the change uniformly. In the second version, it&#x27;s on us to make sure we update all references to the name correctly.&lt;&#x2F;p&gt;
&lt;p&gt;Now, I don&#x27;t think reducing compiler checking here is a huge loss. There are some things the compiler just can&#x27;t check, and you wouldn&#x27;t want to have it check:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Content.&lt;&#x2F;strong&gt; Having to define content, like dialog trees, within the Rust type system is cumbersome and annoying.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scene Editors.&lt;&#x2F;strong&gt; Since marker components are compiled into the app, they are more complex to embed in scenes. Name strings are easy for editors to work with.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Scripting.&lt;&#x2F;strong&gt; Using a simple key-value store instead of a resource makes it trivial to read and write from scripts.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Networking.&lt;&#x2F;strong&gt; If you&#x27;re writing a networked game, encoding the organization of game state dynamically rather than within the type system can allow the server to send custom state to the client.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There are just so many things you can do with dynamic patterns like these. What you lose in correctness, we make up in flexibility and interoperability.&lt;&#x2F;p&gt;
&lt;p&gt;My issue with many ECS implementations, which I alluded to earlier, is that they often do not include dynamic patterns or even discourage them. There is probably a slight selection bias among users of ECS-based engines (and especially Bevy), which draws people who like type-checking and correctness and large, consistent systems. To some extent, I think those same people tend to dislike exceptions, inconsistencies, ad-hoc behavior, and specificity. It&#x27;s fine to dislike these sorts of APIs, especially if your work doesn&#x27;t require them. But I think they are still important things for an engine to support.&lt;&#x2F;p&gt;
&lt;p&gt;Engines which discourage these patterns rob their designers of the ability to make consistency&#x2F;specificity correctness&#x2F;flexibility tradeoff decisions themselves. And focusing on static correct consistent patterns can make it more difficult to implement certain things. All the categories I listed (Content editing, Scripting, Networking) have historically been weak points for Bevy. Perhaps it is because we are simply using the wrong patterns.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;stay-tuned&quot;&gt;Stay Tuned&lt;&#x2F;h2&gt;
&lt;p&gt;Some of you may still be skeptical, and that&#x27;s fine. This post ended up being a lot of me &quot;telling&quot; and less &quot;showing&quot;. In my next post, I&#x27;m going to show a more concrete example of how all this runtime-dynamic stuff can be used to implement a pretty sweet rules-based response system (modeled off the Source Engine dialog system).&lt;&#x2F;p&gt;
&lt;p&gt;Until then, here&#x27;s an omen of things to come...&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;rust&quot; class=&quot;language-rust z-code&quot;&gt;&lt;code class=&quot;language-rust&quot; data-lang=&quot;rust&quot;&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;criterion TeddyBearInTrashCompactor &lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;is_teddy_bear_in_trash_compactor &lt;span class=&quot;z-keyword z-operator z-comparison z-rust&quot;&gt;==&lt;&#x2F;span&gt; &lt;span class=&quot;z-constant z-language z-rust&quot;&gt;true&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;rule &lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;ConceptInteract Ally NpcIdle TeddyBearInTrashCompactor&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;YouMonster&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;rule &lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;ConceptInteract Ally IsLisa NpcIdle TeddyBearInTrashCompactor&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt; &lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;NeverLikedBears&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;response YouMonster list
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;line &lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;(gasp) you monster!&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;    
&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;response NeverLikedBears list
&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-source z-rust&quot;&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;    &lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-begin z-rust&quot;&gt;(&lt;&#x2F;span&gt;line &lt;span class=&quot;z-string z-quoted z-double z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-begin z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;I never liked bears anyway.&lt;span class=&quot;z-punctuation z-definition z-string z-end z-rust&quot;&gt;&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-group z-rust&quot;&gt;&lt;span class=&quot;z-punctuation z-section z-group z-end z-rust&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I&#x27;m Giving A Talk In Boston</title>
        <published>2025-09-10T00:00:00+00:00</published>
        <updated>2025-09-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Miles Silberling-Cook
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://internet.place/content/boston-forte-talk/"/>
        <id>https://internet.place/content/boston-forte-talk/</id>
        
        <content type="html" xml:base="https://internet.place/content/boston-forte-talk/">&lt;blockquote&gt;
&lt;p&gt;You Americans, all you do is talk, and talk...&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;The Boston Rust meetup group has invited me to deliver a short talk on multi-threading games using &lt;a href=&quot;https:&#x2F;&#x2F;www.rust-lang.org&#x2F;&quot;&gt;Rust&lt;&#x2F;a&gt; and &lt;a href=&quot;https:&#x2F;&#x2F;bevy.org&#x2F;&quot;&gt;Bevy&lt;&#x2F;a&gt;. Topics will include:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;How Rust can help (and hinder) game development.&lt;&#x2F;li&gt;
&lt;li&gt;Bevy&#x27;s aggressive approach to multi-threading.&lt;&#x2F;li&gt;
&lt;li&gt;The design and implementation of a new ultra-low-latency scheduling library.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;pre class=&quot;z-code&quot;&gt;&lt;code&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Where: 285 Summer Street, Suite 101, Boston, MA.
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;When: Tuesday, September 30th. 
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;
&lt;&#x2F;span&gt;&lt;span class=&quot;z-text z-plain&quot;&gt;Doors open at 5:30 p.m. Talks start at 6:30 p.m.
&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For more information, see the &lt;a href=&quot;https:&#x2F;&#x2F;www.meetup.com&#x2F;bostonrust&#x2F;events&#x2F;310907806&#x2F;&quot;&gt;official meetup page&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you somehow (a) read this blog (b) live in the greater Boston area and (c) do not already know me, please do come and introduce yourself!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Working In Groups</title>
        <published>2025-08-30T00:00:00+00:00</published>
        <updated>2025-08-30T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Miles Silberling-Cook
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://internet.place/content/working-groups/"/>
        <id>https://internet.place/content/working-groups/</id>
        
        <content type="html" xml:base="https://internet.place/content/working-groups/">&lt;blockquote&gt;
&lt;p&gt;Wann hast du Geburtstag?&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;A little over a year ago, Bevy introduced a new &quot;Working Groups&quot; process, as part of an effort to overcome some of the issues we were having with RFCs. Cart discussed this briefly in the &lt;a href=&quot;https:&#x2F;&#x2F;bevy.org&#x2F;news&#x2F;bevys-fifth-birthday&#x2F;#1-the-year-of-free-range-organic-bevy-development&quot;&gt;5th birthday post&lt;&#x2F;a&gt;, but I&#x27;m going to go into more detail about why we made this change, the ways I think it has succeeded and failed, and what conclusions I think the maintainers of other projects might draw from our little experiment.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-problem-of-scale&quot;&gt;A Problem Of Scale&lt;&#x2F;h2&gt;
&lt;p&gt;Many successful open source projects suffer from the same problem: Massive contributor base, minimal structure. Take Bevy as an example. I believe the last time &lt;a href=&quot;https:&#x2F;&#x2F;www.charlotte.fyi&quot;&gt;Charlotte&lt;&#x2F;a&gt; counted, we had somewhere around &lt;code&gt;60&lt;&#x2F;code&gt; regular contributors (people who merged at least ten PRs per year). That&#x27;s actually pretty good for a project of Bevy&#x27;s size, but it only represents a tiny fraction of the larger contributor base. Apparently Bevy merged &lt;code&gt;9,795&lt;&#x2F;code&gt; PRs last year, from somewhere upwards of &lt;code&gt;350&lt;&#x2F;code&gt; different contributors.&lt;&#x2F;p&gt;
&lt;p&gt;Yowza! That&#x27;s a lot of engineers.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine if Bevy were a company. With that number of developers, it would certainly have multiple isolated departments run by their own vice-presidents, an army of middle-managers, maybe a sales team, and probably several project managers. But Bevy isn&#x27;t a company. It has a project lead, one full-time staff-engineer&#x2F;engineering-PM, three maintainers, and a loose unstructured confederation and &lt;code&gt;1200&lt;&#x2F;code&gt; other people&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; who are, by and large, doing their own thing.&lt;&#x2F;p&gt;
&lt;p&gt;Lack of structure isn&#x27;t inherently a bad thing. Most features and fixes are uncontroversial and can be decomposed into bite-sized tasks that a single engineer can complete more or less on their own. As long as bureaucracy and friction are kept comparatively low, it&#x27;s possible to achieve really high throughput for this sort of work. Everyone just does whatever looks most interesting, more or less on their own. It takes some light community organizing and speedy code review, but the work gets done and the project keeps trundling along.&lt;&#x2F;p&gt;
&lt;p&gt;However, not everything fits neatly into the &quot;single-developer&quot; mold. Invariably, projects appear which are too big or too controversial for a single developer to tackle. All the really important aspects of software development — standards writing, API design, and broad system architecture — inherently need some degree of collaboration and consensus-building. Work like this calls for a different set of tools.&lt;&#x2F;p&gt;
&lt;p&gt;More often than not, this boils down to some sort of RFC process.&lt;&#x2F;p&gt;
&lt;p&gt;More often than not, this is a mistake.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;everybody-gets-rfcs-wrong&quot;&gt;Everybody Gets RFCs Wrong&lt;&#x2F;h2&gt;
&lt;p&gt;Now, I love a good RFC. But I have a problem with how most people approach writing RFCs, and how most RFC processes are administered.&lt;&#x2F;p&gt;
&lt;p&gt;All RFC processes — Python&#x27;s PEPs, BitTorrent&#x27;s BEPs, Bevy, and Rust&#x27;s RFCs — are to some degree modeled off the original IETF RFC series. Here&#x27;s how that process was originally described. These are excerpts from &lt;a href=&quot;https:&#x2F;&#x2F;datatracker.ietf.org&#x2F;doc&#x2F;html&#x2F;rfc3&quot;&gt;RFC 3&lt;&#x2F;a&gt;, drafted in the summer of 1969:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;The content of [an RFC] may be any thought, suggestion, etc. [...]&lt;&#x2F;p&gt;
&lt;p&gt;Notes are encouraged to be timely rather than polished. Philosophical positions without examples or other specifics, specific suggestions or implementation techniques without introductory or background explication, and explicit questions without any attempted answers are all acceptable.&lt;&#x2F;p&gt;
&lt;p&gt;The minimum length for [an RFC] is one sentence.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;These standards (or lack of them) are stated explicitly for two reasons. First, there is a tendency to view a written statement as ipso facto authoritative, and we hope to promote the exchange and discussion of considerably less than authoritative ideas. Second, there is a natural hesitancy to publish something unpolished, and we hope to ease this inhibition.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Unfortunately, some fifty years later, many modern RFC processes seem to have forgotten these guidelines. Getting the first draft of an RFC published is usually an exhausting, sometimes excruciating process. Incomplete thoughts or designs, documents that collate useful information without making recommendations, and unanswered questions are often not accepted.&lt;&#x2F;p&gt;
&lt;p&gt;Take Rust as an example. Rust has, on the whole, a &lt;em&gt;healthy skepticism&lt;&#x2F;em&gt; of RFCs submitted by project newcomers. It is not a very open process. The Rust project also apparently uses something called a &quot;pre-RFC&quot; to vet documents before they reach the RFC stage; something akin to an RFC, but without the procedure. These &quot;pre-RFCs&quot; are, as far as I can tell, coupled with prototype compiler implementations, and shuffled around for informal review until deemed &quot;ready for general consumption&quot;.
This protective attitude is justified by the observation that&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] once an RFC has been published, it actually very rarely evolves significantly, because the author becomes entrenched in the proposal they&#x27;ve made. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-jubilee-1&quot;&gt;&lt;a href=&quot;#fn-jubilee&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I don&#x27;t begrudge Rust for adopting these procedures; they are a small team of experts navigating the development of a language and compiler that are at once extremely popular and &lt;em&gt;extremely complicated&lt;&#x2F;em&gt;. Aggressive vetting is obviously required. Still, to me as an outsider, this sounds like a red flag. RFCs are &quot;Requests For Comments&quot; after all. They are intended to stimulate discussion, and to be updated based on those discussions until consensus is reached. If authors are regularly becoming &quot;entrenched&quot; in their existing views, that is, in my layman&#x27;s opinion, a bad sign.&lt;&#x2F;p&gt;
&lt;p&gt;Bevy had entirely different issues with its RFC process. Writing an RFC took ages, getting it through review took ages, and then getting it actually accepted took ages. Partly this was because reading and reviewing an RFC is a heck of a lot harder than reviewing code, and partly it was because it wasn&#x27;t clear whose job it was to make the &quot;yes&#x2F;no&quot; call.&lt;&#x2F;p&gt;
&lt;p&gt;The result was burnout. We got some great RFCs, but usually the author was so exhausted after getting the design approved that they couldn&#x27;t manage the implementation. When things ended up being implemented, it often was much harder than expected, or the design had to be fundamentally altered. A few years on, most of Bevy’s accepted RFCs are now either not completely implemented or outdated.&lt;&#x2F;p&gt;
&lt;p&gt;These problems are not universal. It&#x27;s possible you&#x27;ve participated in an RFC process that didn&#x27;t suffer from these issues (in which case, please reach out, I&#x27;d love to hear more about it). But I&#x27;m willing to bet most people with any experience with RFCs will empathize with the issues I&#x27;ve described. Many RFC processes have issues like these. And almost always it&#x27;s because they have neglected an important aspect of what made RFCs make sense.&lt;&#x2F;p&gt;
&lt;p&gt;If you haven&#x27;t guessed it yet, that thing is the &quot;Working Group&quot;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;it-was-always-working-groups&quot;&gt;It Was Always Working Groups&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;datatracker.ietf.org&#x2F;doc&#x2F;html&#x2F;rfc3&quot;&gt;RFC 3&lt;&#x2F;a&gt;, which I quoted in the previous section, doesn&#x27;t talk about RFCs. It uses the term &quot;NWG Note&quot; instead, because originally RFCs were notes circulated to six members of the IETF Network Working Group.&lt;&#x2F;p&gt;
&lt;p&gt;I think this is super important context. Originally, an RFC was literally a &quot;request for comments &lt;em&gt;from the other five guys in the working group&lt;&#x2F;em&gt;&quot;. The members of the NWG all knew each other. They were working on similar stuff, and they started the RFC series to track and discuss their ideas. If you take process out of a collaborative group setting, the whole thing kind of falls apart.&lt;&#x2F;p&gt;
&lt;p&gt;All of the Bevy RFCs had basically a single author, as far as I can tell. They mostly weren&#x27;t writing for their peers, and they always didn&#x27;t have buy-in before they started writing. Without collaborators, the main source of comments on RFCs was the maintainers, and often reviews could be quite sparse because of the difficulty of the material. To the degree that any RFC was successful, it was due in large part because other members of the community were willing to spend the time to become deeply involved. And that didn&#x27;t always happen.&lt;&#x2F;p&gt;
&lt;p&gt;The lack of collaboration is, I think, why authors tended to burn out, and why RFCs tended to languish without implementations.&lt;&#x2F;p&gt;
&lt;p&gt;Honestly, I find this solo approach to RFCs very odd. After all, one of the neat things about working groups is that they are self-organizing. They spring up naturally after you get enough engineers in a room together, like mushrooms after a rain. People with similar interests naturally seek each other out if given the opportunity, and once two or three like-minded contributors get to talking, it&#x27;s only a short step to making plans and collaborating.&lt;&#x2F;p&gt;
&lt;p&gt;So I&#x27;m surprised that we didn&#x27;t see many “homegrown working groups&quot; submitting proposals through the RFC process. Outside the RFC system, we see them everywhere! Many of Bevy&#x27;s complex or controversial features were pushed forward by a team of three or four dedicated contributors, who could all review each other&#x27;s work and collaborate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-new-process&quot;&gt;The New Process&lt;&#x2F;h2&gt;
&lt;p&gt;After much discussion, we settled on a new process that would re-emphasize the importance of collaboration on complex features, but which would allow maintainers to steer (or veto) the direction of the work. You can read &lt;a href=&quot;https:&#x2F;&#x2F;bevy.org&#x2F;learn&#x2F;contribute&#x2F;project-information&#x2F;working-groups&#x2F;&quot;&gt;the full set of guidelines here&lt;&#x2F;a&gt;, but I will also briefly summarize them:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;To form a new working group, three people must put together a minimal proposal (a few sentences) and ask for maintainer ascent.&lt;&#x2F;li&gt;
&lt;li&gt;If accepted, the maintainers give them a dedicated space to communicate (a Discord thread), and the working group is tasked with developing a design document (essentially an RFC) and submitting it to the maintainers.&lt;&#x2F;li&gt;
&lt;li&gt;If the design doc is accepted by the maintainers, they may proceed to implementation without having to justify their design choices during code review (expediting the process).&lt;&#x2F;li&gt;
&lt;li&gt;Anyone can join or leave the group at any point, and there is no appointed leader. The group is encouraged to write down as much as possible, so it is easy for new members to join.&lt;&#x2F;li&gt;
&lt;li&gt;Groups are formally disbanded by the maintainers after the implementation is completed, there are fewer than three active participants, the work stalls, or the direction is vetoed.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;We hoped this process would:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Force people to check in with maintainers before starting work.&lt;&#x2F;li&gt;
&lt;li&gt;Allow the maintainers to limit the number of initiatives underway at once.&lt;&#x2F;li&gt;
&lt;li&gt;Help distribute the load over more people.&lt;&#x2F;li&gt;
&lt;li&gt;Ensure that there are always two people capable of doing internal peer review.&lt;&#x2F;li&gt;
&lt;li&gt;Allow design documents to change and shift during the implementation phase.&lt;&#x2F;li&gt;
&lt;li&gt;Direct bright-eyed new contributors to experts who can put them to work.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There was a second change that, in retrospect, was no less important. Previously, all our design documentation lived in GitHub discussions or as Markdown files within the RFC repo. But shortly before introducing working groups, we also created a quasi-official &lt;a href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;@bevy&quot;&gt;HackMD Org&lt;&#x2F;a&gt;. HackMD is Google Docs for Markdown, and though it wasn&#x27;t explicitly specified, most working groups ended up relying on HackMD to manage their associated design documents.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-went-well&quot;&gt;What Went Well&lt;&#x2F;h3&gt;
&lt;p&gt;We&#x27;ve now been using this process for well over a year and have hosted &lt;code&gt;27&lt;&#x2F;code&gt; working groups in that time.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;5&lt;&#x2F;code&gt; were for releases or game jams.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;3&lt;&#x2F;code&gt; were otherwise process or community-focused.&lt;&#x2F;li&gt;
&lt;li&gt;Of the remaining &lt;code&gt;19&lt;&#x2F;code&gt; feature-oriented working groups:
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;8&lt;&#x2F;code&gt; are effectively completed (curves, color, picking, no_std, text, bsn, audio, relations)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;2&lt;&#x2F;code&gt; were closed as unsuccessful (render-graph, decoupled-rendering)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;2&lt;&#x2F;code&gt; have temporarily stalled due to lack of contributors (ptr, transforms)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;7&lt;&#x2F;code&gt; are ongoing (cli, hotpatching, wesl, tilemaps, nonsend-data, observers, rendering-refactor)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Which means that, of the &lt;code&gt;19&lt;&#x2F;code&gt; feature-oriented working groups, &lt;code&gt;15&lt;&#x2F;code&gt; either ended up completed successfully or are on track to be completed. When I ran a similar tally in April, this stood at &lt;code&gt;11&lt;&#x2F;code&gt; groups out of &lt;code&gt;14&lt;&#x2F;code&gt;. If we only consider the definitively ended groups, it&#x27;s &lt;code&gt;8&lt;&#x2F;code&gt; successes and effectively &lt;code&gt;2&lt;&#x2F;code&gt; failures (I expect the two stalled groups to get back into motion soon).&lt;&#x2F;p&gt;
&lt;p&gt;These numbers are pretty encouraging: more than half the working groups we started last year reached a definitive conclusion, and three-fourths were successful. By contrast, of the &lt;code&gt;74&lt;&#x2F;code&gt; Bevy RFCs, &lt;code&gt;32&lt;&#x2F;code&gt; have stalled with no expectation of completion and &lt;code&gt;33&lt;&#x2F;code&gt; were closed without being accepted. Only &lt;code&gt;9&lt;&#x2F;code&gt; were ever accepted, and &lt;code&gt;5&lt;&#x2F;code&gt; took two or more years to implement.&lt;&#x2F;p&gt;
&lt;p&gt;It&#x27;s worth noting that Bevy&#x27;s RFC usage was already in decline before these procedural changes, and these lackluster RFC success numbers looked more or less the same a year ago.&lt;&#x2F;p&gt;
&lt;p&gt;One thing I was not expecting was the degree to which HackMD has displaced the RFC writing process. It ended up being essential to the working group process and has led to a substantial increase in the amount of writing done by the community as a whole. Our HackMD org is now filled with content that would fit very nicely under the criteria of RFC 3. Much of it is loosely structured or incomplete. But timely information, even if partial, is preferable to none. And incomplete work is, in this case, an invitation to collaborate.&lt;&#x2F;p&gt;
&lt;p&gt;I think HackMD has largely freed us from the friction, formality, and stuffiness of RFCs. As a result, the community has written a lot of really great stuff! The org now has &lt;code&gt;59&lt;&#x2F;code&gt; members (and &lt;code&gt;25&lt;&#x2F;code&gt; non-member contributors) and has produced &lt;code&gt;72&lt;&#x2F;code&gt; notes. That&#x27;s close to &lt;code&gt;74&lt;&#x2F;code&gt; RFCs Bevy received over the last five years. So in that regard, I&#x27;m incredibly pleased.&lt;&#x2F;p&gt;
&lt;p&gt;The new process has met many of its stated goals as well:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The maintainers have said &quot;no&quot; to working groups that it wasn&#x27;t time for.&lt;&#x2F;li&gt;
&lt;li&gt;Maintainers have been able to conclusively halt work they disagreed with.&lt;&#x2F;li&gt;
&lt;li&gt;Proposed working groups have failed to form due to lack of interest.&lt;&#x2F;li&gt;
&lt;li&gt;Many working groups incorporate significant work from multiple core contributors.&lt;&#x2F;li&gt;
&lt;li&gt;New contributors do join working groups and often make meaningful contributions.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Most importantly: the new process does seem to have reduced burnout and fostered healthy and sustained collaborations. The &quot;Better Audio&quot; working group, for example, has been quietly trucking along for more than a year now, with multiple brilliant contributors regularly producing amazing work, and no signs of slowing down. Is this because that working group is full of amazing and uniquely talented contributors? Yes! But I hazard it&#x27;s also because it&#x27;s become Bevy’s dedicated audio-nerd hang-out space. A tiny community has formed around that feature, and it keeps people motivated to work on it.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-s-still-hard&quot;&gt;What&#x27;s Still Hard&lt;&#x2F;h3&gt;
&lt;p&gt;Nothing is perfect, and there are still issues with the working group process.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;You can&#x27;t manufacture interest. Some working groups still languish.&lt;&#x2F;li&gt;
&lt;li&gt;Rendering tends not to create working groups, and some of the rendering working groups have struggled with participation.&lt;&#x2F;li&gt;
&lt;li&gt;We potentially have started too many working groups at once, and our core contributor base may be spread too thinly between them.&lt;&#x2F;li&gt;
&lt;li&gt;Several working groups have proceeded directly to implementation, without completing their design documents or getting them approved.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;While the working group process feels less formal and heavy-weight than RFCs, it also has a tendency to let boundaries blur. Every group needs at least three active participants to sustain it, but it&#x27;s hard to say exactly what constitutes &quot;active&quot;, or how many groups a single person can reasonably be &quot;active&quot; in at once. The line between the &quot;design phase&quot; and &quot;implementation phase&quot; is also pretty permeable.&lt;&#x2F;p&gt;
&lt;p&gt;There&#x27;s also a degree of permeability between what is and isn&#x27;t a working group.
When I got &lt;a href=&quot;https:&#x2F;&#x2F;www.charlotte.fyi&quot;&gt;Charlotte&lt;&#x2F;a&gt;&#x27;s opinion on the scarcity of rendering working groups, she pointed out the rendering contributors&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] tend to be pretty well aligned relative to other teams and do a good job building consensus in a more ad-hoc manner&quot; without needing to actually create formal groups for each initiative. [...] It&#x27;s more about forming small groups in order to execute on some sub-goal rather than generating buy-in through a higher level planning process.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;This is a good take, and an indication that the formal &quot;working groups process&quot; is still too formal and bureaucratic for some situations. The rendering contributors are extremely well aligned and highly productive, so clearly whatever they are doing is working. Still, I&#x27;d still like to encourage them to write more stuff down, and to make their informal groups easier to discover and join. Perhaps there are ways we can change the process to make it work better for them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;maybe-try-it&quot;&gt;Maybe Try It?&lt;&#x2F;h2&gt;
&lt;p&gt;To summarize, we took an existing semi-dysfunctional RFC process and&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Shifted the emphasis from the documents themselves to the communities that write them,&lt;&#x2F;li&gt;
&lt;li&gt;Gave those communities names, gentle oversight, and spaces to communicate,&lt;&#x2F;li&gt;
&lt;li&gt;Made it much easier for them to write and edit documents collaboratively.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;People really seem to like the new process; more stuff has been getting written down, more newcomers are able to help with big initiatives, and many complex features are proceeding swiftly from design and into implementation.&lt;&#x2F;p&gt;
&lt;p&gt;It has been amazing to see the Bevy community come together over the past year for these &lt;code&gt;27&lt;&#x2F;code&gt; different initiatives. I cannot wait for the day when — some time in the next year —  the first editor working group is officially launched. I&#x27;d also be eager to see other open source projects experiment with ways to get closer to the &quot;old school&quot; spirit outlined in RFC 3.&lt;&#x2F;p&gt;
&lt;footer class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;I&#x27;m counting total historical contributors here. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-jubilee&quot;&gt;
&lt;p&gt;This is a quote of a friendly and helpful explanation &lt;code&gt;workingjubilee&lt;&#x2F;code&gt; posted in response to a newcomer eager to submit an RFC. It&#x27;s worth noting that Jubilee is a member of the compiler team rather than the lang team, and obviously doesn’t speak for the project as a whole. Still, this framing has kind of stuck in my brain since I read it. There&#x27;s more context in the &lt;a href=&quot;https:&#x2F;&#x2F;rust-lang.zulipchat.com&#x2F;#narrow&#x2F;channel&#x2F;131828-t-compiler&#x2F;topic&#x2F;speculative.20compiler.20internals.20as.20lang.20RFC.20content&#x2F;near&#x2F;529592840&quot;&gt;original thread&lt;&#x2F;a&gt;. &lt;a href=&quot;#fr-jubilee-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;footer&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Become a Regular Contributor</title>
        <published>2025-03-10T00:00:00+00:00</published>
        <updated>2025-03-10T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Miles Silberling-Cook
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://internet.place/content/regular-contributor/"/>
        <id>https://internet.place/content/regular-contributor/</id>
        
        <content type="html" xml:base="https://internet.place/content/regular-contributor/">&lt;blockquote&gt;
&lt;p&gt;Would you tell me, please, which way I ought to go from here? &lt;&#x2F;br&gt;
That depends a good deal on where you want to get to.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Any healthy community project attracts a crowd of people who want to help out in a regular sustained way, but don&#x27;t know where to begin. The &lt;a href=&quot;https:&#x2F;&#x2F;bevyengine.org&quot;&gt;Bevy Game Engine&lt;&#x2F;a&gt; gets a lot of these people, which is great. I am a regular contributor to Bevy and am somewhat active in community discussions, and so I&#x27;m occasionally in a position to offer advice to people caught in this situation. To make things easier, I thought I&#x27;d collect this advice into an article so I can easily link to it.&lt;&#x2F;p&gt;
&lt;p&gt;If you did get linked here from Bevy, you should also take a look at the &lt;a href=&quot;https:&#x2F;&#x2F;bevyengine.org&#x2F;learn&#x2F;contribute&#x2F;introduction&#x2F;&quot;&gt;Contributing Guide&lt;&#x2F;a&gt; (which, incidentally, I helped write). If not, the advice I&#x27;m going to offer should be generally applicable to most open-source projects.&lt;&#x2F;p&gt;
&lt;p&gt;This advice is aimed mostly at junior devs - especially those new to open source. If you&#x27;re more experienced, what I have to say probably won&#x27;t be very interesting to you. Whoever you are, if there&#x27;s an open-source project you just &lt;em&gt;know&lt;&#x2F;em&gt; you&#x27;d love to become closely involved with but don&#x27;t know where to start, I recommend doing these four things:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Offer to do tiny, longstanding chores.&lt;&#x2F;li&gt;
&lt;li&gt;Study the code and take notes.&lt;&#x2F;li&gt;
&lt;li&gt;Ask questions in code reviews.&lt;&#x2F;li&gt;
&lt;li&gt;Attempt ambitious projects and refactors.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;h2 id=&quot;tackle-tiny-chores&quot;&gt;Tackle Tiny Chores&lt;&#x2F;h2&gt;
&lt;p&gt;Starting small is the most obvious approach, and it&#x27;s a good one. Most projects have a mountain of tiny little chores that no one ever seems to get to. Probably because the more senior contributors are preoccupied with larger problems. Part of why new contributors are valuable to projects is exactly that they can help tackle this backlog (with the other part being that they sometimes grow into senior contributors and help sustain the project).&lt;&#x2F;p&gt;
&lt;p&gt;The main thing you will get out of chores (apart from an exercise in self-discipline) is experience with the tooling and process in a low-stakes environment. If you&#x27;re new to the language, or for example, &lt;code&gt;git&lt;&#x2F;code&gt;, chores are the way to level up your skills until you reach basic proficiency. If you already have basic technical proficiency, it will still teach you about the social conventions and process particular to the community you are joining.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;study-the-code&quot;&gt;Study The Code&lt;&#x2F;h2&gt;
&lt;p&gt;If the previous section seemed obvious, this one may not: You should get out a pen and paper (or whatever note-taking app you prefer) and read the entire codebase top-to-bottom like a &quot;Choose Your Own Adventure&quot; novel. Pick an example or some well-isolated top-level logic, and open it in an editor with &lt;em&gt;go-to-definition&lt;&#x2F;em&gt; support. This is the &quot;top&quot; of your call-stack; from there you should trace down all the definitions, reading and annotating as you go, until you reach the &quot;bottom&quot; and your code hits the underplaying API calls. Your goal here is to produce an architectural overview describing all the layers of abstraction you encounter and how they fit together. If you stick at it, you should end up with something like &lt;a href=&quot;https:&#x2F;&#x2F;hackmd.io&#x2F;@bevy&#x2F;rendering_summary&quot;&gt;this&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I sense some of you may have some concerns...&lt;&#x2F;p&gt;
&lt;p&gt;The first thing I want to assure you is &lt;em&gt;you can do this&lt;&#x2F;em&gt;. If you can write code, you can read it. Code comprehension is a skill, and like all skills you can develop it through regular exercise, even if it feels strange at first. The second thing you should know is: there is no substitute. The other things on this list will teach you the tooling and the process, teach you to make good engineering and design decisions, teach you where the codebase is going. But nothing will familiarize you with the codebase as it is like buckling down and reading it.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t think it&#x27;s controversial to say that most codebases are poorly documented. Even those that are not tend to lack broad architectural overviews, or cohesive visions of how all the pieces fit together to make the whole. Those diagrams usually exist only in people&#x27;s minds. If you&#x27;ve only worked on your own projects before, you&#x27;ve gotten those mental models for free. But when you are interacting with code written by others, potentially hundreds or thousands of others, you&#x27;ll need to spend time to grok (a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Grok&quot;&gt;wonderful term&lt;&#x2F;a&gt; from a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Stranger_in_a_Strange_Land&quot;&gt;horrible book&lt;&#x2F;a&gt;) the existing structure. It won&#x27;t necessarily happen on its own.&lt;&#x2F;p&gt;
&lt;p&gt;Note that you don&#x27;t have to actually complete your architectural review for it to be a useful exercise. About 20%, or just enough to know how the lower-level API calls relate to the top-level abstraction, is probably enough to get you to where you need to be.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;ask-questions-in-reviews&quot;&gt;Ask Questions In Reviews&lt;&#x2F;h2&gt;
&lt;p&gt;Bevy, like some other open source projects, has a &lt;a href=&quot;https:&#x2F;&#x2F;www.leafwing-studios.com&#x2F;blog&#x2F;triage-by-controversy&#x2F;&quot;&gt;community review process&lt;&#x2F;a&gt;. Alice&#x27;s article lays out how it works, so I&#x27;ll just pick out the most salient point:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;Anyone (literally, anyone) can review a PR. GitHub just lets you do it!&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Now I&#x27;ll let you in on a little secret: Even if GitHub doesn’t let you hit the &quot;approve&quot; button for your particular project, you can almost always leave comments on open PRs pointing out errors or asking questions. When you&#x27;re just starting out, my advice is to do this a lot.&lt;&#x2F;p&gt;
&lt;p&gt;First, obviously, you&#x27;ve got to read the PR over. Don&#x27;t leave review comments on PRs you have not read. But, if you followed the advice from the previous section, reading code should already feel natural to you. You will find that code review feels a little different than static architectural analysis: When doing an architectural analysis, all you care about is how things fit together, but when reviewing a PR, you should also be trying to ascertain if it is &lt;em&gt;correct&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll warn you upfront: checking code for correctness is hard. How hard depends on the domain, but it&#x27;s always hard. As a new contributor, you are likely to immediately run into code you either don&#x27;t understand or misunderstand (and which you may therefore incorrectly identify as an issue). This is fine and expected. So what you should do, considering that you may make frequent mistakes, is (a) be polite and (b) ask a lot of clarifying questions.&lt;&#x2F;p&gt;
&lt;p&gt;Most of the time, the author will be happy to explain, but sometimes you will actually catch bugs just by asking about confusing bits of code! After all, the confusing bits are the most likely to be wrong. So the project gets additional valuable scrutiny on its PRs, and you essentially get mentored by the author for a bit. As an aside, please try to be mindful of the author&#x27;s time when following this advice. Ask for additional information, not additional work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;attempt-ambitious-projects&quot;&gt;Attempt Ambitious Projects&lt;&#x2F;h2&gt;
&lt;p&gt;Many new contributors seem to tend naturally to ambitious large-scale improvements, and I can hardly blame them. Ambition is a great motivator, and to some degree is probably selected for in the population of people who are willing to throw themselves at a new project knowing basically nothing. My advice here is to temper your expectations, but to let yourself be ambitious nonetheless.&lt;&#x2F;p&gt;
&lt;p&gt;If you&#x27;re doing the other three things on this list, you&#x27;re probably going to start developing opinions about and ideas for improving your project&#x27;s codebase. Follow those feelings... follow them, with the knowledge that your first few big projects are probably not going to make it to completion. Part of becoming a seasoned contributor is, honestly, fighting with big changes, struggling, figuring out why no one else has solved this yet, and walking away. Don&#x27;t let yourself become discouraged by failure - having to give up on a branch, or deciding you took the wrong approach and needing to start over, or declaring git bankruptcy because your history is out of control - these are all perfectly normal. If worst comes to worst, you can always shelve your idea and come back to it when you&#x27;ve got more experience.&lt;&#x2F;p&gt;
&lt;p&gt;I don&#x27;t want to give you the impression that I&#x27;m expecting you to fail every time you pick up a big task. There will be successes too: For me, I&#x27;d say about one in every five of my early attempts at big contributions ended up with a merged PR. A 20% success rate is not nothing. For the project that merges them, the unlikely successes are golden eggs. Ambitious PRs are, by definition, important. When someone new steps in and resolves an important bug or feature, that is the best-case scenario for the project: increasing momentum, freeing up other resources down the line, moving the project closer to its goals. It&#x27;s not just that the important thing got done, it&#x27;s that none of the other existing contributors had to take time away from their other work to do it.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;now-what&quot;&gt;Now What&lt;&#x2F;h2&gt;
&lt;p&gt;If I know my audience, I suspect all of you will be doing some of these already, and some of you will be doing all of them. If you&#x27;re only doing (1), (2), or (3), consider balancing out your approach with the other two: it can keep things fresh and interesting. In my experience, (4) tends to develop more from the other three than a conscious choice.&lt;&#x2F;p&gt;
&lt;p&gt;Eventually, you will find:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;That the chores are no longer a good use of your time.&lt;&#x2F;li&gt;
&lt;li&gt;That you need to read up on the code less and less.&lt;&#x2F;li&gt;
&lt;li&gt;That your questions reveal more and more issues.&lt;&#x2F;li&gt;
&lt;li&gt;That your ambitious projects frequently end in success.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Congratulations, you&#x27;ve become a regular contributor.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Hello World</title>
        <published>2025-03-08T00:00:00+00:00</published>
        <updated>2025-03-08T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Miles Silberling-Cook
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://internet.place/content/hello-world/"/>
        <id>https://internet.place/content/hello-world/</id>
        
        <content type="html" xml:base="https://internet.place/content/hello-world/">&lt;blockquote&gt;
&lt;p&gt;Look at that subtle off-white coloring. The tasteful thickness of it.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I now have an internet place (a blog). For anyone who may not be aware, a &quot;Blog&quot; is where you play around with graphic design while imagining all the amazing and insightful articles that you will, one day, totally get around to writing. I spent a lot of time making this one look pretty and ensuring it met all the web accessibility guidelines. And by that, I mean I spent a lot of time browsing other websites and stealing stuff.&lt;&#x2F;p&gt;
&lt;p&gt;The headers are &lt;a href=&quot;http:&#x2F;&#x2F;vollkorn-typeface.com&quot;&gt;Vollkorn&lt;&#x2F;a&gt;, the body is &lt;a href=&quot;https:&#x2F;&#x2F;tinytype.co&#x2F;type&#x2F;dover-text&quot;&gt;Dover Text&lt;&#x2F;a&gt;, the monospace bits are &lt;a href=&quot;https:&#x2F;&#x2F;www.colophon-foundry.org&#x2F;custom-projects&#x2F;space-mono&quot;&gt;Space Mono&lt;&#x2F;a&gt;. I cribbed the core design language pretty much wholesale from the &lt;a href=&quot;https:&#x2F;&#x2F;usgraphics.com&quot;&gt;US Graphics Company&lt;&#x2F;a&gt;. Even the colors are from Tailwind. It&#x27;s all built using &lt;a href=&quot;https:&#x2F;&#x2F;www.getzola.org&quot;&gt;Zola&lt;&#x2F;a&gt; and hosted on &lt;a href=&quot;https:&#x2F;&#x2F;pages.cloudflare.com&quot;&gt;Cloudflare Pages&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;One day, all of those links will be dead, and no one will know what any of that meant. The servers hosting this will be rusting in a backlot somewhere, or maybe they&#x27;ll have been recycled into aluminum Yetti mugs. This site probably will have gone down long before that. Maybe I&#x27;ll get fed up with it and take it down, or maybe give up programming entirely and forget it exists. Most likely I&#x27;ll fail to renew the domain and will have to set it all up again in a year.&lt;&#x2F;p&gt;
&lt;p&gt;But for now, we&#x27;re both here, at the same time, and we can enjoy this internet place together.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
