<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://coderchrismills.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://coderchrismills.github.io/" rel="alternate" type="text/html" /><updated>2025-09-03T03:35:43+00:00</updated><id>https://coderchrismills.github.io/feed.xml</id><title type="html">CoderChrisMills</title><subtitle>A place for me to write about UI/UX, game dev, and gardening among other things </subtitle><entry><title type="html">A Potential Future for Games</title><link href="https://coderchrismills.github.io/game-development/2024/06/25/future-of-game-development.html" rel="alternate" type="text/html" title="A Potential Future for Games" /><published>2024-06-25T18:01:00+00:00</published><updated>2024-06-25T18:01:00+00:00</updated><id>https://coderchrismills.github.io/game-development/2024/06/25/future-of-game-development</id><content type="html" xml:base="https://coderchrismills.github.io/game-development/2024/06/25/future-of-game-development.html"><![CDATA[<p>With the speed AI is being integrated into everything (for better and mostly worse), it feels like we’re seeing the start of the “meme-ification” of games. I don’t mean that all games will be trivially easy make, we’ll still have AAA titles, but that the gradient of games between between small and large budget them will be vast.</p>

<h2 id="meme-games">“Meme” Games</h2>

<p>On one end of the spectrum will be “meme” games. These games will be developed using AI tools in near real-time. I imagine in my lifetime that kids will be able to talk to their devices and riff on a silly game idea and see it come to life. Anyone with a phone or headset will be able to see the same thing and the experience will be shared. Much like when I was a kid we had to use our imagination to “see” the same made up world, kids soon will be able to use speech and multi-modal AI tools and conjure these worlds. These games will prioritize speed and creativity over quality. Topical to the moment, hyper sharable, these viral games will not last much longer than the time it took to build them.</p>

<h2 id="future-of-aaa">Future of AAA</h2>

<p>On the other end, blockbuster titles like Call of Duty and God of War will still exist. These games will require larger budgets than they currently do now to develop and market. With high development cost fewer of these games will be made, and as a result, fewer large studio will survive. AI will be used to streamline some of the production process (code / art) and will also be a part of the games themselves. Imagine an RPG that has a pre-trained model for character dialog. The way you interact with the NPCs will alter the story every play through. The NPCs will start to feel like other players, able to hold conversations with each other and you. Player expectation for content and richness of story at this level is going to be immense. Games will be boom or bust and this risk will lead to a reduction in AAA studio staff with external development partners filling the staffing gap. While this is somewhat true now, see credits for any AAA game, the scope of work these partners will be responsible for will make them indistinguishable from core team. Aside from benefits.</p>

<h2 id="decline-of-aa">Decline of AA</h2>

<p>Caught in the middle are AA games like Call of Cthulu or Sifu. These games are relatively high quality and fill a creative niche. I would argue that their creativity and departure from what tends to be either the safe bets or relying on purely a visual quality bar of a AAA game is what sets them apart, for now. The reason this segment will be in trouble is that the creative niche games will be rapid fire in the, and the games will be trained and tailored to the people playing them. It will be hard to compete on creativity and impossible to compete on budget.</p>

<p>For developers like myself, this future is uncertain and I struggle to see how it will allow me to make a living. Just as people make memes for fun, they will be making games for the same reason. No longer a career, but a hobby, the thing you do in your free time. Speed, creativity, and first to market will be what matters, not quality. As a friend of mine said when we were discussing this topic, “Getting someone to pay for your game will be like getting them to pay for poetry”. AAA studios can still allow for a development career, one that will be demanding, exceedingly high bar, and almost no way for entry level people to be a part of it.</p>

<h2 id="a-possible-exciting-future">A Possible Exciting Future</h2>

<p>All is not lost. The future for games and the creative explosion that will happen over the next decade is going to be exciting. Fueled by AR and AI technologies that will be everywhere. How we play games will be personal, sharable, interactive, and immensely creative. While I’m cautiously optimistic that games will be fine, the industry is going to evolve beyond recognition. So while the gaming landscape will see a dramatic change, the possibility for everyone to have the ability to share their game ideas has me hyped. Going from closed source game engine to Unity and Unreal, the barrier of entry continues to get lower. We’re soon going to see that barrier be non-existent.</p>]]></content><author><name></name></author><category term="Game-Development" /><summary type="html"><![CDATA[Some observations on where I think the industry is going]]></summary></entry><entry><title type="html">How to Make Better Decisions</title><link href="https://coderchrismills.github.io/lead-development/2023/02/02/how-to-make-better-decisions.html" rel="alternate" type="text/html" title="How to Make Better Decisions" /><published>2023-02-02T21:00:00+00:00</published><updated>2023-02-02T21:00:00+00:00</updated><id>https://coderchrismills.github.io/lead-development/2023/02/02/how-to-make-better-decisions</id><content type="html" xml:base="https://coderchrismills.github.io/lead-development/2023/02/02/how-to-make-better-decisions.html"><![CDATA[<h1 id="how-to-make-better-decisions">How to Make Better Decisions</h1>

<h2 id="intro">Intro</h2>

<p>There are a number of <a href="https://fs.blog/mental-models/">mental models</a> one can use to improve decision making such as an <a href="https://en.wikipedia.org/wiki/Time_management#The_Eisenhower_Method">Eisenhower Matrix</a>, or <a href="https://fs.blog/inversion/">Inversion</a>. To find one that works for you you’re going to need to iterate and try them out. There’s no one method that will work for everyone, and any method will need refinement to you as the individual. There is also no mental model that fits all situations. The following is an overview of a high level process, they key part is to not spend more time than is needed in making any decision.</p>

<h2 id="how-quick-can-you-make-a-decision">How Quick Can You Make a Decision</h2>

<p>Step one is to assess how much time I need to spend making the decision. Starting with a decision matrix with axis reversible vs scope of work you should be able to, with in a matter of seconds, assess this time.</p>

<p>Example 1: <em>Should we add a bug about a missing UI element?</em></p>

<p>This is a quick decision. Yes. There’s minimal work in adding the bug and worst case, we can simply close it out. Not adding the bug sends the signal that we care more about the noise in our bug tracker than we do the quality of the game.</p>

<p>Example 2: <em>Should we hire this person?</em></p>

<p>This decision is both not easily reversible and has a high scope of work. Lots of things kick into motion for the company and the individual after this decision is made. This is where you want to take some time, at least a full day to mull over your thinking.</p>

<p>Once you’ve assessed how much to put into the decision it’s time to start to digging into the details. What context am are you missing? Do you understand the impact?  Since you were unable to quickly make a decision in step one, it means there’s missing information. Whether it’s pen and paper or a text editor, it’s time to start clarifying your thinking outside of your head. You simply won’t be able to evaluate complex systems in isolation. Even if you could, documenting your thought process will help you refine it later, additionally, it allows you to look back at previous decisions to learn from them.</p>

<h2 id="example">Example</h2>

<p>Let’s run through a contrived example to see a potential decision process you might have.</p>

<p>It’s time to start the next version of your game and you know that during preproduction you need people who can excel in a fast decision making, rapid prototyping, highly collaborative environment. However, the people you know to be the best fit are supporting your live ops team.</p>

<ul>
  <li>Do you pull the live ops people and backfill?</li>
  <li>Do you have someone else start the new project with an assist from the live ops team?</li>
  <li>Do you have someone else start but with no help from live ops</li>
  <li>Something else?</li>
</ul>

<p>You start by inverting the question, rather than who should start the next version, you ask, who needs to support the live ops game, and what happens if they’re not there. When you ask this question you’re trying to identify gaps in your understanding of the impact of the decision.</p>

<p>With impact assessed you start to ideate and enumerate your options. To evaluate each option you make a quadrant diagram with Impact vs Effort and plot your options. The image below is a hypothetical Impact vs Effort matrix, where A-F are possible decisions you are evaluating.</p>

<p><a href="/assets/images/how-to-make-better-decisions/impact-vs-effort.jpg"><img src="/assets/images/how-to-make-better-decisions/impact-vs-effort-article.jpg" alt="Example of an impact vs effort matrix with options plotted as dots" /></a></p>

<p>To start, focus on the solutions that will have high positive impact and low effort. For instance, maybe you can redefine the scope of work on the live ops side to where it can be delegated to a trusted vendor. This frees up your live ops lead to begin focusing on the next game. Assuming the trust level with the vendor is sufficiently high and they’re already on the project, the effort to make the change might be low. 
For each option in the low effort, high impact category, began to think about the second and third order ramifications. In the example above, let’s say you pulled the vendor to take over live ops. What were they working on that’s no longer having effort put into it? What were they going to work on next? What’s the impact there? Was there dependancies in the work that are now going to become blockers? Maybe they aren’t able to get permissions to effectively support live ops. Or are unable to get equipment.</p>

<p>We might not be able to identify all the gaps in our initial assessment of a situation or solution, which is why we need to spend additional time evaluating how they play out. Once you have a few options you like, it’s time to run them by others. Never make decisions that will impact others in isolation. We all have blind spots and biases, working with others helps us identify them.</p>

<p>Now the last step. Pick one solution and live with the fallout.</p>

<h2 id="feedback-on-ideas">Feedback on Ideas</h2>

<p>In the example above, we saw the need to get feedback from others. This step happened towards the end, but it can, and should, happen multiple times throughout the decision making process. One method or eliciting feedback when wanting to effect change is called <a href="https://en.wikipedia.org/wiki/Nemawashi">Nemawashi</a>. Decisions affect change, they create branches, and Nemawashi is a great way informally gain new perspectives on these branches.</p>

<p>Another avenue for getting feedback is to discuss your situation with proposed solution and mitigation plans with someone who has been in a similar position, or is higher in the org than you. While it’s great to get their insights, keep in mind that the decision is ultimately up to you. If it wasn’t, you wouldn’t be the one making it. Don’t take their feedback blindly, make the decision and own the results.</p>

<p>There are times when you won’t be able to get feedback from others, say late night trying to finish a release build to QA, and you have to make an “executive” decision. But and “executive” decision is no different than any other. Going through a process, you have information that tells you why this is the best decision given the situation. And if you believe the decision is the right one by the project or company it’s the right one. You didn’t flip a coin, you thought critically about your choices. While it sounds flippant to say, if you are in an org that focuses on the outcomes of your decisions rather than your process, your growth will be limited.</p>

<h2 id="wrapping-up">Wrapping up</h2>

