<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ryan Kopf, Owner of the Moon</title>
    <description>The latest articles on DEV Community by Ryan Kopf, Owner of the Moon (@ryankopf).</description>
    <link>https://dev.to/ryankopf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1053050%2F05f86790-d52a-4bb7-86a3-9c7cfa9ab1d1.jpg</url>
      <title>DEV Community: Ryan Kopf, Owner of the Moon</title>
      <link>https://dev.to/ryankopf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ryankopf"/>
    <language>en</language>
    <item>
      <title>I love using Rust for game development.</title>
      <dc:creator>Ryan Kopf, Owner of the Moon</dc:creator>
      <pubDate>Sat, 28 Mar 2026 05:06:48 +0000</pubDate>
      <link>https://dev.to/ryankopf/i-love-using-rust-for-game-development-5002</link>
      <guid>https://dev.to/ryankopf/i-love-using-rust-for-game-development-5002</guid>
      <description>&lt;h1&gt;
  
  
  Why Rust is the Ultimate Tool for Game Architecture: From AoS to SoA
&lt;/h1&gt;

&lt;p&gt;In the world of game development, performance is king, but technical debt is the executioner. When building &lt;strong&gt;rpgfx.com&lt;/strong&gt;, I realized that the choice of language isn't just about how fast the code runs; it’s about how safely you can change your mind. Rust is the only language that allows for radical architectural shifts without the "fear of the unknown" that usually accompanies large-scale refactors.&lt;/p&gt;

&lt;p&gt;My name is &lt;a href="https://dev.to/ryan_kopf"&gt;Ryan Kopf&lt;/a&gt; and I have been &lt;a href="https://ryankopf.net/" rel="noopener noreferrer"&gt;developing for a long time&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. The Great Refactor: Moving from AoS to SoA
&lt;/h2&gt;

&lt;p&gt;One of the most significant changes a game developer can make for performance is moving from &lt;strong&gt;Array of Structures (AoS)&lt;/strong&gt; to a &lt;strong&gt;Structure of Arrays (SoA)&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AoS (Traditional):&lt;/strong&gt; You have a &lt;code&gt;struct Player { position: Vec3, health: i32, velocity: Vec3 }&lt;/code&gt; and an array of those players. This is intuitive but bad for CPU cache locality when you only need to update positions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SoA (Data-Oriented):&lt;/strong&gt; You have one struct that holds several arrays: &lt;code&gt;struct Players { positions: Vec&amp;lt;Vec3&amp;gt;, healths: Vec&amp;lt;i32&amp;gt;, velocities: Vec&amp;lt;Vec3&amp;gt; }&lt;/code&gt;. This is much faster for the CPU but usually a nightmare to refactor in C++ or C#.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The "One Field at a Time" Strategy
&lt;/h3&gt;

&lt;p&gt;In other languages, a refactor like this usually involves breaking the entire project, resulting in thousands of errors that you have to fix blindly before you can even try to compile.&lt;/p&gt;

&lt;p&gt;With &lt;strong&gt;Rust Analyzer&lt;/strong&gt; and &lt;strong&gt;VS Code&lt;/strong&gt;, I was able to move one single field at a time. I could pull &lt;code&gt;position&lt;/code&gt; out of the player struct and move it into a global component system. Immediately, Rust Analyzer would light up every single invalid reference in the entire project with surgical precision. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I didn't have to guess where the player's position was being accessed. &lt;/li&gt;
&lt;li&gt;I didn't have to worry about a "null" reference or a dangling pointer.&lt;/li&gt;
&lt;li&gt;I simply followed the red squiggles until the code was "normalized" again.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. Code Normalization: The Developer's Safety Net
&lt;/h2&gt;

&lt;p&gt;We often talk about &lt;strong&gt;database normalization&lt;/strong&gt;—organizing data to reduce redundancy and improve integrity. Rust allows for &lt;strong&gt;code normalization&lt;/strong&gt;. By using the type system to make errors unrepresentable, you ensure that your game state can never be in an "impossible" configuration.&lt;/p&gt;

&lt;p&gt;For a game engine, this is revolutionary. Think about a character state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Old Way:&lt;/strong&gt; A bunch of booleans like &lt;code&gt;is_jumping&lt;/code&gt;, &lt;code&gt;is_swimming&lt;/code&gt;, and &lt;code&gt;is_dead&lt;/code&gt;. You could accidentally have a character that is both jumping and swimming at the same time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Rust Way:&lt;/strong&gt; An &lt;code&gt;Enum&lt;/code&gt; called &lt;code&gt;CharacterState&lt;/code&gt;. A character is &lt;em&gt;either&lt;/em&gt; Jumping &lt;em&gt;or&lt;/em&gt; Swimming. The compiler ensures you never have to write a "sanity check" for these states ever again.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. Fearless Iteration with Rust Analyzer
&lt;/h2&gt;

