diff --git a/_posts/2023-10-25-making-unity-a-decent-employee-0.md b/_posts/2023-10-25-making-unity-a-decent-employee-0.md
new file mode 100644
index 0000000..f5c927c
--- /dev/null
+++ b/_posts/2023-10-25-making-unity-a-decent-employee-0.md
@@ -0,0 +1,161 @@
+---
+layout: post
+title: "The Unity Engine is your worst coworker - Here's 4 strategies to improve it"
+date: 2023-10-25 10:30:00
+categories: unity
+tags: unity, csharp, workflow, testing, reliability
+# image: /assets/article_images/unity/worst-colleague.png
+author_name: Johannes Vollmer
+author_link: /authors/johannes-vollmer
+author_image: /assets/images/authors/johannes-vollmer/thumbnail.jpg
+published: false
+# target publish date: december
+---
+
+
+
+It's a cloudy monday morning. Your jeans are soaked from the rain on the way to the office. There's only a sip of cold coffee left in your mug as you are leaving your desk with your presentation notes.
+
+Your heart is pounding, as you open the door to the meeting room, knowing that a dozen of people sit there, waiting.
+Jeff, the coworker you teamed up with, nods and smiles, reassuring that everything is prepared. Everyone's staring at you.
+
+"So, this is the fantastic game Jeff and I worked on", you say nervously.
+"Jeff, could you please put it on the Screen?"
+
+Jeff goes "Alright!" and plugs his Laptop in. Everyone sees the cat trying to eat cotton candy, his desktop background.
+"Jeff could you please open the Game?" What is he waiting for?
+
+"No, I cannot open the Game", Jeff explains calmly, "the attachment in your mail last week was corrupted, and I didn't want to get in your way, so of course I don't have it."
+
+### WTjeFf?!
+
+You take a deep breath. Isn't that wonderful. What a bold move, Jeff.
+
+Think about it for a second: If your human colleague was doing what Unity does, you'd dig up their dead pet cat called Pumpkins, and leave the stiff body on their bed while they're sleeping. Well, at least I would.
+
+![image of pumpkins the cat. if you are reading this instead of seeing the image: he was cute, trust me. not in this image though. this is a picture of the exhumined cat.]()
+
+Let's shift perspectives: What would you have done in Jeff's position? What would be the right thing to do? What would be the nicest thing you could imagine?
+
+
+
+## What could have been
+
+Just looking at the code and assets, it's hard to tell whether the game will even run. Every tiny little change has to be tested manually. A missing prefab will only result in an Error when encountered in the running Game, because Unity ... assumes you did that on purpose????
+
+If you have had the chance in your life to program in more statically tight languages, like Elm or Rust, you will know that programming can be very different. (If not, please do try those!) The Elm language, for example, prevents **all runtime errors**. Yes, you read that right. You will not experience a single runtime exception in Elm. How is that possible?
+
+If an operation can fail in Elm, BEFORE anything happens, the compiler gets up from his desk and walks over to yours:
+"Hey, if they don't have the pumpkin spiced latte grande with extra glitter, should I get you something else or just nothing?"
+His soothing voice is a grace. You're happy they asked you, instead of just returning with bare hands. You rest assured they'd let you know of a fire when it starts, not when your house burned down already.
+
+Sorry, I get emotional about this topic sometimes. The point is: The Elm compiler is your friend, your pair programmer. If he does not see any problem with your code, you can be pretty sure it works. Sprinkle a few unit tests on top, and you're safe. Yes, it's a bit tedious sometimes, but for me, it's definitely worth it.
+
+Unity however is quiet the opposite, just like most popular language in 2023 (he who must not be named).
+If anything goes wrong, they will try to pretend that nothing happened. Happily driving a car that is slowly falling
+as they are entering the highway.
+
+
+
+This is unacceptable behaviour in any professional environment with money at stakes. Well, at least for humans, but not for software apparently.
+
+BUT don't give up! Let me tell you: You and me, we are clever developers, we will not restrain from employing dark magic to squeeze Unity into something we can work with.
+
+> If your strategy was instead to switch to Unreal (what are you doing here??!), please let me know how it went in the comments. I might envy you :>
+
+# Why so series
+
+
+Hi! I'm Johannes. In my handful of years of fulltime Unity development at [SWCode](https://swcode.io), I have discovered one or two goodies, that I'm happy to share with you now. Maybe this stuff is widely known and my Google Fu is just not good enough. All I know is that I'm writing the blog posts I wish I had read when starting to developing real projects in Unity.
+
+> I can't be the only one thinking that Unity is horribly unreliable. I often wondered how all the professional studios deal with that, and my colleagues did too. In case you know, hit me up in the comment section!
+
+Why care about developer confidence? Sure, you're not crashing and airplance on a mountain if you introduce a bug. But sooner or later you might want to ship something. And at that point, you want to know if everything is okay, not one month later, when the shitstorm hits your face and negative reviews rain on your dream product. However, I'm not here to convince you that you should add more tedious Tests. I'm here to show you what else is possible, so that, if you want to, you too might gain the magic powers to shape your Unity workflow.
+
+How?
+
+The key strategy is to find problems sooner in the development workflow, instead of at the last possible moment. Why sooner? Well, if Jeff had been telling you about the corrupted email attachment last week, you could have sent him a dropbox link the same day. This reduces the time needed to code and manually test, it increases your confidence, and therefore speeds up the whole development process.
+
+Learning from statically typed languages, we will add checks that run while Unity is building your application. We will automate error prone manual processes. We will craft our own C#, with blackmagic and hooks! We will exploit Unity's feature of adding scripts to the Editor to make up for missing functionality, which is actually a very neat feature of Unity c:
+
+
+
+While I'm at it, let me dial back a bit on my rant. Don't let me shit on Unity for something we can easily add ouselves. Unity is an amazing piece of 21st century technology right at our hands! I just sometimes wish some minor features were there by default, so we wouldn't have to add them by hand.
+
+### Disclaimer
+I'm working in a rather unconventional project environment. For example, we embed a Unity View into an existing Android/iOS App. That's because we at [SWCode](https://swcode.io) build an app that uses AR, called [SoesTour](https://www.so-ist-soest.de/de/tourismus/sehenswertes/soestour.php). The app aims to revive historical sites that long vanished, by digitally showing them at their exact locations in the real world. Due to this complicated setup, I had to touch with some nasty Unity bits that most people might not have to touch. Also, I didn't touch a lot of the stuff that you might be using regularly! But don't worry, I won't jugde you for reading these articles only because of the Jeff stories.
+
+Oh my GOD JOHANNES STOP talking already! Let's get GOING!
+
+The Four Strategies
+-------------------
+
+0. [YOU ARE HERE] Introduction
+
+1. Make it your own, make it your home!
+
+ In addition to utilizing the boring old clean code strategies, we will add missing basic features to both Unity and C#. Everything else builds on those.
+
+2. Use code instead of assets (the controversial one)
+
+ We will use code to control Unity, generating and modifying assets, instead of manually editing them by hand.
+
+3. Smoothen the overall workflow (the one you might have expected)
+
+ Also we will automate clicking the clickies.
+ Seriously, let me press ONE button and then give me twenty minutes to pet my cat ... UHHHH work on something else.
+
+4. Perform rigorous checks at build time (the banger! also black magic)
+
+ This one is huge. We will make sure that you notice bad project files before waiting for the 20 minute long build process to complete.
+ I've not seen this one anywhere else yet, but I'm sure any serious developer MUST be doing that... right?
+
+These are rather large topics and I want to go into detail about them, so this will probably be more than one article. Goo look for a link at the end of this blogpost in case I forgot to go back here and edit this text before I click the juicy UPLOAD BUTTON! :D
+
+Within each topic, I will first describe the problematic situation that you too might have encountered in Unity. Afterwards I'll present my attempt at making it less horrible. I'll also try to share my experiences that I made after working with those solutions for quite some time. There will be code! Maybe a lot of it! Some will be controversial!
+
+## Find the Jeff
+
+In each post, I'll challenge you to find the hidden Jeff.
+To find him, you'll have to find the matching code section for that posts Jeff story. Take the first character of each heading where Jeff's code section appears. These four letters are the secret code.
+
+
+This introduction does not contain a Jeff.
+
+
+> Sorry if your name is Jeff, I had to choose a name. Visit me in Soest and the beer is on me!
+
+## A note on performance
+
+
+We're still not starting with the real content. Here's why:
+
+A recurring theme in this series will be performance. So let me get this straight, once, and link to this section a thousand times from those indivudal blog posts:
+
+- of course performance matters
+- but only in a fraction of the code
+- and developer time is more important
+- so use high-level abstractions first,
+- and optimize only where you've __measured__ a performance bottleneck
+
+We will use crazy Reflection and LINQ and write horribly inefficient code. That is, if you were to run it every frame unconditionally. But it's only used in tests, or once at initialization, or on build time. So get ready to unlearn those annoying foreach-loops and write better code in less time!
+
+All the time you save by choosing high-level abstractions, you gain for later optimization. It pays off. If this ever didn't work out for you, meet me outside, in the comment section.
+
+## The code is now.
+If there is one thing I hate more than badly designed software, it's blog posts that promise a wonderful world, but then never get to the point, leaving you all hyped up. That's why I personally made sure, for you specifically, that this blog posts has some real code in it, and you're not left with a hollow promise yet again: The first blog post of this series is already online!
+
+[Show me the code already!!1 Jesus...](TODO)
+
+Here you go, have fun! :)
diff --git a/_posts/2023-10-25-making-unity-a-decent-employee-1.md b/_posts/2023-10-25-making-unity-a-decent-employee-1.md
new file mode 100644
index 0000000..7cd1e35
--- /dev/null
+++ b/_posts/2023-10-25-making-unity-a-decent-employee-1.md
@@ -0,0 +1,1158 @@
+---
+layout: post
+title: "The Unity Engine is your worst coworker - Here's strategy #1 to improve it"
+date: 2023-10-25 10:30:00
+categories: unity
+tags: unity, csharp, workflow, testing, reliability
+# image: /assets/article_images/unity/worst-colleague.png
+author_name: Johannes Vollmer
+author_link: /authors/johannes-vollmer
+author_image: /assets/images/authors/johannes-vollmer/thumbnail.jpg
+published: false
+# target publish date: december
+---
+
+The sun creates beautiful orange patterns on your desk, as your project finally seems complete. Finally, it's done! Such a relief. Only one single thing to check:
+
+```md
+> You
+hi jeff, have you received
+the RX C# script i sent you?
+
+> Jeff
+yup
+
+> You
+does it work?
+
+> Jeff
+it was already in the project. in `scripts/rx.cs`
+
+> You
+nice. so it's the same script?
+
+> Jeff
+yes, it is the same script. no bugs
+
+> You
+alright, thansk :)
+```
+
+What a great friday. Time for a beer!
+The weekend passes like a breeze, and you're happy to present your progress on monday.
+
+On Sunday night, you open the project once again, just to feel the satisfaction again. But then you notice something weird... you realize something is horribly wrong! Fouriously, you open the chat in the glorios teams app.
+
+```md
+> You
+JEFF
+
+> You
+JEFF!!!!
+
+> Jeff
+what?
+
+> You
+JFEFF THE SCRIPT IS NOT THE SAME
+
+> Jeff
+the script is the same, look at `scripts/rx.cs`
+
+> You
+BUT IT'S NOT THE SAME CODE
+
+> Jeff
+of course it's not the same code
+
+> You
+WHAT?? I ASKED YOU ON FIRDAY
+YOU SAID ITS THE SAME!!!1
+
+> Jeff
+it's the same script file
+so i didn't check the code inside.
+you didn't tell me to compare each line in the file!!?
+
+> You have blocked 'Jeff (jefferson_magnotastic_x3000)'.
+> Unblock this person to see newer messages.
+```
+
+### WTjeFf?!
+
+You take a deep breath. Isn't that wonderful. What a bold move, Jeff.
+
+Think about it for a second: If your human colleague was doing what Unity does, you'd place a few pieces of raw fish and meat in their curtain poles and let it rot over months. Well, at least I would.
+
+Let's shift perspectives: What would you have done in Jeff's position?
+
+
+
+## Why are you like this, C#?
+Did you know? Pretty much all of the features that your favorite language recently added were already invented in the 70s, or even earlier.
+
+Yes, this includes C#: Records, Tuples, Non-Nullable, Pattern Matching, Immutability, Ranges. All of these concepts are multiple __centuries__ old.
+Unfortunately, now it's too late to glue those things on top of the outdated core. C# is only about 20 years old, but it still has [a lot of cruft from Java (and by extension from C)](https://eev.ee/blog/2016/12/01/lets-stop-copying-c/).
+
+LISP is one of the oldest programming languages, being 60 years old, yet it hat a lot of features. Some might say, it has __all__ the features. There is a saying that every programming language, adding more and more features, eventually converges into a (likely slightly buggy) version of Lisp. Or so. [Here's an inspiring read that might make you want to learn Lisp.](http://paulgraham.com/avg.html)
+
+But before we have a look at how and why to make C# a better Lisp, we gently start with some easy Unity code, for our comfort.
+
+# Why so series
+This blog post is part of a series: Making Unity a decent employee. Well, at least a little less horrible, I admit.
+
+These posts are largely independent. However, you should go read the [introduction here](TODO) if you haven't done that yet, and then come back. Otherwise, you might be thinking "wtf, why are we doing all of this again?" when reading the wonderfully ridiculous code sections later in this post.
+
+> Disclaimer: I'm working in a rather unconventional project environment. For example, we embed a Unity View into an existing Android/iOS App. That's because we at [SWCode](https://swcode.io) build an app that uses AR, called [SoesTour](https://www.so-ist-soest.de/de/tourismus/sehenswertes/soestour.php). The app aims to revive historical sites that long vanished, by digitally showing them at their exact locations in the real world. Due to this complicated setup, I had to touch with some nasty Unity bits that most people might not have to touch. I want this article to be generally applicable, so don't worry about it. It might be fun either way!
+
+Here's where we are at:
+
+The Four Strategies
+-------------------
+(Copied from Introduction)
+
+
+
+# Strategy I: Make it your own, make it your home!
+
+"Give me 6 hours to chop down a tree and I’ll spend the first four sharpening the axe." - [probably not Abrahalm Lincoln](https://www.velaction.com/sharpen-the-axe/).
+
+This article is the equivalent of choosing and sharpening the right axe for the job. Some might say it's boring, but without it, everything that follows will take a lot longer. We will explore some simple helpers to write and debug the real code faster.
+
+At the end of this blog post, you might almost feel like coding in a simpler C#, made just for your project. You should feel at home in your code.
+
+This code has been developed with a Clean Code mantra. At SWCode, we declare our Coding Bible be [Clean Code by Bob C. Martin](https://a.co/d/e3EVrb3). Even though I don't agree with every little detail, it's still a great book, and I recommend every coder to read it.
+
+#### Ye be warned
+
+This post contains a whole lot of code. I hope that's why you're here.
+While this code is used in production, it is by no means exhaustive, and will fail in other contexts. That's why I won't publish it as a library at this time. By only showing you snippets, I hope to inspire you to write your own helper code. You can copy and paste from this blog post, but you might have to insert some special cases for your project.
+
+Also, this article might contain some opinionated advice. Of course, you should use only what you find useful, as you see fit. If you think I'm absolutely wrong about something, quickly slash together a furious comment to explain why.
+
+In this post
+------------
+
+(All the Headlines of this post)
+
+## Raising the Level of Abstraction
+
+Working on a higher level allows you to make changes quickly. Move the code around like a sculptor moves clay. Change the large-scale behaviour without touching a single loop. Be the GOD in Age of Empires, not the little guy slamming a pile of rubbish with a hammer until it becomes a tower. Stay in control.
+
+To illustrate the techniques in this blog post, I'll start with an exemplary piece of code. After discussing all the techniques, we will rewrite the script on a higher level of abstraction.
+
+
+
+```cs
+
+```
+
+
+```cs
+
+```
+
+
+# Utilize the Type System
+
+The topic of your game is your "domain". But another domain you code in is the spatial world, so you should make it effortless to code. For example, add units for real world distances.
+
+- Add strongly typed measurement units such as Seconds or Metres
+- Add strongly typed paths instead of using string-based paths. I'll get to that later. It's fantastic, trust me.
+- Add stronlgy typed quantities such as Angles, so you never have to write `Mathf.Pi*2` ever again.
+
+Note: C# structs have no runtime overhead, so you can use them without any bad feelings, even in `Update` functions.
+
+__Have you ever written `(r/360)*Math.Pi*2`, even though Unity has `Mathf.Deg2Rad`?__
+Because you're using floats instead of a strongly typed `Angle` struct.
+If you were using
+
+
+### Extension Methods
+How often do you attempt to use an API in Unity and think: "Gosh, I wish there was just this one slightly different function instead of this mess!"? C# has a wonderuful feature called [extension methods](https://www.tutorialsteacher.com/csharp/csharp-extension-method), and they allow us to make this place our own. They don't even have any kind of performance overhead!
+
+Use Extension functions extensively. I mean it!
+We're going to take whatever Unity currently is, and make it be what we actually needed.
+Extend the LINQ, extend Unity, extend System.File, extend everything!!!1
+
+
+### Five Reasons to use Extension Methods
+
+### Top 20 Extension Methods in our Unity Project that have proven their value
+
+Let's start with some simple quality of life improvements. Some of them do as little as aliasing an existing function.
+You might disagree about the necessity of these helpers. I think they improve the code I write significantly, without a lot of effort, because it allows the code to read like prose and less like maths.
+
+#### Extension Methods can be Suggested by Your Editor
+There is another indispensable big advantage of extension function: They are easier to discover than static helper functions.
+For example `array.ToStringSeparated(", ")` will be suggested by your editor, whereas you will have to remember `string.Join(array, ", ")` manually before typing. And while typing, you don't have to go back to the start of the expression. Furthermore, appending a method call is much more flexible than surrounding your possibly complex expression with a static call.
+
+Extension methods allow us to use the dot-based notation, instead of having to remember which class they are implemented in.
+Why didn't they make these helpers an extension method in the first place?
+
+
+```cs
+// example usage:
+prefabPaths.Concat(scenePaths).ToStringSeparated("\n");
+linePointsArray.Fill(transform.position);
+
+if (this.audioFilePath.IsNullOrEmptySpace())
+ Debug.LogWarning("Annotation does not contain any audio.");
+
+if (gameObject.name.ExactlyEndsWith("%ß"))
+ Debug.Log("Found it!");
+
+// -- the extension method defined somewhere else --
+
+public static string ToStringSeparated(this IEnumerable items, string separator = ", ") =>
+ string.Join(separator, items);
+
+public static bool IsNullOrEmpty(this string value) =>
+ string.IsNullOrEmpty(value);
+
+public static bool IsNullOrEmptySpace(this string value) =>
+ string.IsNullOrWhiteSpace(value); // includes empty strings
+
+public static void Fill(this T [] array, T value) =>
+ Array.Fill(array, value);
+
+public static int IndexOf(this T [] array, T item) =>
+ Array.IndexOf(array, item);
+
+public static bool ExactlyEndsWith(this string value, string suffix) =>
+ // you don't want to spell this out every time, do you?
+ // ordinal is the only correct method for "programmer strings" if you want exact matches
+ // because you wouldn't want it to behave differently in japan or sweden
+ value.EndsWith(suffix, StringComparison.Ordinal);
+```
+
+
+#### Extension Methods can fix a badly named method
+The `GetDirectChildren` extension method has a rather clear meaning. In contrast, the implicit iteration over a transform object doesn't explain a lot of what it does.
+
+```cs
+// without extension method (the explicit variable type `Transform` is required for the C# compiler)
+foreach(Transform transform in gameObject.transform)
+ SceneTests.CheckGameObjectForMissingPrefabs(transform.gameObject);
+
+// with our method:
+gameObject.GetDirectChildren()
+ .ForEach(SceneTests.CheckGameObjectForMissingPrefabs);
+
+
+// -- the extension method defined somewhere else --
+
+public static IEnumerable GetDirectChildren(this Transform transform) =>
+ // the transform can enumerate all its direct children,
+ // but it implements IEnumerable