<p>This whole process may only take a few minutes or hours. For a big decision such as a new hire, maybe a full day. Remember, the time you spend in making the decisions is proportional to the impact of getting it wrong. Given that we’re in game dev, and no one’s life is on the line, try not to stress too much. Also, most of us are not at the executive level, our decisions have rather small chance of resulting in layoffs or the cancelation of a project. It’s hard for a single decision to have that level of impact, those results tend to be from a number of small decisions.</p>

<p>With all this there are two perils to be aware of: <a href="https://en.wikipedia.org/wiki/Decision_fatigue">decision fatigue</a> and <a href="https://en.wikipedia.org/wiki/Analysis_paralysis">analysis paralysis</a>. It’s easy to get wrapped up in wanting your decisions to be perfect, but don’t let perfect be the enemy of good. You will never make perfect decisions and it’s not a scorecard; number of “good” vs “bad” decisions. You will always make the best decision you could with the information you have at that time, with hindsight you will always be able to reason about a “better” decision. The point of a processes is to allow us to evaluate that information more effectively and over time refine our ability to make decisions with more confidence.</p>

<h2 id="further-reading">Further Reading</h2>

<ul>
  <li><a href="https://fs.blog/practical-ideas-better-decisions/">Practical Ideas Better Decisions</a></li>
  <li><a href="https://fs.blog/decision-anatomy/">Decision Anatomy</a></li>
  <li><a href="https://fs.blog/decision-matrix/">Decision Matrix</a></li>
  <li><a href="https://fs.blog/smart-decisions/">Smart Decisions</a></li>
  <li><a href="https://hbr.org/2022/03/how-to-make-great-decisions-quickly">How to Make Great Decisions Quickly</a></li>
  <li><a href="https://www.amazon.com/Importance-Small-Decisions-Simplicity-Technology/dp/0262039745">The Importance of Small Decisions</a></li>
  <li><a href="https://www.amazon.com/Good-Strategy-Bad-difference-matters/dp/1781256179/">Good Strategy Bad Strategy</a></li>
  <li><a href="https://www.amazon.com/Thinking-Fast-Slow-Daniel-Kahneman/dp/0374533555/">Thinking Fast and Slow</a></li>
</ul>]]></content><author><name></name></author><category term="Lead-Development" /><summary type="html"><![CDATA[A short article on decision making I wrote for someone I mentor at Pipeworks]]></summary></entry><entry><title type="html">Types of UI in Games</title><link href="https://coderchrismills.github.io/game-development/2022/10/16/types-of-ui-in-games.html" rel="alternate" type="text/html" title="Types of UI in Games" /><published>2022-10-16T21:00:00+00:00</published><updated>2022-10-16T21:00:00+00:00</updated><id>https://coderchrismills.github.io/game-development/2022/10/16/types-of-ui-in-games</id><content type="html" xml:base="https://coderchrismills.github.io/game-development/2022/10/16/types-of-ui-in-games.html"><![CDATA[<p>While continuing to learn the Unreal UI System I built a small demo illustrating the four main types of UI’s found in games.</p>

<p><img src="/assets/images/types-of-ui-in-games/types-of-ui-demo.png" alt="From left to right and example of non-diegetic, spatial, diegetic, and meta UI elements" /></p>

<ol>
  <li>Non-Diegetic</li>
  <li>Spatial</li>
  <li>Diegetic</li>
  <li>Meta</li>
</ol>

<p>If you’re looking for a more in depth description of each, check out <a href="https://codechangers.com/blog/video-game-ui-made-simple-with-case-studies/">Code Changers</a>.</p>

<h2 id="non-diegetic">Non-Diegetic</h2>

<p>For an example of non-diegetic UI I chose to implement a classic “health bar” and “energy bar”, these specifically were inspired by <a href="https://www.guerrilla-games.com/games">Forbidden West</a> which I happened to be playing at the time. The goal of this exercise was to learn how to use size boxes and horizontal / vertical boxes. I did’t build this in modular way. I wanted to go the quick route, focused more on building it versus building it right. Regardless, there were a few lessons learned.</p>

<p><img src="/assets/images/types-of-ui-in-games/non-diegetic-hierarchy.png" alt="Non-diegetic hierarchy in Unreal" /></p>

<p><strong>Lesson 1</strong>: Size boxes are great. Not just for overriding the width and height, but specifying desired size combined with aspect ratio makes them, pardon the pun, rather flexible. The majority of UI’s I’ve built over my career have all be based on specific pixel dimensions. The main utility of size boxes so far for me as been blocking out UI elements. Rather than using images. Size box + a Common Border set to Draw As box is a quick way to prototype layout.</p>

<p><strong>Lesson 2</strong>: Horizontal box and percentage based fills. Coming from iOS with horizontal and vertical stacks these behaved in a similar manner. If the box is set to fill, then each element will initially be greedy and attempt to fill the space. In each element you can specify a fill value (0-1) that specifies it’s preferred area to fill. For example, if you have 3 widgets all set to  1.0 for their fill, each will take 1/3 of the total area. If you set one of them to 0.25, you’re saying 0.25 of 0.33. While at first it’s not intuitive, once you’re used to it’s easy to work with.</p>

<p><strong>Lesson 3</strong>: My background in laying out UI elements has primarily come from iOS app development and web development. UMG’s layout system is rather intuitive if you share a similar background. I found <a href="https://joyrok.com/UMG-Layouts-Tips-and-Tricks">joyrok’s</a> site incredibly useful in the way they break down different widgets and their various tips. 100% worth a read.</p>

<h2 id="spatial">Spatial</h2>

<p>Spatial and diegetic only differ by the avatar’s perceptiveness of the widget. That is, if the avatar would be aware of it in the world. Unreal makes building these kind of UI element trivial.</p>

<p><img src="/assets/images/types-of-ui-in-games/spatial-hierarchy.png" alt="Unreal hierarchy of the spatial UI widget" /></p>

<p>Since implementing this UI was easy, and there wasn’t much to learn from it, I wanted to get it to <a href="https://www.youtube.com/watch?v=91-89b3wlSo">billboard</a> (see the first minute of this video for an explanation). Implementing this was actually easy and as straightforward as you’d expect. Get the position of the player, get the position of the UI widget, find the look at, set the rotation.</p>

<p><img src="/assets/images/types-of-ui-in-games/spatial-billboarding.png" alt="Spatial UI billboarding blueprint" /></p>

<h2 id="diegetic">Diegetic</h2>

<p>I always find diegetic UI interesting. The purpose of UI in games is to convey information in a readily available way. The health bar in a fighting game is prominent to the point you can see it in your periphery while focused on the fight. Diegetic UI however lives in world as is just as much a part of it as the player. So it needs to be clear that it’s a “UI” element, but still feel like it belongs in the world. The most recent game I’ve played that I think did this really well was <a href="https://stray.game/">Stray</a>. The use of wall art and neon signs to guild the player through the world was so well done that after you see the first couple you start to be on the look out for them.</p>

<p><img src="/assets/images/types-of-ui-in-games/diegetic-hierarchy.png" alt="Unreal hierarchy of the diegetic UI widget" /></p>

<h2 id="meta">Meta</h2>

<p>Meta UI’s are what you would see in an an old school JRPG when a character is talking to you. While setting up this UI is no different than setting up a non-diegetic UI, it’s context is what separates it from non-diegetic. Rather than simply implement another widget in screen space, I thought this would be a good time to learn how to create a render-to-texture in Unreal.</p>

<p><img src="/assets/images/types-of-ui-in-games/meta-hierarchy.png" alt="Unreal hierarchy of the meta UI widget" /></p>

<p>A render-to-texture needs two things: a camera to do the capture and a target to render the capture to. In Unreal you can set this up by doing the following:</p>

<ol>
  <li>A camera that will be used for the capture, in Unreal this would be a SceneCaptureComponent</li>
  <li>Create a RenderTarget asset</li>
  <li>Set your SceneCaptureComponent render target to the RenderTarget asset in step 2.</li>
  <li>Right click on the RenderTarget and choose “Create Material”</li>
</ol>

<p>After that you’ll have a material that you can use in your UI or anywhere else.</p>

<h2 id="wrapping-up">Wrapping Up</h2>

<p>I hope you found some of this useful and informative. Building  small examples / demos helps reinforce what you know and what you don’t know. They’re a good way to slow build competency in a given area. Next time you’re playing a game see if you can identify these types of UIs.</p>]]></content><author><name></name></author><category term="Game-Development" /><summary type="html"><![CDATA[Continuing to learn Common UI I go over the four UI types often seen in games]]></summary></entry><entry><title type="html">Intersection Testing UI Demo</title><link href="https://coderchrismills.github.io/game-development/2022/10/11/intersection-testing-ui-demo.html" rel="alternate" type="text/html" title="Intersection Testing UI Demo" /><published>2022-10-11T21:00:00+00:00</published><updated>2022-10-11T21:00:00+00:00</updated><id>https://coderchrismills.github.io/game-development/2022/10/11/intersection-testing-ui-demo</id><content type="html" xml:base="https://coderchrismills.github.io/game-development/2022/10/11/intersection-testing-ui-demo.html"><![CDATA[<h1 id="intersection-testing-ui-demo">Intersection Testing UI Demo</h1>

<p>In a <a href="/game-development/2022/07/31/intersection-testing-demo.html">previous post</a> on intersection testing I describe a UI widget that would always point to an element on a map. It was a long weekend for Pipeworks (Indigenous People’s day here in the U.S.) so I decided to spend some time in Unreal and implement a rough version. Source is available on <a href="https://github.com/coderchrismills/CommonUIPlayground">Github</a>.</p>

<p><img src="/assets/images/intersection-testing-ui-demo/unreal-map-ui-marker.png" alt="Imaging showing map marker with points marked for intersection" /></p>