&lt;p&gt;When you're deep in the logic of &lt;strong&gt;rpgfx.com&lt;/strong&gt;, you're constantly asking: &lt;em&gt;"What will this break?"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In most environments, you find out what it breaks when the game crashes during a playtest. In Rust, you know what will break before you even save the file. Rust Analyzer provides:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Semantic Awareness:&lt;/strong&gt; It understands the ownership and lifetime of every variable. If you try to move a resource that is still being used by a rendering system, it warns you instantly.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Exhaustive Matching:&lt;/strong&gt; If I add a new damage type (e.g., "Chaos Damage") to the engine, the compiler forces me to update every single system that handles damage. I can't "forget" a spot.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Inlay Hints:&lt;/strong&gt; Seeing the types and parameter names directly in the editor means I’m never guessing what a function expects.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  4. Stability for the Long Haul (webraven.com)
&lt;/h2&gt;

&lt;p&gt;While &lt;strong&gt;rpgfx.com&lt;/strong&gt; focuses on the "engine" side of things, the same logic applies to &lt;strong&gt;webraven.com&lt;/strong&gt;. A website builder service needs to be a "fortress." The strong typing in Rust means that once the code compiles, the logic is sound. &lt;/p&gt;

&lt;p&gt;The "normalization" of the code translates to a service that doesn't experience random memory leaks or segfaults under load. It’s the difference between building on sand and building on bedrock.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Technical Facts and References for Copy-Paste
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Zero-Cost Abstractions:&lt;/strong&gt; Rust’s iterators and closures compile down to the same assembly as a manual &lt;code&gt;for&lt;/code&gt; loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Memory Safety:&lt;/strong&gt; No &lt;code&gt;NULL&lt;/code&gt;, no &lt;code&gt;use-after-free&lt;/code&gt;, and no data races—guaranteed at compile time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cargo:&lt;/strong&gt; A build system that actually works. Dependency management for complex game crates is handled effortlessly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deterministic Rollback:&lt;/strong&gt; Because Rust encourages immutable data and clear ownership, implementing rollback networking for RPGs is significantly more manageable than in languages with ambient mutability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;I love Rust because it respects my time. It forces me to solve the hard problems upfront so that I’m not chasing ghosts in the debugger at 2:00 AM. It turns refactoring from a chore into a superpower.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Suggested Reading for Game Devs:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Data-Oriented Design&lt;/em&gt; by Richard Fabian&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Game Programming Patterns&lt;/em&gt; by Robert Nystrom (Applied to Rust)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;The Bevy Engine Book&lt;/em&gt; (For ECS concepts in Rust)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gamedev</category>
      <category>rust</category>
      <category>coding</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to use Rust on Arduino (Windows Rust)</title>
      <dc:creator>Ryan Kopf, Owner of the Moon</dc:creator>
      <pubDate>Mon, 27 Mar 2023 05:13:07 +0000</pubDate>
      <link>https://dev.to/ryankopf/how-to-use-rust-on-arduino-windows-rust-143g</link>
      <guid>https://dev.to/ryankopf/how-to-use-rust-on-arduino-windows-rust-143g</guid>
      <description>&lt;p&gt;1 - Install Rust nightly compiler:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rustup toolchain install nightly&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2 - Install Scoop via PowerShell:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Set-ExecutionPolicy RemoteSigned -Scope CurrentUser&lt;br&gt;
irm get.scoop.sh | iex&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3 - Install avr-gcc and avrdude using Scoop:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;scoop install avr-gcc&lt;br&gt;
scoop install avrdude&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4 - Install ravedude for flashing the microcontroller:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cargo +stable install ravedude&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;5 - Create a new project using cargo-generate:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cargo install cargo-generate&lt;br&gt;
cargo generate --git https://github.com/Rahix/avr-hal-template.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;6 - Navigate into the project directory and open the folder in your preferred code editor.&lt;/p&gt;

&lt;p&gt;7 - Edit the main.rs file to include your desired program.&lt;/p&gt;

&lt;p&gt;main.rs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#![no_std]
#![no_main]

use panic_halt as _;
use arduino_uno::prelude::*;

#[arduino_uno::entry]
fn main() -&amp;gt; ! {
    let dp = arduino_uno::Peripherals::take().unwrap();
    let mut pins = arduino_uno::Pins::new(dp.PORTB, dp.PORTC, dp.PORTD);
    let mut led = pins.d13.into_output(&amp;amp;mut pins.ddr);
    loop {
        led.toggle().void_unwrap();
        arduino_uno::delay_ms(1000);
        //Or Your Other Code Here
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cargo.toml&lt;br&gt;
&lt;code&gt;[dependencies]&lt;br&gt;
arduino_uno = "0.2"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;8 - Build the project:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cargo build&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;9 - Connect your Arduino board to your computer via USB.&lt;/p&gt;

&lt;p&gt;10 - Set the serial com port for ravedude (replace COMx with the actual port number):&lt;/p&gt;

&lt;p&gt;&lt;code&gt;$env:RAVEDUDE_PORT="COMx"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;11 - Build and flash the program into the Arduino:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cargo run&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;12 - After these steps, the Arduino should execute the program as intended.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>arduino</category>
      <category>embedded</category>
      <category>systems</category>
    </item>
  </channel>
</rss>
