--- > Building an engine from scratch means every line of code has intention. No framework defaults. No opinionated abstractions hiding behind macros. Just Rust, `winit`, `softbuffer`, and deliberate choices. --- ## Stack Decisions ### Why Rust? - Memory safety without garbage collection - Strong type system catches mistakes at compile time - Zero-cost abstractions ### Why Not Bevy / Godot / <Insert Engine/Framework here>? I've done my fair share with existing game engines like Unity and Godot. They have their places, but I want the engine to behave exactly how _I_ want it to. I want full control over data types, rendering pipelines, collision detection, and more. I want as much control as possible while still keeping it realistic. I could write my own window handler, input system, and renderer from scratch for every operating system, but inventing every wheel seems redundant. **Yes, I'm not lost to the irony of writing my own game engine.** I also want granular control over which libraries are used and which aren't. Why import 3D libraries when the game I'm making is strictly 2D? There's also a security benefit. Just look at the worms and compromised `pypi`/`npm` packages getting pwned day in and day out. Minimizing dependency surface area is a feature, not a bug. I preach reducing attack surface every day at work. I can't exactly cast stones from a glass house by blindly importing every crate on crates.io. Anywho! I want to learn something new. What better way than writing my own game engine alongside the game itself? ### Workspace Structure So, how about keeping all this manageable as code? Split everything up into different workspaces. The engine is a library crate, and the game is a regular binary crate. ```text chromatic-hero/ ├── Cargo.lock ├── Cargo.toml ├── chromatic-hero/ │ ├── Cargo.toml │ └── src/ │ └── main.rs ├── corrosion-2d/ │ ├── Cargo.toml │ └── src/ │ ├── app.rs │ ├── ecs/ │ │ ├── component.rs │ │ ├── entity.rs │ │ ├── mod.rs │ │ └── world.rs │ ├── gfx/ │ │ ├── camera.rs │ │ ├── mod.rs │ │ ├── renderer.rs │ │ └── sprite.rs │ ├── input.rs │ ├── lib.rs │ └── utils/ │ ├── math.rs │ └── mod.rs ├── .gitignore └── README.md ``` Separating the engine from the game early on enforces certain "rules." The engine doesn't know game logic, and the game logic doesn't depend on engine internals. A caveat, though, one that sort of goes against my ethos: **solving a problem that isn't there yet.** I could just separate the code into subfolders: one for the Engine and all its components, and one for the Game itself. There's nothing inherently bad with building a monolithic codebase, especially when it's just me and nobody else coding in my project. But... if halfway through development (which is likely based on past experience) I get a new, awesome idea that I want to implement _now_, reusing an engine buried in two years of spaghetti code isn't easy, nor fun, to fix. This structure forces me to split the code correctly from the start, saving future headaches. --- ## Version Control: Jujutsu Over Git After years of wrestling with merge conflicts, rebase hell, and accidental force pushes, I switched to **Jujutsu** (`jj`) for local development. ### Why `jj`? |Git|Jujutsu| |---|---| |Commits are fixed once written|Changes are mutable until pushed| |Merge commits create noise|Automatic linear history by default| |`rebase` requires understanding the whole chain|`jj squash` just works| |Detached HEAD is confusing|Every commit has a change ID independent of hash| For solo development, `jj` removes the mental tax of version control. I spend less time managing branches and more time writing code. One thing I really enjoy with `jj` compared to `git` is the **"code-first, VCS-later"** workflow. If you get into a flow and start typing away like a crazy person, it's much easier in `jj` to branch off later and not screw everything up. You code first, then version control when you're done, rather than dealing with that problem hours before even trying something out. With `git`, you usually create a `branch` _and then_ program. With `jj`, you can safely try out some weird shit, then version control to a different branch or whatever without the friction. --- Next up: **0x2001_Winit** - getting pixels on screen without a shader pipeline. --- _[[email protected]](mailto:[email protected]) | [[0x2000_init]] → Next: [[0x2001_cargo_new_chromatic-hero]]_