<p>In the screenshot above we take the mid point of the “map marker” (green box) and project it onto the right side of our “info box”, intersecting at point PP (projected point). The way dragging and dropping is implemented in Unreal I found it best to work was with the absolute coordinate values of the “info” view and the “map marker” view. The marker is a a part of the map hierarchy, where as the info box is a completely separate entity in the viewport.</p>]]></content><author><name></name></author><category term="Game-Development" /><summary type="html"><![CDATA[Implementing a small UI widget from a previous post]]></summary></entry><entry><title type="html">Unreal Common UI Loses Parent Class</title><link href="https://coderchrismills.github.io/game-development/2022/10/03/unreal-common-ui-loses-parent-class.html" rel="alternate" type="text/html" title="Unreal Common UI Loses Parent Class" /><published>2022-10-03T21:00:00+00:00</published><updated>2022-10-03T21:00:00+00:00</updated><id>https://coderchrismills.github.io/game-development/2022/10/03/unreal-common-ui-loses-parent-class</id><content type="html" xml:base="https://coderchrismills.github.io/game-development/2022/10/03/unreal-common-ui-loses-parent-class.html"><![CDATA[<p>Recently I’ve been enjoying learning more about <a href="https://docs.unrealengine.com/5.0/en-US/common-ui-plugin-for-advanced-user-interfaces-in-unreal-engine/">Common UI</a>, the new-ish Unreal UI system that’s used in Fortnite. The new widgets, input system, and navigation make it easy to quickly put together <a href="https://dev.epicgames.com/community/learning/tutorials/BKJ7/unreal-engine-common-ui-tutorial-create-cross-platform-ui-easily-with-this-new-ue5-system">menu flows</a>. However, every now and then in my C++ based projects Blueprint classes keep losing their parent class. The end result is that when I open my uproject all the <code class="language-plaintext highlighter-rouge">CommonUI.CommmonActivatableWidget</code>’s are corrupted. The Blueprint’s themselves no longer able to be opened. Entire UI, broken. 😭</p>

<p>I was nearing a breaking point this weekend, contemplating going back to UMG when I stumbled across this <a href="https://forums.unrealengine.com/t/blueprint-keeps-losing-parent/538652">forum</a> post. In the <code class="language-plaintext highlighter-rouge">Blueprint Keeps Losing Parent</code> post, which was unrelated to Common UI, the group comes to the conclusion that the bug is a side effect of the Live Coding feature introduced in UE 4.22. In other side projects I have Live Coding disabled as it’s caused a number of frustrating issues when opening the editor. For instance working on my <a href="https://github.com/coderchrismills/UnrealPlayground">intersection testing</a> demo, actors like <code class="language-plaintext highlighter-rouge">NearestPointToLineActor</code> would fail to load and would result in a broken Level file. Since then I’ve been disabling it, but forgot to do so in my Common UI playgrounds. Disabling Live Coding as “fixed” my issue. I just need to make sure run through Visual Studio rather than launching through the Epic Launcher. If you really need Live Coding enabled and you run into this, here’s a “quick” way to fix things up.</p>

<ol>
  <li>Hope you’re using source control or have a backup</li>
  <li>Close the editor</li>
  <li>Delete corrupted blueprints</li>
  <li>Rebuild from Visual Studio</li>
  <li>Open the editor or launch from VS</li>
  <li>Force sync / replace corrupted blueprints from backup while the editor is open</li>
</ol>

<p>The only annoyance I’ve run into with this workaround is that I had to manually fix up any Blueprints that had a <code class="language-plaintext highlighter-rouge">Create Widget</code> node as the out value from them was broken.</p>]]></content><author><name></name></author><category term="Game-Development" /><summary type="html"><![CDATA[How to work around an issue with Common UI Blueprints losing their parent class in a C++ based project]]></summary></entry><entry><title type="html">Sharing is Caring</title><link href="https://coderchrismills.github.io/game-development/2022/08/16/sharing-is-caring.html" rel="alternate" type="text/html" title="Sharing is Caring" /><published>2022-08-16T21:00:00+00:00</published><updated>2022-08-16T21:00:00+00:00</updated><id>https://coderchrismills.github.io/game-development/2022/08/16/sharing-is-caring</id><content type="html" xml:base="https://coderchrismills.github.io/game-development/2022/08/16/sharing-is-caring.html"><![CDATA[<h1 id="sharing-is-caring">Sharing is Caring</h1>

<p>I love Elden Ring. For me the best part about the game isn’t FromSoftware’s design around crushing difficulty, but their other skill; story telling. The lore of Elden Ring spreads out like a web. To get a “clear” picture you have to find bits of lore in weapon descriptions, side quests, and boss dialog. The only issue with all this is 1, Elden Ring is massive and you’ll need to scour every nook and cranny of the map, and 2, you have to progress in the game. Elden Ring has a wonderful story and it’s a bit of a shame it’s guarded behind the difficulty.</p>

<p>Let’s imagine a world where more people get to experience this game. Where sharing of lore is put in front of the difficulty, priority-wise. Let’s look at just a few features that would get us closer to the Elden Ring of my dreams.</p>

<ul>
  <li>No damage</li>
  <li>No falling</li>
  <li>Shaders</li>
  <li>Controller remapping</li>
</ul>

<h2 id="no-damage">No Damage</h2>

<p>One of the cool, but sometimes overwhelming things about Elden Ring is its use of vertical space. Dungeons nestled into cliff sides, castles and dungeons where there may or may not be something under a lift, etc. For example, there’s a spot in Caelid where a cave entrance is along a cliff wall.</p>

<p><a href="/assets/images/sharing-is-caring/caelid-enemies.jpg"><img src="/assets/images/sharing-is-caring/caelid-enemies-article.jpg" alt="Caelid abandon cave approach - Enemies" /></a></p>

<p>When trying to approach the branch you’re probably going to be attacked by the Abductor that’s nearby. The narrow catwalk is easy to fall off and there’s nothing worse than being chased while trying to navigate these branches. So it would be great if you could clear this enemy out first. These enemies are pretty notorious, especially at lower levels and there’s a couple of giant dogs around that can get aggro’d while you engage with the Abductor. I think this setup is intentional with respect to design. You have to choose, move quickly / sneak across the branches or fight the enemies. This creates tension for the player, but sometimes you’d rather just explore. These risk reward moments are a big part of FromSoftware games and I’m not saying they shouldn’t exist, just it would be nice to not have to deal with them once in a while.</p>

<h2 id="no-falling">No Falling</h2>

<p><a href="/assets/images/sharing-is-caring/narrow-paths.jpg"><img src="/assets/images/sharing-is-caring/narrow-paths-article.jpg" alt="Highlighting the path the user takes to the Abandon Cave" /></a></p>

<p>Speaking of that Caelid Abandoned Cave…the approach. I have fallen off these branches more times than I really care for. Whether it’s my own ineptitude, disagreements with Torrent, or what I would consider odd collision pushback, it’s happened a lot. Another example of the risk / reward design mechanics of FromSoftware’s games. Do you risk falling off the narrow walkway and redoing all the things it took to get there, or skip the area? I’m all for practice makes perfect, but we’re talking about exploration. We’re not training, we’re trying to take a stroll around the lovely park that is Caelid. Having the option to not inadvertently fall to your death would be great. Because of the use of vertical space we still need to be able to fall, but the game could have an option that prevents the user from falling to their death.</p>

<h2 id="shaders">Shaders</h2>

<p>In the <a href="#no-damage">No Damage</a> section above, can you spot all three enemies? Maybe you can without issue, but for me, the Abductor in particular blends into the environment. Let’s imagine an option that allows us to toggle a shader that highlights certain aspects on the environment.</p>

<p><a href="/assets/images/sharing-is-caring/caelid-hero-shader.jpg"><img src="/assets/images/sharing-is-caring/caelid-hero-shader-article.jpg" alt="Highlighting three enemies with with a simulated shader" /></a></p>

<p>This is simulated with Photoshop, but the enemies now pop from the background. Not only are we highlighting the enemies, but we’re desaturating to increase contrast. We don’t have to stop at just enemies either, we can also highlight resources or pickups.</p>

<p><a href="/assets/images/sharing-is-caring/albinaurics-article.jpg"><img src="/assets/images/sharing-is-caring/albinaurics-article.jpg" alt="Highlighting the albinaurics near Mogwyn Dynasty Palace" /></a></p>

<p>So how does this help us with our goal of experiencing the story of Elden Ring more easily? Well, if we can’t see the enemies, every attack from them is a surprise attack. Constantly being jumped is no fun and it creates apprehension for us during exploration. Ultimately, we are looking for ways to mitigate the risk of dying for the reward of exploration and lore. We want to incentivize the player to explore more and provide settings to allow them to do that. Difficulty here is adjustable and it’s opt-outable for the player.</p>

<h2 id="controller-remapping">Controller Remapping</h2>

<p>Ok, last feature we’re going to consider today, controller remapping. Since I play on console, I’m using a controller, not keyboard and mouse. This causes a good amount of hand fatigue and a requirement for some dexterity. As I’ve gotten older the number of basketball hand injuries have made holding buttons in certain configurations difficult. Elden Ring does have some controller remapping, but it’s rather limited.</p>

<p>My play style is usually on melee builds and I rarely use magic. One of my favorite weapons in the game is Moonveil, which has a great weapon art call <a href="https://www.youtube.com/watch?v=VasoZC6Ez-g">Transient Moonlight</a>. While I love using this weapon, to perform Transient Moonlight requires that I hold L2, then press R2 within a given window of time. If you press R2 too soon you do a move that leaves you open to counter attacks. If you press the buttons too close together you sheath your sword. In an ideal world I wouldn’t have to worry about this and I could assign Transient Moonlight to say the up button on the d-pad. That button defaults to Sorcery which I never use. There’s no option to assign a single button to weapon arts. Skills can be assigned, and in fact they’re defaulted to L2, but some weapon arts require more than one press to execute. Another option would be to allow the player to assign double tap of buttons to perform the action. This doesn’t work for everyone, as tap windows can be challenging for some.</p>

<p>So what does this have to do with exploration? Well, the more extensible we make our button assignments the more we give the player the power to customize their experience. For example, if we’re able to assign actions to buttons maybe we could assign the action of jumping off Torrent to a single button and make it separate from calmly dismounting. While small, the ability to control Torrent a bit easier makes a huge difference when exploring. On more than one occasion I found myself mashing at the buttons trying to remember how to get off my magical pony. In an effort to make exploring more pleasant, using Torrent should be a delight.</p>

<h2 id="dark-souls-1">Dark Souls 1</h2>

<p>When I played Dark Souls for the first time I had similar experiences. I wanted more, but I didn’t want to deal with the difficulty. I just wanted to explore the world and have fun. I found Cheat Engine and decided to play Dark Souls on PC just so I could use it. It was great. I couldn’t die, except falling, and I could specify which weapon I wanted to play with. All of a sudden every side quest, area and weapon become open to me. All of the lore or connection between NPCs became tangible. The world of Dark Souls became richer because I “cheated”. That’s the intent with all that I’ve written above about Elden Ring. I understand I could play it on PC (PS 5 at the moment), but the point here is that every user could have the chance to experience the game in their own way.</p>

<h2 id="accessibility-is-for-everyone">Accessibility is for Everyone</h2>

<p>Lately, these types of features have been placed under accessibility. See <a href="https://www.gameuidatabase.com/gameData.php?id=664">The Last of Us Part II</a> and <a href="https://www.sie.com/en/blog/inside-the-accessibility-features-of-ratchet-clank-rift-apart/">Ratchet and Clank</a> as recent examples. Seeing how many accessibility features these two games have is inspiring. As an industry I feel we have a long way to go with respect to accessibility, but these are good steps forward. But the best thing about accessibility features is that they’re not just for people with needs, they can help everyone. These features can be optional and opt-in, as long as anyone can change them at any time. No one is forcing the person who wants to play Elden Ring at its current difficulty to play with any of the settings I’ve described. What I’m advocating for is adding options to make the game more open and accessible to everyone. By doing so we can share our stories with more people. We can create shared experiences and bring others into the conversation.</p>

<p>If this is something that interests you, take a look at Ratchet and Clank and also the <a href="https://accessible.games/accessible-player-experiences/">ABX patterns</a> from <a href="https://ablegamers.org">ablegamers</a>. If you’re in the UK, check out <a href="https://www.specialeffect.org.uk">Special Effect</a> as a local charity. Both organizations do amazing things and are worth a look.</p>]]></content><author><name></name></author><category term="Game-Development" /><summary type="html"><![CDATA[Games are experiences to share]]></summary></entry><entry><title type="html">Yet Another Boids Post</title><link href="https://coderchrismills.github.io/game-development/2022/08/06/yet-another-boids-post.html" rel="alternate" type="text/html" title="Yet Another Boids Post" /><published>2022-08-06T21:00:00+00:00</published><updated>2022-08-06T21:00:00+00:00</updated><id>https://coderchrismills.github.io/game-development/2022/08/06/yet-another-boids-post</id><content type="html" xml:base="https://coderchrismills.github.io/game-development/2022/08/06/yet-another-boids-post.html"><![CDATA[<h1 id="yet-another-boids-post">Yet Another Boids Post</h1>

<p>It’s been a long time since I’ve implemented <a href="https://en.wikipedia.org/wiki/Boids">boids</a> and I wouldn’t be writing this post if it wasn’t for a work prompt from work slack a few weeks ago.</p>

<blockquote>
  <p>Implement flocking behavior in the engine of your choice, and post your source code and/or a video of your results under this thread.
If you’re not sure what flocking is, <a href="https://www.youtube.com/watch?v=mjKINQigAE4">https://www.youtube.com/watch?v=mjKINQigAE4</a> is pretty good basic tutorial.</p>
</blockquote>

<p>Having not written code in awhile this seemed like a nice small and directed thing to do over a weekend. On top of that it would give me a topic to write about and I could use it to learn a bit more Unreal. Side comment about writing. Writing is a great way to help you clarify your thinking and understanding of problems. Even if you don’t have a blog or feel like posting anything online, write. In my post about <a href="/game-development/2022/07/31/intersection-testing-demo.html">intersection testing</a> there were a few times that I had to stop and rederive something, or check my math. For me these types of post help me verify my understanding of the material. So if you find this topic interesting, go and implement it, then write about it.</p>

<p>If you want to see boids in action and love interactive sites, go check out <a href="https://eater.net/boids">Ben Eater’s</a><sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>, I’m going to reference this page a few times during this post. Play around with the sliders on the page to get a sense of what each parameter does. Afterward, before reading the rest of his article or the rest of this one, think about how you might implement the behavior.</p>

<p>Boids steer by following three simple rules:</p>

<p>Separation: Steer to avoid local crowding</p>

<p><a href="/assets/images/yet-another-boids-post/separation.jpg"><img src="/assets/images/yet-another-boids-post/separation-256.jpg" alt="Example of separation with an arrow indicating direction away from neighbor boids" /></a></p>

<p>Cohesion: Steer towards local average position</p>

<p><a href="/assets/images/yet-another-boids-post/cohesion.jpg"><img src="/assets/images/yet-another-boids-post/cohesion-256.jpg" alt="Example of cohesion with an arrow indicating direction towards average position of neighbor boids" /></a></p>

<p>Alignment: Steer towards local facing direction</p>

<p><a href="/assets/images/yet-another-boids-post/alignment.jpg"><img src="/assets/images/yet-another-boids-post/alignment-256.jpg" alt="Example of alignment with facing vector of boid aligning towards neighbor boids" /></a></p>

<p>Local here just means an individual boids perception of its flockmates (neighbors), black circle in the images above. Each boid has a radius and angle of perception. In Ben Eater’s post, you can see the effect of the radius of perception by changing the visual range. Shrinking the field of view (angle of perception) will also reduce the neighborhood of flockmates.</p>

<p>For each boid to know who its neighbors are it either needs access to the flock to filter from or is given a list of neighbors that are within some distance metrics and in its field of view, so pre-filtered.</p>

<p><a href="/assets/images/yet-another-boids-post/field-of-view.jpg"><img src="/assets/images/yet-another-boids-post/field-of-view-256.jpg" alt="Example of reducing the field of view and the filtering out of neighbors" /></a></p>

<p><a href="/assets/images/yet-another-boids-post/radius-of-view.jpg"><img src="/assets/images/yet-another-boids-post/radius-of-view-256.jpg" alt="Example of increasing the radius of perception to increase the number of neighbors" /></a></p>

<p>Putting this all together,</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>w1 = weight of separation
w2 = weight of cohesion 
w3 = weight of alignment

for each boid in our list of neighbors
    v1 = compute the sum of difference vectors between the boid and each neighbor (separation)
	v2 = find the center of mass of neighbors, compute the vector from boid to that position (cohesion)
	v3 = compute the average facing angle of all neighbors (alignment)
	boid velocity = boid velocity + w1*v1 + w2*v2 + w3*v3
	boid position = boid position + boid velocity
</code></pre></div></div>

<p>Few things that tripped me up when reimplementing this system. First, limiting the amount of force applied each frame can be helpful not only for debugging, but for keeping the system from spinning out of control. Second, which seems obvious in hindsight is how important alignment is. On Ben’s page, set coherence to its max value, but set separation and alignment to zero. After the simulation settles set alignment to max too. All the boids should rapidly coalesce into what will look like a single boid. Ok, last thing. Set alignment back to zero. Pretty quickly they’ll start to diverge. They won’t completely diverge, but there will be a bit more divergence of the flock. All this is without separation being considered. I like to think of alignment as how “chaotic” do I want the system to appear.</p>

<p>When I was implementing this I had the coefficient of cohesion being used for alignment. On Ben’s page put separation at the mid point and cohesion at 0. Then mess around with alignment. When it’s at the max you get this really nice follow the leader school of fish. They act a bit odd, trying to keep in perfect alignment, but it’s nice. When alignment is at zero it’s just chaos. In my system with this bug, I was so focused that there was a problem with the separation code as they seemed to constantly trying to get away from each other. After I verified separation was fine, or at least should be, I then looked at the field of view filtering. This lead me to implementing more debug visualization that ended up being rather helpful throughout the implementation. Though it was nice to have the debug helpers, what I really needed to do was to stop. If I would have paused for a few minutes and thought about how the system was reacting to changes it would have been clear alignment was the culprit.</p>

<p>Debugging starts with understanding the systems we’re working in and how they respond to change. The code I write for work is thought through, mainly because I’m more aware about the time investment. But I have a blind spot for the code I write at home where the value of time is not on my mind. Typically it’s the weekend and I’m exploring intellectual curiosities. My good programming practices at work sometimes don’t make their way home; they’re practices and not habits.</p>

<p>Welp, that’s it. Boids are beautiful. From these three simple steering rules you can get this wonderful and dynamic motion. They’re are super approachable and very extendable. They also make a great introduction into steering behaviors and it’s just really satisfying when you start to see them move in a perceived orderly fashion. The most complicated math in the whole things is filtering based on the the field of view. If you understand the basics of vector math there’s and think this would be fun to implement, check out <a href="http://www.kfish.org/boids/pseudocode.html">kfish’s</a> pseudocode page. There’s some fun ways to extend the system such as goal setting and object avoidance. Also, if you want to read the original paper, see <a href="https://www.red3d.com/cwr/boids/">Craig Reynolds’</a> page.</p>

<p><em>Title comes from the fact that there are already a <a href="https://www.google.com/search?q=boids">number</a> of pages on the topic</em></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>The site is great all around and strongly suggest checking it out <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="Game-Development" /><summary type="html"><![CDATA[A quick post about what I learned implementing boids after many years]]></summary></entry><entry><title type="html">Intersection Testing Demo</title><link href="https://coderchrismills.github.io/game-development/2022/07/31/intersection-testing-demo.html" rel="alternate" type="text/html" title="Intersection Testing Demo" /><published>2022-07-31T21:00:00+00:00</published><updated>2022-07-31T21:00:00+00:00</updated><id>https://coderchrismills.github.io/game-development/2022/07/31/intersection-testing-demo</id><content type="html" xml:base="https://coderchrismills.github.io/game-development/2022/07/31/intersection-testing-demo.html"><![CDATA[<h1 id="intersection-testing">Intersection Testing</h1>

<p>Let’s make a game! Well, parts of a game that we can use to illustrate intersection testing in 2 and 3-space. We have an action RPG that has the following elements:</p>

<ol>
  <li>A UI element that points to an area of interest on a map</li>
  <li>A spell pierces a target causing an effect to spawn at point of contact and point of exit</li>
  <li>A summon that causes a meteor to hit the planet, like you’d see in an RPG maybe</li>
</ol>

<p>Now that we have our three hypothetical situations, let’s break down each one to show where we might use intersection testing to help us implement them.</p>

<h2 id="ui-element">UI Element</h2>

<p>Imagine our UI element looks like this,</p>

<p><img src="/assets/images/intersection-testing-demo/map.jpg" alt="A box on the left simulating a user interface menu and a box to the right indicating a marker on a map. A right triangle is drawn over the top connecting the top right menu corner and center of the marker" /></p>

<p>The goal here is to find a point <code class="language-plaintext highlighter-rouge">q</code> on the left edge that’s nearest to our point on the map. In the image above we can see this point as the intersection of <code class="language-plaintext highlighter-rouge">st</code> with the line perpendicular or normal to <code class="language-plaintext highlighter-rouge">st</code> starting at <code class="language-plaintext highlighter-rouge">p</code>.</p>

<p>Another way to look at what we’re trying to do is we’d like to project our map point onto the edge of the UI widget and see if it’s on the line and to the left. We’re not going to really cover the “to the left bit”. Exercise for the reader? OK, time for math! There’s lots of ways to approach this problem, but hopefully this approach will help you build some intuition for the rest of the post.</p>

<p>To start, we will be using the <a href="https://en.wikipedia.org/wiki/Dot_product">dot product</a> for this.</p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="right left">
            <mtr>
                <mtd>
                    <mi>a</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mo form="prefix" stretchy="false">[</mo>
                    <msub><mi>a</mi><mn>1</mn></msub>
                    <mo separator="true">,</mo>
                    <msub><mi>a</mi><mn>2</mn></msub>
                    <mo separator="true">,</mo>
                    <mo>&#x22ef;</mo>
                    <mo separator="true">,</mo>
                    <msub><mi>a</mi><mi>n</mi></msub>
                    <mo form="postfix" stretchy="false">]</mo>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>b</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mo form="prefix" stretchy="false">[</mo>
                    <msub><mi>b</mi><mn>1</mn></msub>
                    <mo separator="true">,</mo>
                    <msub><mi>b</mi><mn>2</mn></msub>
                    <mo separator="true">,</mo>
                    <mo>&#x22ef;</mo>
                    <mo separator="true">,</mo>
                    <msub><mi>b</mi><mi>n</mi></msub>
                    <mo form="postfix" stretchy="false">]</mo>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>a</mi><mo>&#xB7;</mo><mi>b</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <munderover>
                        <mo movablelimits="false">∑</mo>
                        <mrow><mi>i</mi><mo>=</mo><mn>1</mn></mrow>
                        <mi>n</mi>
                    </munderover>
                    <msub><mi>a</mi><mn>1</mn></msub>
                    <mo>&#x2062;</mo>
                    <msub><mi>b</mi><mn>1</mn></msub>
                    <mo>+</mo>
                    <msub><mi>a</mi><mn>2</mn></msub>
                    <mo>&#x2062;</mo>
                    <msub><mi>b</mi><mn>2</mn></msub>
                    <mo>+</mo>
                    <mo>&#x22ef;</mo>
                    <mo>+</mo>
                    <msub><mi>a</mi><mi>n</mi></msub>
                    <mo>&#x2062;</mo>
                    <msub><mi>b</mi><mi>n</mi></msub>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>a</mi><mo>&#xB7;</mo><mi>b</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mi>&#x2225;</mi><mi>a</mi><mi>&#x2225;</mi>
                    <mo>&#x2062;</mo>
                    <mi>&#x2225;</mi><mi>b</mi><mi>&#x2225;</mi>
                    <mo>&#x2062;</mo>
                    <mspace width="0.1667em"></mspace>
                    <mi>cos</mi>
                    <mo>&#x2061;</mo>
                    <mi>&#x3b8;</mi>
                </mtd>
            </mtr>
        </mtable>
    </math>
</div>
<p />

<p>With the dot product defined, let’s look again at the diagram above and see how we can use it to solve our problem.</p>

<p>Since we don’t know theta let’s use the algebraic definition of the dot product, and as an aside if you’re using a math library of some sort it’s more than likely built in. Ok, so our target point <code class="language-plaintext highlighter-rouge">q</code> is a point from <code class="language-plaintext highlighter-rouge">s</code> in the direction of <code class="language-plaintext highlighter-rouge">st</code> of length <code class="language-plaintext highlighter-rouge">l</code>. So what is the length <code class="language-plaintext highlighter-rouge">l</code>?</p>

<p>Looking at our first case where <code class="language-plaintext highlighter-rouge">p</code> is between <code class="language-plaintext highlighter-rouge">s</code> and <code class="language-plaintext highlighter-rouge">t</code>, <code class="language-plaintext highlighter-rouge">l</code> is one of the sides of the right triangle formed by the three points <code class="language-plaintext highlighter-rouge">s</code>, <code class="language-plaintext highlighter-rouge">p</code>, and <code class="language-plaintext highlighter-rouge">q</code>. So if we can find the proportion along the line where the line normal to <code class="language-plaintext highlighter-rouge">st</code> and <code class="language-plaintext highlighter-rouge">p</code> intersect we’ll have q. This leads us to the dot product as projection.</p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="right left">
            <mtr>
                <mtd>
                    <mi>st</mi>
                </mtd>
                <mtd>
                    <mo>=</mo><mi>w</mi>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>sp</mi>
                </mtd>
                <mtd>
                    <mo>=</mo><mi>v</mi>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>v</mi><mo>
                    <mo>&#xB7;</mo>
                    </mo><mi>w</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mi>&#x2225;</mi><mi>v</mi><mi>&#x2225;</mi>
                    <mo>&#x2062;</mo>
                    <mi>&#x2225;</mi><mi>w</mi><mi>&#x2225;</mi>
                    <mo>&#x2062;</mo>
                    <mspace width="0.1667em"></mspace>
                    <mi>cos</mi>
                    <mo>&#x2061;</mo>
                    <mi>&#x3b8;</mi>
                </mtd>
            </mtr>
        </mtable>
    </math>
</div>

<p />

<p>
Projection of V onto W
</p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="left">
            <mtr>
              <mtd>
                <mo>=</mo>
                <mstyle displaystyle="true"> 
                    <mfrac>
                      <mrow>
                        <mi>v</mi>
                        <mo>&#xB7;</mo>
                        <mi>w</mi>
                      </mrow>
                      <mrow>
                        <mi>&#x2225;</mi><mi>w</mi>
                        <msup>
                          <mi>&#x2225;</mi>
                          <mn>2</mn>
                        </msup>
                      </mrow>
                    </mfrac>
                </mstyle>
                <mo>&#x2062;</mo>
                <mi>&#x1D430;</mi>
              </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mo>=</mo>
                    <mstyle displaystyle="true"> 
                        <mfrac>
                          <mrow>
                            <mi>&#x2225;</mi><mi>v</mi><mi>&#x2225;</mi>
                            <mo>&#x2062;</mo>
                            <mi>&#x2225;</mi><mi>w</mi><mi>&#x2225;</mi>
                            <mo>&#x2062;</mo>
                            <mspace width="0.1667em"></mspace>
                            <mi>cos</mi>
                            <mo>&#x2061;</mo>
                            <mi>&#x3b8;</mi>
                          </mrow>
                          <mrow>
                            <mi>&#x2225;</mi>
                            <mi>w</mi>
                            <msup>
                              <mi>&#x2225;</mi>
                              <mn>2</mn>
                            </msup>
                          </mrow>
                        </mfrac>
                    </mstyle>
                    <mo>&#x2062;</mo>
                    <mi>&#x1D430;</mi>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mo>=</mo>
                    <mstyle displaystyle="true"> 
                        <mfrac>
                          <mrow>
                            <mi>&#x2225;</mi><mi>v</mi><mi>&#x2225;</mi>
                          </mrow>
                          <mrow>
                            <mi>&#x2225;</mi><mi>w</mi><mi>&#x2225;</mi>
                          </mrow>
                        </mfrac>
                    </mstyle>
                    <mo>&#x2062;</mo>
                    <mspace width="0.1667em"></mspace>
                    <mi>cos</mi>
                    <mo>&#x2061;</mo>
                    <mi>&#x3b8;</mi>
                    <mi>&#x1D430;</mi>
                </mtd>
            </mtr>
        </mtable>
    </math>
</div>

<p />

<p>The above defines the projection equations, but take a moment to think through some things. When is the dot product less than zero? When is the dot product zero? In each case, what would that projection look like? How might we tell when the map point is below <code class="language-plaintext highlighter-rouge">t</code>? From these equations we can see here that the resultant vector formed from <code class="language-plaintext highlighter-rouge">s</code> to <code class="language-plaintext highlighter-rouge">q</code> is a vector that a proportional length of <code class="language-plaintext highlighter-rouge">sp</code> and <code class="language-plaintext highlighter-rouge">st</code> in the direction of <code class="language-plaintext highlighter-rouge">st</code>. So our point <code class="language-plaintext highlighter-rouge">q</code> is:</p>

<p />

<div class="cc-math">
    <math style="display:block math;">
      <mrow>
        <mi>p</mi><mo>=</mo><mi>s</mi><mo>+</mo>
        <mstyle displaystyle="true"> 
            <mfrac>
              <mrow>
                <mi>v</mi>
                <mo>&#xB7;</mo>
                <mi>w</mi>
              </mrow>
              <mrow>
                <mi>&#x2225;</mi>
                <mi>w</mi>
                <msup>
                  <mi>&#x2225;</mi>
                  <mn>2</mn>
                </msup>
              </mrow>
            </mfrac>
        </mstyle>
        <mo>&#x2062;</mo>
        <mi>&#x1D430;</mi>
      </mrow>
    </math>
</div>

<p>The end result of all of this is an UI element that we can make “taller” using a proportional distance from <code class="language-plaintext highlighter-rouge">p</code> to <code class="language-plaintext highlighter-rouge">q</code> and will slide up and down the left edge of our widget as we move around our map. Neat! Even better, we’ve defined the projection equation and have started to build some sense of how it works.</p>

<h2 id="spell-effect">Spell Effect</h2>

<p>Next up. We have our cool spell that when it impacts with another player we’re going to see an effect on the entry and exit points of the collision. Here’s the setup to our problem.</p>

<p><img src="/assets/images/intersection-testing-demo/sphere-ray-problem.jpg" alt="Sphere-ray intersection of player casting line through another player" /></p>

<p>First, let’s define some variables to work with</p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="right left">
            <mtr>
                <mtd>
                    <mi>s</mi>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>Player</mtext>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>c</mi>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>Center of collision with the sphere</mtext>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>t</mi>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>Target point</mtext>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                 <msub><mi>s</mi><mi>i</mi></msub>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>One potential intersection point with the sphere between S and T</mtext>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <msub><mi>t</mi><mi>i</mi></msub>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>The other potential intersection point with the sphere between S and T</mtext>
                </mtd>
            </mtr>
        </mtable>
    </math>
</div>

<p>We can simplify this problem a bit, by focusing on the 2-D representation of the problem. When in doubt simplify and draw the problem. This helps in modeling scenarios and edge cases. In the UI problem above we had a ray and a map point. We were curious about the point <code class="language-plaintext highlighter-rouge">p</code> on our UI widget, the intersection point to the line that was normal to <code class="language-plaintext highlighter-rouge">st</code> and <code class="language-plaintext highlighter-rouge">p</code>. This is essentially the same problem. All we’ve done is replaced <code class="language-plaintext highlighter-rouge">p</code> in our map problem with <code class="language-plaintext highlighter-rouge">c</code>, the center of the sphere. When we project <code class="language-plaintext highlighter-rouge">c</code> onto the ray defined by <code class="language-plaintext highlighter-rouge">st</code> we get an intersection point <code class="language-plaintext highlighter-rouge">p</code> in this example. If <code class="language-plaintext highlighter-rouge">p</code> is within the radius of the sphere, we know we have two possible points of intersection (in the pathological case there may only be one point).</p>

<p>To find these points let’s start by using the projection equation to get our point <code class="language-plaintext highlighter-rouge">p</code>. Once we have <code class="language-plaintext highlighter-rouge">p</code> we have we need to wrap this up. Imagine a line from the center of the sphere <code class="language-plaintext highlighter-rouge">c</code> to our first intersection point <code class="language-plaintext highlighter-rouge">s_i</code>. We can form a right triangle with <code class="language-plaintext highlighter-rouge">p</code>, <code class="language-plaintext highlighter-rouge">c</code>, and <code class="language-plaintext highlighter-rouge">s_i</code>. We know the length of the vector between <code class="language-plaintext highlighter-rouge">s_i</code> and <code class="language-plaintext highlighter-rouge">c</code>, it must be <code class="language-plaintext highlighter-rouge">r</code> as <code class="language-plaintext highlighter-rouge">s_i</code> lies on the sphere. We know the length of another side of our triangle, <code class="language-plaintext highlighter-rouge">|n|</code>.</p>

<p><img src="/assets/images/intersection-testing-demo/sphere-ray-sphere-setup.jpg" alt="Breakdown of sphere ray intersection. Lines drawn to show triangles between s, t, p, and c" /></p>

<p />

<div class="cc-math">
    <math style="display:block math;">
      <mrow>
        <mi>p</mi><mo>=</mo><mi>s</mi><mo>+</mo>
        <mstyle displaystyle="true"> 
            <mfrac>
              <mrow>
                <mi>st</mi>
                <mo>&#xB7;</mo>
                <mi>sc</mi>
              </mrow>
              <mrow>
                <mi>&#x2225;</mi><mi>st</mi>
                <msup>
                  <mi>&#x2225;</mi>
                  <mn>2</mn>
                </msup>
              </mrow>
            </mfrac>
        </mstyle>
        <mo>&#x2062;</mo>
        <mi>st</mi>
      </mrow>
    </math>
</div>

<p>Using the Pythagorean Theorem, we can solve for the length of <code class="language-plaintext highlighter-rouge">l</code>, the length of the vector between <code class="language-plaintext highlighter-rouge">p</code> and <code class="language-plaintext highlighter-rouge">s_i</code>. With that length we can start at <code class="language-plaintext highlighter-rouge">p</code> and move along <code class="language-plaintext highlighter-rouge">st</code> in the direction of <code class="language-plaintext highlighter-rouge">s</code> and in the direction of <code class="language-plaintext highlighter-rouge">t</code> to find our points of intersection.</p>

<p><img src="/assets/images/intersection-testing-demo/sphere-ray-sphere-pythagorean.jpg" alt="Breakdown of sphere ray intersection. Lines drawn to show triangles between s, t, p, and c" /></p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="right left">
            <mtr>
                <mtd>
                    <msup>
                        <mi>r</mi>
                        <mn>2</mn>
                    </msup>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msup>
                        <mi>l</mi>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <mi>&#x2225;</mi>
                    <mi>n</mi>
                    <msup>
                        <mi>&#x2225;</mi>
                        <mn>2</mn>
                    </msup>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>l</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msqrt>
                    <mrow>
                        <msup>
                            <mi>r</mi>
                            <mn>2</mn>
                        </msup>
                        <mo>−</mo>
                        <mi>&#x2225;</mi>
                        <mi>n</mi>
                        <msup>
                            <mi>&#x2225;</mi>
                            <mn>2</mn>
                        </msup>
                    </mrow>
                    </msqrt>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <msub>
                        <mi>s</mi>
                        <mi>i</mi>
                    </msub>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mi>p</mi>
                    <mo>+</mo>
                    <mi>l</mi>
                    <mo>&#x2062;</mo>
                    <mo form="prefix" stretchy="false">(</mo>
                    <mi>p</mi>
                    <mo>−</mo>
                    <mi>s</mi>
                    <mo form="postfix" stretchy="false">)</mo>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <msub>
                        <mi>t</mi>
                        <mi>i</mi>
                    </msub>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mi>p</mi>
                    <mo>+</mo>
                    <mi>l</mi>
                    <mo>&#x2062;</mo>
                    <mo form="prefix" stretchy="false">(</mo>
                    <mi>p</mi>
                    <mo>−</mo>
                    <mi>t</mi>
                    <mo form="postfix" stretchy="false">)</mo>
                </mtd>
            </mtr>
        </mtable>
    </math>
</div>

<h2 id="meteor">Meteor!</h2>

<p><img src="/assets/images/intersection-testing-demo/sphere-sphere-problem.jpg" alt="Sphere-sphere intersection of two orbital bodies impacting" /></p>

<p>Alright! We have some nice UI and a cool spell effect, time to summon our meteor. Our last type of intersection testing is sphere-sphere. Checking to see if two spheres intersect is as easy as seeing if the sum of their radii is larger than the length of the vector between their centers. What is slightly more difficult, and the problem we’re trying to solve, is what’s the circle (all points of intersection) between the two spheres? As with any problem, let’s start by writing down our variables.</p>

<p><img src="/assets/images/intersection-testing-demo/sphere-sphere-setup.jpg" alt="Sphere-sphere intersection of two orbital bodies impacting" /></p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="right left">
            <mrow>
                <mtd>
                    <msub><mi>c</mi><mi>1</mi></msub>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>Center of sphere being impacted</mtext>
                </mtd>
            </mrow>
            <mrow>
                <mtd>
                    <msub><mi>c</mi><mi>2</mi></msub>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>Center of sphere impacting (meteor)</mtext>
                </mtd>
            </mrow>
            <mrow>
                <mtd>
                    <mi>p</mi>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>Center of circle of intersection</mtext>
                </mtd>
            </mrow>
            <mrow>
                <mtd>
                    <mi>a</mi>
                </mtd>
                <mtd>
                    <mo>=</mo><mtext>Radius of circle of intersection</mtext>
                </mtd>
            </mrow>
        </mtable>
    </math>
</div>

<p>First, what does it mean for two spheres to intersect. If we had the equations of these two sphere’s we would be looking for all points where the two equations were equal. Surprisingly, we can solve sphere-sphere intersection with algebra and a bit of geometry.</p>

<p>Let’s start by defining our sphere’s geometrically. First, let’s assume our sphere’s are aligned along the x-axis. This won’t change the solution, but it does simplify the problem.</p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="right left">
            <mtr>
                <mtd>
                    <mi>d</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msub>
                        <mi>c</mi>
                        <mrow>
                            <mn>2</mn>
                            <mo>&#x2063;</mo>
                            <mi>x</mi>
                        </mrow>
                    </msub>
                    <mo>−</mo>
                    <msub>
                        <mi>c</mi>
                        <mrow>
                            <mn>1</mn>
                            <mo>&#x2063;</mo>
                            <mi>x</mi>
                        </mrow>
                    </msub>
                    <mspace width="0.25em" />
                    <mtext>, length of vector between the two sphere's</mtext>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mtext>sphere 1:</mtext>
                    <mspace width="0.25em" />
                    <msubsup>
                        <mi>r</mi>
                        <mn>1</mn>
                        <mn>2</mn>
                    </msubsup>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msup>
                        <mi>x</mi>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <msup>
                        <mi>y</mi>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <msup>
                        <mi>z</mi>
                        <mn>2</mn>
                    </msup>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mtext>sphere 2:</mtext>
                    <mspace width="0.25em" />
                    <msubsup>
                        <mi>r</mi>
                        <mn>2</mn>
                        <mn>2</mn>
                    </msubsup>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mo form="prefix" stretchy="false">(</mo>
                    <mi>x</mi>
                    <mo>−</mo>
                    <mi>d</mi>
                    <msup>
                        <mo form="postfix" stretchy="false">)</mo>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <msup>
                        <mi>y</mi>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <msup>
                        <mi>z</mi>
                        <mn>2</mn>
                    </msup>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mphantom>
                        <mtext>sphere 2:</mtext>
                        <msubsup>
                            <mi>r</mi>
                            <mn>2</mn>
                            <mn>2</mn>
                        </msubsup>
                    </mphantom>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mo form="prefix" stretchy="false">(</mo>
                    <mi>x</mi>
                    <mo>−</mo>
                    <mi>d</mi>
                    <msup>
                        <mo form="postfix" stretchy="false">)</mo>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <mo form="prefix" stretchy="false">(</mo>
                    <msubsup>
                        <mi>r</mi>
                        <mn>1</mn>
                        <mn>2</mn>
                    </msubsup>
                    <mo>−</mo>
                    <msup>
                        <mi>x</mi>
                        <mn>2</mn>
                    </msup>
                    <mo form="postfix" stretchy="false">)</mo>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>x</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mstyle displaystyle="true"> 
                        <mfrac>
                          <mrow>
                            <msup>
                              <mi>d</mi>
                              <mn>2</mn>
                            </msup>
                            <mo>−</mo>
                            <msubsup>
                              <mi>r</mi>
                              <mn>2</mn>
                              <mn>2</mn>
                            </msubsup>
                            <mo>+</mo>
                            <msubsup>
                              <mi>r</mi>
                              <mn>1</mn>
                              <mn>2</mn>
                            </msubsup>
                          </mrow>
                          <mrow>
                            <mn>2</mn>
                            <mo>&#x2062;</mo>
                            <mi>d</mi>
                          </mrow>
                        </mfrac>
                    </mstyle>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mi>p</mi>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msub>
                        <mi>c</mi>
                        <mn>1</mn>
                    </msub>
                    <mo>+</mo>
                    <mi>x</mi>
                    <mo>&#x2062;</mo>
                    <mover>
                        <mrow>
                            <msub>
                                <mi>c</mi>
                                <mn>1</mn>
                            </msub>
                            <msub>
                                <mi>c</mi>
                                <mn>2</mn>
                            </msub>
                        </mrow>
                        <mo stretchy="true" style="math-style:normal;math-depth:0;">→</mo>
                    </mover>
                </mtd>
            </mtr>
        </mtable>
    </math>
</div>

<p>So what did we just find? Well, <code class="language-plaintext highlighter-rouge">x</code> is how from from <code class="language-plaintext highlighter-rouge">c1</code> we need to go along the vector <code class="language-plaintext highlighter-rouge">c1-&gt;c2</code> to find <code class="language-plaintext highlighter-rouge">p</code>. Awesome! We have <code class="language-plaintext highlighter-rouge">p</code>, but what’s the radius; what’s <code class="language-plaintext highlighter-rouge">a</code>? The radius of the circle is in the yz-plane centered around <code class="language-plaintext highlighter-rouge">x</code> in our setup of the two spheres being aligned on the x-axis. So, plugging in <code class="language-plaintext highlighter-rouge">x</code> to our original equation and solving for y<sup>2</sup> + z<sup>2</sup> gives us,</p>

<p />

<div class="cc-math">
    <math style="display:block math;">
        <mtable columnalign="right left">
            <mtr>
                <mtd>
                    <msup>
                        <mi>y</mi>
                        <mn>2</mn>
                    </msup>
                    <mo>+</mo>
                    <msup>
                        <mi>z</mi>
                        <mn>2</mn>
                    </msup>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msubsup>
                        <mi>r</mi>
                        <mn>1</mn>
                        <mn>2</mn>
                    </msubsup>
                    <mo>−</mo>
                    <msup>
                        <mi>x</mi>
                        <mn>2</mn>
                    </msup>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mphantom>
                        <msup>
                            <mi>y</mi>
                            <mn>2</mn>
                        </msup>
                        <mo>+</mo>
                        <msup>
                            <mi>z</mi>
                            <mn>2</mn>
                        </msup>
                    </mphantom>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msubsup>
                    <mi>r</mi>
                    <mn>1</mn>
                    <mn>2</mn>
                    </msubsup>
                    <mo>−</mo>
                    <msup>
                        <mrow>
                            <mo fence="true" form="prefix">(</mo>
                            <mstyle displaystyle="true"> 
                                <mfrac>
                                    <mrow>
                                    <msup>
                                      <mi>d</mi>
                                      <mn>2</mn>
                                    </msup>
                                    <mo>−</mo>
                                    <msubsup>
                                      <mi>r</mi>
                                      <mn>2</mn>
                                      <mn>2</mn>
                                    </msubsup>
                                    <mo>+</mo>
                                    <msubsup>
                                      <mi>r</mi>
                                      <mn>1</mn>
                                      <mn>2</mn>
                                    </msubsup>
                                    </mrow>
                                    <mrow>
                                    <mn>2</mn>
                                    <mo>&#x2062;</mo>
                                    <mi>d</mi>
                                    </mrow>
                                </mfrac>
                            </mstyle>
                            <mo fence="true" form="postfix">)</mo>
                        </mrow>
                        <mn>2</mn>
                    </msup>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mphantom>
                        <msup>
                            <mi>y</mi>
                            <mn>2</mn>
                        </msup>
                        <mo>+</mo>
                        <msup>
                            <mi>z</mi>
                            <mn>2</mn>
                        </msup>
                    </mphantom>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <msubsup>
                        <mi>r</mi>
                        <mn>1</mn>
                        <mn>2</mn>
                    </msubsup>
                    <mo>−</mo>
                    <mstyle displaystyle="true"> 
                        <mfrac>
                          <mn>1</mn>
                          <mrow>
                            <mn>4</mn>
                            <mo>&#x2062;</mo>
                            <msup>
                              <mi>d</mi>
                              <mn>2</mn>
                            </msup>
                          </mrow>
                        </mfrac>
                    </mstyle>
                    <mo>&#x2062;</mo>
                    <msup>
                      <mrow>
                        <mo fence="true" form="prefix">(</mo>
                        <msup>
                          <mi>d</mi>
                          <mn>2</mn>
                        </msup>
                        <mo>−</mo>
                        <msubsup>
                          <mi>r</mi>
                          <mn>2</mn>
                          <mn>2</mn>
                        </msubsup>
                        <mo>+</mo>
                        <msubsup>
                          <mi>r</mi>
                          <mn>1</mn>
                          <mn>2</mn>
                        </msubsup>
                        <mo fence="true" form="postfix">)</mo>
                      </mrow>
                      <mn>2</mn>
                    </msup>
                </mtd>
            </mtr>
            <mtr>
                <mtd>
                    <mphantom>
                        <msup>
                            <mi>y</mi>
                            <mn>2</mn>
                        </msup>
                        <mo>+</mo>
                        <msup>
                            <mi>z</mi>
                            <mn>2</mn>
                        </msup>
                    </mphantom>
                </mtd>
                <mtd>
                    <mo>=</mo>
                    <mstyle displaystyle="true"> 
                        <mfrac>
                          <mrow>
                            <mn>4</mn>
                            <mo>&#x2062;</mo>
                            <msup>
                              <mi>d</mi>
                              <mn>2</mn>
                            </msup>
                            <mo>&#x2062;</mo>
                            <msubsup>
                              <mi>r</mi>
                              <mn>1</mn>
                              <mn>2</mn>
                            </msubsup>
                            <mo>−</mo>
                            <msup>
                              <mrow>
                                <mo fence="true" form="prefix">(</mo>
                                <msup>
                                  <mi>d</mi>
                                  <mn>2</mn>
                                </msup>
                                <mo>−</mo>
                                <msubsup>
                                  <mi>r</mi>
                                  <mn>2</mn>
                                  <mn>2</mn>
                                </msubsup>
                                <mo>+</mo>
                                <msubsup>
                                  <mi>r</mi>
                                  <mn>1</mn>
                                  <mn>2</mn>
                                </msubsup>
                                <mo fence="true" form="postfix">)</mo>
                              </mrow>
                              <mn>2</mn>
                            </msup>
                          </mrow>
                          <mrow>
                            <mn>4</mn>
                            <mo>&#x2062;</mo>
                            <msup>
                              <mi>d</mi>
                              <mn>2</mn>
                            </msup>
                          </mrow>
                        </mfrac>
                    </mstyle>
                </mtd>
            </mtr>
        </mtable>
    </math>
</div>

<p>
Phew, ok, so now that we have y<sup>2</sup> + z<sup>2</sup>, we just need to take the square root of it to get the radius we're looking for.
</p>

<div class="cc-math">
    <math style="display:block math;">
        <mrow>
            <mi>a</mi>
                <mo>=</mo>
                <mfrac>
                    <mn>1</mn>
                    <mrow>
                        <mn>2</mn>
                        <mo>&#x2062;</mo>
                        <mi>d</mi>
                    </mrow>
                </mfrac>
                <mo>&#x2062;</mo>
                <msqrt>
                    <mrow>
                        <mn>4</mn>
                        <msup>
                            <mi>d</mi>
                            <mn>2</mn>
                        </msup>
                        <msubsup>
                            <mi>r</mi>
                            <mn>1</mn>
                            <mn>2</mn>
                        </msubsup>
                        <mo>−</mo>
                        <msup>
                            <mrow>
                                <mo fence="true" form="prefix">(</mo>
                                <msup>
                                    <mi>d</mi>
                                    <mn>2</mn>
                                </msup>
                                <mo>−</mo>
                                <msubsup>
                                    <mi>r</mi>
                                    <mn>2</mn>
                                    <mn>2</mn>
                                </msubsup>
                                <mo>+</mo>
                                <msubsup>
                                    <mi>r</mi>
                                    <mn>1</mn>
                                    <mn>2</mn>
                                </msubsup>
                                <mo fence="true" form="postfix">)</mo>
                            </mrow>
                            <mn>2</mn>
                        </msup>
                    </mrow>
                </msqrt>
        </mrow>
    </math>
</div>

<p />

<p>So we now have our point <code class="language-plaintext highlighter-rouge">p</code> and our radius <code class="language-plaintext highlighter-rouge">a</code>. Finally everything we need to construct our circle. But which way is it oriented? Well, it’s “facing” along the vector formed by the vector <code class="language-plaintext highlighter-rouge">c1-&gt;c2</code>. If you want to draw this circle. you’ll need some vectors orthogonal to the vector <code class="language-plaintext highlighter-rouge">c1-&gt;c2</code>. So if this is something you want to do, check out <a href="https://en.wikipedia.org/wiki/Gram–Schmidt_process">Gram-Schmidt Orthogonoaliztion</a>.</p>

<h2 id="summary">Summary</h2>

<p>I hope this was useful for you to see another application of these intersection testing equations. Rather than testing for intersections another way to look at the three example is to view them all as forms of projections. In the first we project a point onto a line. The ray-sphere test is we project our sphere’s center onto our ray. If the length of that project is less than the radius of our sphere we got a hit. The points of intersection can be found via the Pythagorean Theorem. In the sphere-sphere intersection we’re projecting one sphere onto another and looking the circle of intersection. For me a deeper appreciation for projecting a point onto a line, and projections in general, came from Linear Algebra by Gilbert Strang, specifically chapter 4, <a href="https://ocw.mit.edu/courses/18-06-linear-algebra-spring-2010/video_galleries/video-lectures/">lectures 14-17</a>. Strongly suggested if you’ve never seen the linear algebra approach to this topic. <a href="https://www.youtube.com/watch?v=LyGKycYT2v0">3Blue1Brown</a> has a great video on the dot product (suggest the whole linear algebra series) and there’s a good <a href="https://www.youtube.com/watch?v=27vT-NWuw0M">Khan Academy</a> if you’re interesting in going deeper into the projection equation.</p>

<p>If you want to see this in a simple Unreal demo, check out my <a href="https://github.com/coderchrismills/UnrealPlayground">GitHub</a> repro. There’s an Unreal Map “MathDemos”, that shows this in action.</p>

<p><img src="/assets/images/intersection-testing-demo/intersections.jpg" alt="Screenshot of Unreal intersection tests" /></p>]]></content><author><name></name></author><category term="Game-Development" /><summary type="html"><![CDATA[Let's make some game elements to illustration how interection testing works]]></summary></entry><entry><title type="html">Making a Nova Extension</title><link href="https://coderchrismills.github.io/productivity/2022/01/05/making-a-nova-extension.html" rel="alternate" type="text/html" title="Making a Nova Extension" /><published>2022-01-05T15:00:00+00:00</published><updated>2022-01-05T15:00:00+00:00</updated><id>https://coderchrismills.github.io/productivity/2022/01/05/making-a-nova-extension</id><content type="html" xml:base="https://coderchrismills.github.io/productivity/2022/01/05/making-a-nova-extension.html"><![CDATA[<h1 id="making-a-nova-extension">Making a Nova Extension</h1>

<p>In a <a href="https://coderchrismills.com/articles/finding-my-markdown-workflow/">previous post</a> one of the reasons I didn’t continue with Sublime as my note taking app of choice was because I would have to learn how to make a build system. Well, I chose instead to go with Nova and just finished uploading my <a href="https://github.com/coderchrismills/NovaExtensions/tree/main/Todo-txt/todo.txt.novaextension">first extension</a>, a todo.txt syntax highlighter. The irony is not lost on me. Guess if I end up back using Sublime, “making an extension” can’t really be an excuse to not doing something. Especially when the tool does everything else I need 🤔.</p>

<p><img src="https://github.com/coderchrismills/NovaExtensions/raw/main/Todo-txt/todo.txt.novaextension/Images/extension/todo-txt-syntax-highlight.png" alt="Example highlighting" /></p>]]></content><author><name></name></author><category term="Productivity" /><summary type="html"><![CDATA[I spend a few hours making a Nova extension]]></summary></entry><entry><title type="html">Finding my Markdown Workflow</title><link href="https://coderchrismills.github.io/productivity/2021/12/23/finding-my-markdown-workflow.html" rel="alternate" type="text/html" title="Finding my Markdown Workflow" /><published>2021-12-23T21:00:00+00:00</published><updated>2021-12-23T21:00:00+00:00</updated><id>https://coderchrismills.github.io/productivity/2021/12/23/finding-my-markdown-workflow</id><content type="html" xml:base="https://coderchrismills.github.io/productivity/2021/12/23/finding-my-markdown-workflow.html"><![CDATA[<h1 id="finding-my-markdown-workflow">Finding my Markdown Workflow</h1>

<p>Recently I took three weeks off for some end of year vacation time. For the first time there wasn’t one thing I wanted to focus on. A typical vacation for me is either spending some time on side projects like <a href="https://lazygardener.app">Lazy Gardener</a> or doing math. But this time around the drive wasn’t there to put time into either, so where to put it? When faced with endless possibilities I took to making a list. While listing all the things around the house that needed to be done I wanted to go over my notes to see if there was something that hadn’t made it to my todo.txt file. There was a problem; my notes were all over the place.</p>

<p>My documents folder had random notes of various sizes in just about every folder, most out of context of the folder. Over time I’d become rather sloppy relying on search over structure. The laziness came from the fact that I never thought about <em>how</em> I was taking notes. When creating a new note I would first have to think about the context of the note. Home vs personal development? Should I make a folder for this topic? It’s like sitting down to write some code without first thinking of the problem you’re trying to solve. That’s fine when you’re starting to rough things out, but not a great long term plan. The result for me was to create a new file, type some thoughts down, then hit save. Location be damned, thus creating my dependence on Spotlight / <a href="https://www.alfredapp.com">Alfred</a>. Similar to writing code, the best code is the one not written. The best searching is one I didn’t have to do. Having a well-defined (not rigid) structure means I wouldn’t have to search, I could just go to where the note was.</p>

<p>Another I was having with my note taking workflow was just how I was taking notes. I do all my note taking in Markdown as I’ve found plain text files work best for me. During the day I may jot some notes down on pen and paper, but eventually they find their way to a text file. Markdown is great. Simple syntax that supports things like links, list, and images. Plus, renders easily to html (I use <a href="https://pandoc.org">Pandoc</a> for this). Though not a part of Markdown, I use YAML metadata to specify title, date, and tags for my notes. What I was looking for was an IDE of sorts for how I take notes.</p>

<h2 id="what-i-want">What I want</h2>

<p>In an ideal world<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> there would exist some application that would support the following features:</p>

<ul>
  <li>Easy to use</li>
  <li>Structured views (folders and content outline)</li>
  <li>Plain text editing</li>
  <li>Spell check</li>
  <li>Live preview of rendered output</li>
  <li>Ability to run cli actions<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></li>
  <li><strong>Bonus</strong>: Visualization of tag connectedness</li>
</ul>

<h2 id="editors">Editors</h2>

<h3 id="sublime-and-vs-code">Sublime and VS Code</h3>

<p>Over the years I’ve relied heavily (and enjoy using) both <a href="https://www.sublimetext.com">Sublime Text</a> and <a href="https://code.visualstudio.com">VS Code</a>. With Sublime and VS Code had roughly the same problem in that I didn’t want to invest time into setting up were the last two bullet points above. Mainly the ability to run cli commands easily was what kept me looking for a better solution. Both allow you to specify a build target via json files, but it would be something I would need to learn how to do. For whatever reason, VS Code didn’t feel “comfortable” to use as my note taking app. This might be a mental context issue. At work I’m on a PC in VS Code for most the day. It’s a natural for me when I need to make a note to pop open an empty file and just start typing. In fact, for work I might setup a notes workspace and use VS Code or Sublime. But for home with the additional desire to build notes and upload posts to my site, both were close, but not quite there. If I couldn’t find a better workflow I would finish getting Sublime setup.</p>

<p><a href="/assets/images/finding-my-markdown-workflow/sublime.png"><img src="/assets/images/finding-my-markdown-workflow/sublime-article.jpg" alt="Sublime" /></a>
<a href="/assets/images/finding-my-markdown-workflow/vscode.png"><img src="/assets/images/finding-my-markdown-workflow/vscode-article.jpg" alt="VS Code" /></a></p>

<p>It was at this point I decided that I wanted to try some apps that made for editing Markdown.</p>

<h3 id="bear">Bear</h3>

<p>First up, <a href="https://bear.app">Bear</a>. From their website:</p>

<blockquote>
  <p>Bear is a beautiful, flexible writing app for crafting notes and prose.</p>
</blockquote>

<p>It is. For a group of people that I realized were not me. Its ability to cross link notes and workflow based around tagging make it a great choice for people looking to just write. But without the ability to edit arbitrary text files on my computer and no way to view and edit in plain text Bear wasn’t going to work. If you don’t care about plain text editing, they have new Markdown editor <a href="https://bear.app/panda/">Panda</a> that will be integrated into Bear in the future. Though it’s easier to edit the Markdown in Panda, it’s still not full plain text editing. I would love to see Bear support a form of “Source Code Mode” similar to <a href="https://typora.io">Typora</a><sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">3</a></sup>, and allow for local file access^[4]. Bear also didn’t have a way from me to run cli commands. It would require me to completely change how I took notes. And if wanted to ever not use Bear I would have to export all most notes, just like I had to do with <a href="https://evernote.com">Evernote</a> awhile back.</p>

<h3 id="obsidian">Obsidian</h3>

<p>Tried a few others, but all were less feature rich than Bear. Except one, <a href="https://obsidian.md">Obsidian</a>. Obsidian looks great and its graph visualizer for tags is just plain cool. Except the ability to run cli commands easily, Obsidian did it all. But there was something about it, similar to VS Code, that made is somewhat uncomfortable to use. Long term I know that if I didn’t <em>want</em> to open the app to write, I would write. Overall Obsidian is great and when I’m interested in the connectedness of my notes it’s what I’ll use. Though not my primary note taking app, it’s going to stay installed.</p>

<p><a href="/assets/images/finding-my-markdown-workflow/obsidian.png"><img src="/assets/images/finding-my-markdown-workflow/obsidian-article.jpg" alt="Obsidian" /></a></p>

<h3 id="nova">Nova</h3>

<p>After more searching I came across <a href="https://nova.app">Nova</a> by Panic. I’ve been using Panic software since 2005 and actually had Nova installed from when I signed up for the beta. At the time I was using it to build some sites and overall was pleasant to use. It never occurred to me to try it as my Markdown editor of choice until one of those random <a href="https://www.sitepoint.com/the-best-markdown-editors-for-mac/">Best X for Y</a> search hits mentioned it. Nova is nice to use. The more I used it the more I wondered if my issue with VS Code and Obsidian is that they’re not native.  Whatever it is, Nova didn’t have that issue and ticked all the boxes except seeing a tag node graph. For my site I setup a quick Task to build and another to do the upload (Nova supports the upload and syncing, just haven’t set that up). For my notes, I can “build” a note which exports it using Pandoc to html. After a week of use and a bit of organization of folders I’m happily using it as my default note taking app. It’s setup in a way that works for me. I’m pretty sure most people would have stopped at VS Code, and I probably should have too. Workflows are like pens<sup id="fnref:5" role="doc-noteref"><a href="#fn:5" class="footnote" rel="footnote">4</a></sup>; your opinion of the perfect one changes over time. And it takes patience to find the one that works for you. There’s a lot of great editors out there for everyone, Nova just fits my needs right now.</p>

<p><a href="/assets/images/finding-my-markdown-workflow/nova.png"><img src="/assets/images/finding-my-markdown-workflow/nova-article.jpg" alt="Nova" /></a></p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>A truly ideal world I wouldn’t need notes. I could remember everything and recall it instantly. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>My current website is build with <a href="https://github.com/johnsundell/publish">Publish by Sundell</a> <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3" role="doc-endnote">
      <p>Typora was good, but the sliding animation when toggling Source Code Mode on and off was too distracting <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:5" role="doc-endnote">
      <p>I recently purchased 10 different technical pens from <a href="https://www.jetpens.com">Jet Pens</a> looking to change up from my Pilot Hi-Tec C <a href="#fnref:5" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name></name></author><category term="Productivity" /><summary type="html"><![CDATA[I spend a day trying different markdown editors in an effort to find a workflow I enjoy.]]></summary></entry></feed>