<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  
  <title>Brian Norman&#39;s Blog</title>
  <subtitle>Thoughts on software engineering, games, and technology</subtitle>
  <link href="https://www.bnor.me/feed.xml" rel="self" />
  <link href="https://www.bnor.me/" />
  <updated>2022-12-25T00:00:00Z</updated>
  <id>https://www.bnor.me/</id>
  <author>
    <name>Brian Norman</name>
    <email>briankn8@gmail.com</email>
  </author>
  <entry>
    <title></title>
    <link href="https://www.bnor.me/posts/gamedev-2022/" />
    <updated>2022-12-25T00:00:00Z</updated>
    <id>https://www.bnor.me/posts/gamedev-2022/</id>
    <content type="html">&lt;p&gt;One of my New Year&#39;s Resolutions this year was to learn game development (&lt;em&gt;again&lt;/em&gt;) and try actually publishing some games. This post is a look back at how that went.&lt;/p&gt;
&lt;h3 id=&quot;dear-diary&quot;&gt;Dear Diary&lt;/h3&gt;
&lt;p&gt;Back in December 2021, I randomly stumbled across &lt;a href=&quot;https://www.youtube.com/playlist?list=PLjwmj4DhJMRiJ8EmU_HW833iUR5FNQr_i&quot;&gt;Yahtzee&#39;s Dev Diary&lt;/a&gt; on Youtube, and that playlist really struck a cord with me for whatever reason. When coming up with my plan for 2022, I wrote what would go down as an overly ambitious north-star goal:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;I want to spend 365 hours doing gamedev this year&amp;quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Lofty!&lt;/p&gt;
&lt;p&gt;My desire to learn game development goes way back, playing a large part in why I learned to code in the first place. Obsessed with video games since I was old enough to use a mouse and keyboard, I always thought it would be cool to actually make my own experiences. I expressed this interest to my friend Wesley who introduced me to two people (Cole and Sunny) who were also moderately interested in programming/gamedev, and we hit it off! This was back in 2014, and that group would eventually become &lt;a href=&quot;https://cobresun.netlify.app&quot;&gt;Cobresun&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Eight years later and we hadn&#39;t really published any games yet, so I figured I&#39;d better take the opportunity now that I was done with school to get my feet wet and learn.&lt;/p&gt;
&lt;p&gt;Inspired by Yahtzee, I really wanted to have my own &amp;quot;dev diary&amp;quot; retro on the year of gamedev, which is what you&#39;re reading right now. It didn&#39;t go as planned, and I released 5 of the 12 games Yahtzee did in a year, but he&#39;s made games before, and I&#39;m a noob, so I&#39;m still pretty happy with how it turned out!&lt;/p&gt;
&lt;h3 id=&quot;how-it-went&quot;&gt;How It Went&lt;/h3&gt;
&lt;p&gt;If you&#39;re curious, I actually only spent ~135 hours this year working on games, but all in all, I&#39;m extremely thrilled with that!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/gamedev-time-2022.webp&quot; alt=&quot;Time Tracking Gamedev 2022&quot;&gt;&lt;/p&gt;
&lt;p&gt;Obviously the first half of the year was much better for me than the latter half (as New Year&#39;s Resolutions tend to be), but I&#39;m still proud of the games I made this year!&lt;/p&gt;
&lt;p&gt;I learned a new game engine Godot for these games, which was a decision mostly made arbitarily around the idea that an open source engine sounded like a good idea. I&#39;m grateful I chose Godot, the community is really cool, the engine is a delight to use, and appeals to a beginner like myself.&lt;/p&gt;
&lt;h3 id=&quot;revisiting-a-classic-sweet-tooth&quot;&gt;Revisiting a Classic: &lt;em&gt;Sweet Tooth&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Dec 26, 2021 -&amp;gt; Dec 29, 2021&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;It all started with &lt;a href=&quot;https://brian-norman.itch.io/sweet-tooth&quot;&gt;Sweet Tooth&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/9154202/147688886-c567f1d6-a158-4286-8287-8cab777d12b5.png&quot; alt=&quot;Sweet Tooth Screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;Back in 2015 Cobresun decided to host our own Game Jam (a hackathon for video games), where we&#39;d each made a game in a week (this was during winter break in highschool), and we&#39;d get each of our younger siblings to review the games on some criteria, score them, and then determine a winner. I made the &lt;a href=&quot;https://github.com/Cobresun/SweetTooth&quot;&gt;original Sweet Tooth&lt;/a&gt; in Python and Pygame, which at the time was probably the most ambitious coding project I had ever attempted.&lt;/p&gt;
&lt;p&gt;I didn&#39;t win !! Sunny won for his game &lt;a href=&quot;https://github.com/SunnyNagam/Llama-Run&quot;&gt;Llama Run&lt;/a&gt;. His colourful art appealed to the kids judging the games 😜.&lt;/p&gt;
&lt;p&gt;I decided for my first stab at learning gamedev, I&#39;d take the project I was still most proud of (Sweet Tooth is a genuinely fun game with a core gameplay loop I&#39;ve yet to surpass), and update it in Godot. I had done the Godot tutorial before this, but really wanted to learn the engine by avoiding Tutorial Hell and instead getting my hands dirty with my own projects, so that I could feel attached and proud of the work. This turned out to be a great idea.&lt;/p&gt;
&lt;p&gt;What I did with this reboot of Sweet Tooth was add elements like sound effects, particle effects, and generally made little quality of life improvments that really add a ton of polish to a game. Also actually playable version with a web release! Turns out, this goes a long way in making people play your game... (note, a lot of these quality of life improvements were added later in the year as prep for the GMTK 2022 Game Jam, which I&#39;ll talk about later).&lt;/p&gt;
&lt;h3 id=&quot;entering-the-matrix-cobresun-metaverse&quot;&gt;Entering the Matrix: &lt;em&gt;Cobresun Metaverse&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Jan 17, 2022 -&amp;gt; Jan 28, 2022&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;For my next game, and first original game idea since 2015, I decide to learn some multiplayer with the &lt;a href=&quot;https://brian-norman.itch.io/cobresun-metaverse&quot;&gt;Cobresun Metaverse&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.itch.zone/aW1nLzgwMDExNTgucG5n/original/chROqE.png&quot; alt=&quot;Cobresun Metaverse Screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;Okay fine, so not exactly a game. But that would have been too much pressure! I wanted to learn multiplayer as a sort of warmup for my next game (another unoriginal idea), and also learn pixel art.&lt;/p&gt;
&lt;p&gt;I dug around online for the best beginner tool for pixel art, and came across Aseprite. Turns out, Aseprite might as well be one of the most well-designed, delightful apps I&#39;ve ever used! (I do wish there was an iPad app).&lt;/p&gt;
&lt;p&gt;I learned this week just how hard pixel art was, which wasn&#39;t exactly a surprise, but it was still cool to peel back the curtain on that gian black box in my head. As you can see from the screenshot, I didn&#39;t do a great job with the artwork here, but the fact that it was all original art was really exciting.&lt;/p&gt;
&lt;h3 id=&quot;better-with-friends-fadeaway-reboot&quot;&gt;Better With Friends: &lt;em&gt;Fadeaway Reboot&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Jan 28, 2022 -&amp;gt; Feb 13, 2022&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Following up the tech demo that was Cobresun Metaverse, I decided to take another classic from the Cobresun troves, and give it a fresh multiplayer spin. Enter, &lt;a href=&quot;https://brian-norman.itch.io/fadeaway&quot;&gt;Fadeaway Reboot&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.itch.zone/aW1hZ2UvMTM5Nzk2OC84MTQ3NjM5LnBuZw==/original/eP2roN.png&quot; alt=&quot;Fadeaway Reboot Screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;This was a 4-player co-op zombie survival game where you try to rack up the kills, and see who the last player standing is. The catch? You can&#39;t see in the night... except for when lightning strikes!&lt;/p&gt;
&lt;p&gt;This game is the multiplayer reboot of the original game &lt;a href=&quot;https://github.com/SunnyNagam/Fadeway&quot;&gt;Fadeway&lt;/a&gt; which Sunny made for a Cobresun Gamejam in 2017.&lt;/p&gt;
&lt;p&gt;This game was particularly fun to develop for because I had spent some time getting acquainted with Godot at this point, and was starting to go off of muscle memory instead of revisitng tutorials to make everything.&lt;/p&gt;
&lt;p&gt;Every week while working on these games, I&#39;d show updates to Cobresun during our weekly calls (which we have to discuss the latest movie in our &lt;a href=&quot;https://github.com/Cobresun/movie-club&quot;&gt;Movie Club&lt;/a&gt;). I&#39;d solicit feedback and get the boys to play the games, which was a lot of fun, and definitely a habit that made me work on what mattered every week, and avoid bikeshedding. It was also a satisfying feedback loop demo-ing the game every week, pushing me to work more.&lt;/p&gt;
&lt;p&gt;I did give up on this game before it was fully finished, because while the ideas were flowing for fun features, the multiplayer was making the game unweildy. If I were to go back in time, I&#39;d probably make the game fully in single-player just to get a good grasp of the core gameplay loop and determine the minimum viable set of fun features. I&#39;d also flesh out a bunch of levels, and generally just make a good single player campaign. Maybe 10 or so levels. After that I&#39;d have hopefully gotten a solid system in place with the object oriented nature of the code, different enemies, weapons, etc. Only after that would I consider adding multiplayer.&lt;/p&gt;
&lt;h3 id=&quot;using-work-hours-for-fun-and-profit-seat-in-a-seat&quot;&gt;Using Work Hours for Fun and Profit: &lt;em&gt;Seat in a Seat&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Mar 18, 2022 -&amp;gt; Mar 22, 2022&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I was discouraged by Fadeaway and it&#39;s inability to progress through multiplayer issues, but when the opportunity arose to get paid working on a game, I &lt;em&gt;had&lt;/em&gt; to take it, and thus &lt;a href=&quot;https://brian-norman.itch.io/seat-in-a-seat&quot;&gt;Seat in a Seat&lt;/a&gt; was born!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://user-images.githubusercontent.com/9154202/175123313-c6da9a14-1d91-4a88-8468-3299169adc12.png&quot; alt=&quot;Seat in a Seat Screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;A big part of the desire to learn gamedev this year was to keep me entertained but also mentally stimulated outside of work, so it is a little ironic that my favourite game of the year was a game I made for a Hackathon at work! Hyewon Kim, designer at SeatGeek (where I work), designed this game with me, and it was such a pleasure working with her on this project. Sunny and Cole also helped debug an issue I had, which resulted in much smoother gameplay.&lt;/p&gt;
&lt;p&gt;We went all out on polish for this one, a beautiful vector UI, music, sound effects, etc. My biggest regret was not making it a web release from the get-go, which prevented most people from playing the game, and probably hindered out chances of getting a good review in the hackathon!&lt;/p&gt;
&lt;p&gt;Still though, just working on a game with people I enjoy working with was such a pleasure, it made me realize that if I can, I should always find other people to colaborate with (assuming they&#39;re as invested in the project as I am).&lt;/p&gt;
&lt;h3 id=&quot;untitled-unmastered&quot;&gt;untitled unmastered.&lt;/h3&gt;
&lt;p&gt;For the next couple months I worked on a game I am nowhere near releasing, but mostly writing and learning about storytelling, which was a lot of fun! Did some gamedev here, but I&#39;d say nothing too substantial unfortunately...&lt;/p&gt;
&lt;h3 id=&quot;sleepless-weekend-orc-onslaught&quot;&gt;Sleepless Weekend: &lt;em&gt;Orc Onslaught&lt;/em&gt;&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;July 15, 2022 -&amp;gt; July 17, 2022&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There was a drought in terms of released work since Seat in a Seat, so when the opportunity came up to work on a game for my first public game jam (GMTK 2022 Game Jam), I decided to jump at it! The result was &lt;a href=&quot;https://brian-norman.itch.io/orc-onslaught&quot;&gt;Orc Onslaught&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://img.itch.zone/aW1hZ2UvMTYyMzQwNC85NTE0MDE4LnBuZw==/original/b16mIa.png&quot; alt=&quot;Orc Onslaught Screenshot&quot;&gt;&lt;/p&gt;
&lt;p&gt;My friend Ray has spent the pandemic learning how to code (he&#39;s a nurse), and I&#39;ve been trying my best to mentor him through that. I had mentioned the game jam to him and we thought it could be fun if he joined Cole and Sunny and I on this project, so it was one of his first projects in general, which is such a cool project to cut your teeth on!&lt;/p&gt;
&lt;p&gt;Working with these guys over the weekend on this game was one of the best experiences of my life. Nothing will quite top Cobresun collaboration vibes when we&#39;re in a high pressure experience, boucing ideas off of each other, and me in awe of the sheer talent and genius that Cole and Sunny can whip up on a moments notice.&lt;/p&gt;
&lt;p&gt;In the final moments of this game&#39;s balancing we ended up making it too difficult, and we ended up getting a lot of players in the game jam judging period commenting this!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/orc-onslaught-comments.webp&quot; alt=&quot;Orc Onslaught Comments&quot;&gt;&lt;/p&gt;
&lt;p&gt;It was so cool for anyone to have played a game I worked on, I was too excited about that fact to even really pay attention to the criticism!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/orc-onslaught-results.webp&quot; alt=&quot;Orc Onslaught Results&quot;&gt;&lt;/p&gt;
&lt;p&gt;Some lessons here:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Release for web if you want people to play your game. Before the gamejam I practiced by converting the other games to web (Sweet Tooth and Seat in a Seat), which was a life saver.&lt;/li&gt;
&lt;li&gt;Playtest, playtest, playtest! Have other people other than the devs playtest !!!&lt;/li&gt;
&lt;li&gt;Polish is all about sound effects, music, and particles. It&#39;s kind of hilarious how much these things make a difference.&lt;/li&gt;
&lt;li&gt;Okay polishing is nice, but the core gameplay loop has to be fun. We spent a lot of time going back and forth on this for Orc Onslaught, since the basic template of a tower defence game is nice and all, but we were really complicating it with the addition of a roll of the dice and randomness.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&quot;thats-all-folks&quot;&gt;Thats all Folks!&lt;/h3&gt;
&lt;p&gt;And that was that! I unfortunately had a very busy and distracted second half of the year, so I didn&#39;t release any more games after Orc Onslaught (admittedly a weekend of that many hours of gamedev definitely hit me hard, and I needed a break).&lt;/p&gt;
&lt;p&gt;I really hope next year is another great year for gamedev for me, in which I&#39;d like to return to making small proof of concept games with tiny but fun gameplay loops, and sharing them with Cobresun every week and eventually releasing them.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title></title>
    <link href="https://www.bnor.me/posts/community-post-mortem/" />
    <updated>2021-03-21T00:00:00Z</updated>
    <id>https://www.bnor.me/posts/community-post-mortem/</id>
    <content type="html">&lt;p&gt;This brief article will be some collected thoughts and learnings from making &lt;a href=&quot;https://communityrefs.com&quot;&gt;Community: Required Reading&lt;/a&gt; with &lt;a href=&quot;https://twitter.com/cobresun&quot;&gt;my friends&lt;/a&gt;. If you haven&#39;t checked it out, I recommend it! It&#39;s a website that collects every parody and pop-culture reference from every episode of NBC&#39;s hit sitcom Community, organized by episode.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/community.webp&quot; alt=&quot;CommunityRefs Screenshot&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;history-101&quot;&gt;History 101&lt;/h3&gt;
&lt;p&gt;The idea was born on January 4th, 2021. My friend &lt;a href=&quot;https://sunnynagam.github.io&quot;&gt;Sunny Nagam&lt;/a&gt; and I were doing some technical interview prep together, since we both had interviews coming up. As is usually the case with the two of us, any time we get in a call, it never ends up just being for what we initially set out to do. Very quickly we devolved into one of our favourite hobbies, coming up with random ideas for things we&#39;d like to eventually do.&lt;/p&gt;
&lt;p&gt;I can&#39;t remember exactly how we got there, but eventually I started sending him some assorted works of &lt;a href=&quot;https://lynnandtonic.com&quot;&gt;Lynn Fisher&#39;s&lt;/a&gt;. She&#39;s a creator I admire quite a lot, because her projects are interesting, creative, technical explorations of her favourite things. From cataloguing all the &lt;a href=&quot;https://davidrose.style&quot;&gt;apparel David Rose wears in Schitt&#39;s Creek&lt;/a&gt;, to an &lt;a href=&quot;https://airportcod.es&quot;&gt;exploration of three-letter airport codes around the world&lt;/a&gt;, the only common thread between all her projects are the love she has for the content.&lt;/p&gt;
&lt;p&gt;Simultaneously during this call with Sunny, the topic of Vue.js came up. Another member of Cobresun, &lt;a href=&quot;https://github.com/cole-adams&quot;&gt;Cole Adams&lt;/a&gt;, happens to be a full-throated evangelist for the web framework, and his influence has spread through Cobresun like wildfire. Sunny had the opportunity work with Vue on a &lt;a href=&quot;https://github.com/MegaFooby/Drawing-with-Friends&quot;&gt;project he and Cole collaborated on for school&lt;/a&gt;. Sunny was now suggesting that &lt;em&gt;I&lt;/em&gt; learn Vue.&lt;/p&gt;
&lt;p&gt;One thing lead to another, and all of a sudden there I was coming up with the idea for this project while chatting with Sunny.&lt;/p&gt;
&lt;h3 id=&quot;lesson-1-the-adjacent-possible&quot;&gt;Lesson #1: The Adjacent Possible&lt;/h3&gt;
&lt;p&gt;There&#39;s this concept I love called the &amp;quot;Adjacent Possible&amp;quot; which I first came across in Cal Newport&#39;s &lt;em&gt;So Good They Can&#39;t Ignore You&lt;/em&gt; a few years ago. The basic idea is that if you&#39;ve got a pool of chemicals sloshing around, you may or may not have all the ingredients necessary to create a new compound. But let&#39;s say you periodically find new chemicals, and add them to this pool. Theres a chance that eventually, maybe on the 3rd or 10th or 100th addition, you&#39;ll eventually add something that is the &amp;quot;final piece of the puzzle&amp;quot; needed to make a compound.&lt;/p&gt;
&lt;p&gt;The adjacent possible in Newport&#39;s book was talking about new innovations being created. It&#39;s the answer to the question: Why do many of the great scientific innovations not happen for centuries, but then all at once within a decade or so, multiple scientists from around the world come up with the same idea? The explanation is the adjacent possible. All the ingredients for that scientific innovation was gathered by humanity over centuries, so once the final puzzle piece is in place, it&#39;s only a matter of it being sloshed around enough before some people connect the dots.&lt;/p&gt;
&lt;p&gt;I think that any creative project has some element of the Adjacent Possible to it. Heres just a few of the ingredients that had to come together here for this project to get made:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I am relatively new to web development, having only learned React.js at the beginning of 2020 for a now delayed project that the final member of Cobresun, &lt;a href=&quot;https://wesley-tang.github.io&quot;&gt;Wesley Tang&lt;/a&gt;, had asked us to work on. Nevertheless, knowing React helped me visualize the technical details of Community: Required Reading in my head while discussing it.&lt;/li&gt;
&lt;li&gt;I&#39;ve been a fan of Community since 2011 and have rewatched it many times since (the latest rewatch being April 2020).&lt;/li&gt;
&lt;li&gt;Sunny and I happened to be calling because of interviews.&lt;/li&gt;
&lt;li&gt;Cole had to shove Vue down our throats for months before it finally found it&#39;s way into one of our projects.&lt;/li&gt;
&lt;li&gt;I&#39;ve been a fan on Lynn Fisher&#39;s work for a few years (first found her through her various site redesign projects) and I happened to have seen the David Rose project a few weeks before this call with Sunny.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;My point is, you can&#39;t underestimate the adjacent possible. I am not entirely sure what the lesson here is. Maybe it&#39;s to consume lots of great content, have lots of great calls, and when an idea strikes, give it a serious consideration before dismissing it?&lt;/p&gt;
&lt;h3 id=&quot;lesson-2-parallelizing-work-and-task-boards&quot;&gt;Lesson #2: Parallelizing Work and Task Boards&lt;/h3&gt;
&lt;p&gt;Literally that night, on January 4th, 2021, after Sunny left for dinner, I got started coding the website. I began with Vue&#39;s tutorial and documentation, optimizing for quick results and not necessarily good code. The first night was just some Vue boilerplate (Hello World of course) and hosting that boilerplate on Netlify, so Cobresun could quickly look and provide feedback on the latest build.&lt;/p&gt;
&lt;p&gt;Day 2 (Jan 5th) was creating the JSON that would store everything, defining some Vue components for the episode grid, search bar, episode pages, and this was also the day Sunny joined me in coding, implementing routing and making the cards pretty.&lt;/p&gt;
&lt;p&gt;One of the key lessons I&#39;ve learned over the years is how important parallelizing tasks can be. &lt;strong&gt;We started by separating out the code such that Sunny and I could code in parallel on different files, so we wouldn&#39;t have to deal with merge conflicts.&lt;/strong&gt; This also made for an easier to understand and debug codebase, which helped onboard new developers. As a bonus, we all just pushed to master to avoid the overhead of reviews taking too long 😅 (Was this the best idea? Who knows?!)&lt;/p&gt;
&lt;p&gt;Additionally, &lt;strong&gt;we separated out what work was left to do using Github Projects Kanban board, which ended up being extremely useful as more members of Cobresun started working on the site.&lt;/strong&gt; You have to get the whole team on board with this system to work like a well-oiled machine. For example, Sunny was terrible at keeping the board up to date with his work (sorry for calling you out publicly bro!) but we were small enough that I could just update it for him. I think getting this system to be a part of the process for everyone is the key to taking advantage of it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/community-kanban.webp&quot; alt=&quot;Community Kanban&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;Still some tasks in there if anyone wants to contribute 😊&lt;/figcaption&gt;
&lt;p&gt;On Day 3 (Jan 6th) I worked on more of the code, and started importing data into the site by manually scraping the Community Wiki. Sunny was taking a break this day, which was probably a good idea, but I have this constant fear when working on a new project that I need to work on it practically non-stop until it&#39;s done if I want to ever finish it, otherwise I&#39;m prone to dropping it halfway... This is something I&#39;d like to work on.&lt;/p&gt;
&lt;p&gt;Day 4 (Jan 7th) was a big day, because Cole returned from a ski trip, and was overjoyed that Sunny and I had started working on a Vue project! He asked if he could help, and that handy Kanban board I mentioned earlier came in use. We could simply send him the link, and he was off to the races! This was the day Sunny added the amazing navbar, styling, and some bug fixes. I added the remaining references. Cole added some great UI improvements like season collapsing and custom CSS on different screen sizes.&lt;/p&gt;
&lt;p&gt;Day 5 (Jan 8th) was around the time we started heading for the endgame. We had animations, sizing, and other minor improvements. It was on this day that we decided to do a launch on January 10th, the last day of our Winter Break before Sunny, Wesley, and I headed into our final semester of University. The reasoning was simple, I just didn&#39;t want to overwork myself once the semester started, and I would prefer if I could be fully emotionally separated from this site.&lt;/p&gt;
&lt;p&gt;Day 7 (Jan 10th) came the final necessary code changes before launch. I sourced and added all the images for each episode, which Cole made some optimizations to for size. Wesley updated the About page with a disclaimer, and created the logo. We created a Twitter and Reddit account for Cobresun, and added a Kofi to accept donations should any kind souls decide to donate.&lt;/p&gt;
&lt;p&gt;That night we all got on our weekly call, and then we launched, by sharing to &lt;a href=&quot;https://twitter.com/cobresun/status/1348480618892382208&quot;&gt;Twitter&lt;/a&gt; and &lt;a href=&quot;https://www.reddit.com/r/community/comments/kuuwck/check_out_this_searchable_index_of_every/&quot;&gt;Reddit&lt;/a&gt;! 🎉&lt;/p&gt;
&lt;h3 id=&quot;lesson-3-deviating-from-the-plan&quot;&gt;Lesson #3: Deviating From the Plan&lt;/h3&gt;
&lt;p&gt;The original idea was deceivingly simple on paper, so we jumped at it. The final version of the website you can now visit is pretty much exactly how we wanted it to look and function when coming up with the idea in call, with one notable exception. We originally wanted hand-drawn images for every episode, that were of pop-culture references in each episode. After some debate later in the week as we neared completion of the site&#39;s functionality, we decided that would be too much work and we&#39;d never launch anything if we tried to draw 110 individual pieces of art. Thank goodness we decided against this!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/community-guitar.webp&quot; alt=&quot;Guitar drawing&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;This amazing drawing by Cole was for S1E8: Home Economics&lt;/figcaption&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/community-football.webp&quot; alt=&quot;Football drawing&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;I drew this football for S1E6: Football, Feminism and You&lt;/figcaption&gt;
&lt;h3 id=&quot;the-reaction&quot;&gt;The Reaction&lt;/h3&gt;
&lt;p&gt;We were pleasantly surprised by the positive reaction we got. My expectation was that we&#39;d get exactly four visitors (each of us in Cobresun) and maybe one more if my brother opened the link...  We turned on Netlify analytics for the first month, and this was the result:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/community-first-month.webp&quot; alt=&quot;First month viewership stats&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;That sharp drop-off was the giveaway that we did not have a viral hit on our hands 😆&lt;/figcaption&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/community-locs.webp&quot; alt=&quot;First month location stats&quot;&gt;
We&#39;re fairly positive the usage of the site has tapered off, with a few visitors a month now, but I&#39;d like to think at least one person out there is using the site regularly for their latest watch through of the show 😁&lt;/p&gt;
&lt;h3 id=&quot;emotional-consequences-of-broadcast-television&quot;&gt;Emotional Consequences of Broadcast Television&lt;/h3&gt;
&lt;p&gt;In the end, the week we spent making this site will, looking back, be one of my favourite weeks that Cobresun had. I spent 25 hours that week working on the project, which is not bad all things considered. The result was a really fun website I genuinely enjoy clicking around and scrolling through!&lt;/p&gt;
&lt;p&gt;A quick recap of the lessons learned:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The adjacent possible will lead to serendipitous project ideas, don&#39;t dismiss them&lt;/li&gt;
&lt;li&gt;Get started right away, and without overworking, try to keep at it consistently until an MVP is done, so you don&#39;t drop the project unfinished and un-launched&lt;/li&gt;
&lt;li&gt;Parallelize the work in code to avoid merge conflicts, and have a lot of trust in your team&lt;/li&gt;
&lt;li&gt;Kanban board of up-to-date tasks to work on is esssential&lt;/li&gt;
&lt;li&gt;Be okay with changing the original plan to make your life easier, as we discovered, people will likely not notice and not care&lt;/li&gt;
&lt;li&gt;Know when to call it, and make a big deal out of launch day, because it&#39;s fun!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now I&#39;m itching to do another Community rewatch...&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title></title>
    <link href="https://www.bnor.me/posts/hls-explained/" />
    <updated>2021-01-02T00:00:00Z</updated>
    <id>https://www.bnor.me/posts/hls-explained/</id>
    <content type="html">&lt;p&gt;Watching videos is one of the most ubiquitous activities on the internet, but few understand the technology behind it. It would be nice to understand a little of whats happening under the hood, and I&#39;d like to start with a look at HLS (HTTP Live Streaming), a streaming protocol &lt;a href=&quot;https://developer.apple.com/streaming/&quot;&gt;developed by Apple&lt;/a&gt; in 2009 that is used by the majority of video streaming sites today.&lt;/p&gt;
&lt;h3 id=&quot;a-world-without-hls&quot;&gt;A World Without HLS&lt;/h3&gt;
&lt;p&gt;In a world without HLS, there would be a &lt;em&gt;lot&lt;/em&gt; of buffering. Not only during the video, but the time it takes to initally load the video once you click play would be excruciatingly slow (scaling with video length). This of course is dependant on the internet speed of the user, but because most countries have slow or flaky internet, watching videos online would be a luxury few could afford.&lt;/p&gt;
&lt;p&gt;There would be no dynamic changing of video quality while watching, which you might not think is a big deal, but having to change the stream&#39;s quality constantly and then re-start download every single time your internet is flaky would be a nightmare given what consumers have come to expect.&lt;/p&gt;
&lt;p&gt;If this world sounds familiar, its because it is, we used to live it! Internet videos used to be a lot less accessible and much more of an ordeal than they are today, and we have Adaptive Bitrate Streaming to thank for that.&lt;/p&gt;
&lt;h3 id=&quot;adaptive-bitrate-streaming-with-hls&quot;&gt;Adaptive Bitrate Streaming with HLS&lt;/h3&gt;
&lt;p&gt;Note that HLS is not the only protocol in this space, the other popular option is MPEG-DASH. Both are examples of &lt;a href=&quot;https://en.wikipedia.org/wiki/Adaptive_bitrate_streaming&quot;&gt;Adaptive Bitrate Streaming&lt;/a&gt; protocols. Here are a couple of tricks up their sleeves that make modern video streaming possible:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Fragmented Stream&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Imagine the wait time for every video if you had to download the entire clip before the player would start playing the video. That might sound fine for a 30 second cat video, but imagine a Netflix movie! One of the great innovations in the video streaming world was the idea of playing a video without having to download the whole video to a user&#39;s device.&lt;/p&gt;
&lt;p&gt;To experiment with this feature, I created a little archive of my own videos, and below is a screenshot of the network responses that occur when hitting play on one of the videos.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/hls-demo.webp&quot; alt=&quot;HLS Demo&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;The network responses once the play button on the video is clicked.&lt;/figcaption&gt; 
&lt;p&gt;The initial .m3u8 file downloaded is an M3U playlist for the video. An &lt;a href=&quot;https://en.wikipedia.org/wiki/M3U&quot;&gt;M3U (MP3 URL) playlist&lt;/a&gt; is a file that describes a list of media files, including where they can be found (their URL). HLS works by first segmenting the video into .ts files, which are Video Transport Stream files used for compressed video data. A sequence of .ts files numbered in ascending order represent the full video. The .m3u8 file lists .ts files and where they can be found, so if the client has the .m3u8 file they&#39;ll be able to reconstruct the whole video!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/m3u8-example.webp&quot; alt=&quot;M3U8 Example&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;Example of .m3u8 file from &lt;a href=&quot;https://developer.apple.com/documentation/http_live_streaming/example_playlists_for_http_live_streaming/video_on_demand_playlist_construction&quot;&gt;apple docs&lt;/a&gt;.&lt;/figcaption&gt;
&lt;p&gt;You&#39;ve probably noticed when watching Youtube videos that the seek bar has an indicator for how much of the video has already been downloaded ahead of the current timestamp. This feature is noticable when the internet connection goes out while watching a video, and the playback stops abruptly once the seeker reaches the furthest point downloaded.&lt;/p&gt;
&lt;p&gt;This &amp;quot;pre-fetching&amp;quot; of video is done with Adaptive Bitrate Streaming, where .ts files ahead of the current timestamp are constantly queued up. An additional side-effect is that if users frequently open videos and then exit out of them without watching the whole video, or maybe skip around different timestamps, the entire video file need not be downloaded, saving plenty of bandwidth!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Different Bitrates&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I mentioned earlier that one of the benefits of HLS was video quality dynamically changing as the video is viewed. This works via HLS inspecting the bandwidth on the user&#39;s device, which is why HLS is not the only streaming protocol that exists. When Apple created HLS, they built out support for all the Apple devices for the Safari web browser and Apple TV, but HLS has been adopted widely across the board. HLS supports intelligent switching of streams based on bandwidth changes, meaning the video won&#39;t stop playing when a user&#39;s internet slows down, instead a lower quality .ts file is downloaded so the playback is un-interrupted.&lt;/p&gt;
&lt;p&gt;The example .m3u8 file shown above is just one of the various .m3u8 files a video will have in HLS. The reality is that there is a master .m3u8 playlist, which has links to many .m3u8 files each at a different bitrates (or video stream quality). HLS intelligently switches between the .m3u8 file to download from, and in turn downloads the .ts files from that .m3u8 playlist.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/root-m3u8.webp&quot; alt=&quot;Root M3U8&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;The real master m3u8 playlist of the Canon Ad video I showed the network response of above.&lt;/figcaption&gt; 
&lt;p&gt;You can see the various bitrates in the titles of the m3u8 files, for example 0.4Mbps which corresponds to the 480x270 video, versus the 6.5Mbps video which has a resolution of 1280x720.&lt;/p&gt;
&lt;h3 id=&quot;demystifying-streaming&quot;&gt;Demystifying Streaming&lt;/h3&gt;
&lt;p&gt;I wanted this post to be a brief non-technical introduction to HLS, so I won&#39;t go into how the different components actually work to make it all possible. I&#39;ll leave some of that magic intact 😉 (or if you&#39;re still curious, the &lt;a href=&quot;https://developer.apple.com/streaming/&quot;&gt;apple docs&lt;/a&gt; do a good job explaining).&lt;/p&gt;
&lt;p&gt;I hope this brief intro was enough to get you curious the next time you watch a TV show on your Mac in Safari, or a Youtube video on your Android device! The full list of usages and supported players can be found &lt;a href=&quot;https://en.wikipedia.org/wiki/HTTP_Live_Streaming#Usage&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title></title>
    <link href="https://www.bnor.me/posts/first-post/" />
    <updated>2020-11-22T00:00:00Z</updated>
    <id>https://www.bnor.me/posts/first-post/</id>
    <content type="html">&lt;p&gt;I decided to redesign my personal website from scratch (you&#39;re looking at the new one) and this first post is a little explanation as to why. I&#39;ll first go over some of the technical reasons, and then follow it up with the more aspirational.&lt;/p&gt;
&lt;h3 id=&quot;technical&quot;&gt;Technical&lt;/h3&gt;
&lt;p&gt;Purely from a learning point-of-view, it&#39;s fun to learn new technologies and experiment with them! The website I&#39;ve been running for most of 2020 was itself a React.js redesign of my 2019 website (static HTML and CSS).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/old-static-site.webp&quot; alt=&quot;Old static site&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;That beautiful drawing of me was done by my friend &lt;a href=&quot;https://wesley-tang.github.io&quot;&gt;Wesley Tang&lt;/a&gt;&lt;/figcaption&gt; 
&lt;p&gt;I needed to learn React this year for some projects, so practicing it on my own website seemed a fun way to personalize my learning. This was not a bad idea, I learned a lot about React, those projects went well (or nowhere), and my website worked just fine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/old-react-site.webp&quot; alt=&quot;Old react site&quot;&gt;&lt;/p&gt;
&lt;figcaption&gt;Once in React, you know I had to add night mode with hooks (however extraneous) 😎&lt;/figcaption&gt; 
&lt;p&gt;The problem was React was not the best tool for the job. For a website that hosted an About page, a Portfolio of projects, and a list of books I&#39;ve read, it had a pretty long build time! It&#39;s a classic case of seeing every problem as a nail when holding a hammer. I&#39;m not saying there&#39;s anything wrong with using React for a simple website, but it should be dependant on the use-case. I don&#39;t think I&#39;d hear much pushback if I suggested &amp;quot;We probably don&#39;t need Electron for our company&#39;s portfolio page!&amp;quot;&lt;/p&gt;
&lt;p&gt;I ended up switching to &lt;a href=&quot;https://www.11ty.dev&quot;&gt;11ty&lt;/a&gt; for the current incarnation of the site (at the time of writing). I don&#39;t have much to say about why and I can&#39;t claim to have done much research on the subject before deciding, but what I can say is that my build times are shorter! I also enjoy the simplicity of writing posts in markdown, although I&#39;m still getting used to the syntax &lt;a href=&quot;https://shopify.github.io/liquid/&quot;&gt;Shopify Liquid&lt;/a&gt; is... interesting).&lt;/p&gt;
&lt;p&gt;Another switch worth noting is the switch from Firebase to &lt;a href=&quot;https://www.netlify.com&quot;&gt;Netlify&lt;/a&gt; for hosting. I&#39;d argue this is probably the better example of my previous point about the hammer and nails. Firebase was definitely overkill for my website, and the fact that I can now have new builds deployed with a simple push to the main branch is exciting! I could have automated deployment with Firebase using Github Actions, but I enjoy the reduced friction and boilerplate that Netflify comes with. Connecting the site to my repo and having it build 11ty &lt;strong&gt;without any config&lt;/strong&gt; was a magical setup experience.&lt;/p&gt;
&lt;p&gt;The UI for this site was my best attempt at stealing the wonderful design of &lt;a href=&quot;https://www.aaronshekey.com&quot;&gt;Aaron Shekey&#39;s personal site&lt;/a&gt;, who I recommend everyone check out! (Update April 2021: His website no longer looks like the one that I drew inspiration from, but still check him out!)&lt;/p&gt;
&lt;h3 id=&quot;aspirational&quot;&gt;Aspirational&lt;/h3&gt;
&lt;p&gt;I didn&#39;t mention another big reason for switching the website technology, which was to support friction-less blogging. One of my goals going forward is to write a little more publically; about my learnings, my thoughts (I&#39;ll try and refrain from inflicting my views upon the world too much) and my goals. I see this website redesign as my public commitment to writing and putting myself out there more.&lt;/p&gt;
&lt;p&gt;Writing more helps with &lt;a href=&quot;https://twitter.com/igrigorik/status/1324831467638149120&quot;&gt;decision making&lt;/a&gt;, &lt;a href=&quot;https://zenhabits.net/write-daily/&quot;&gt;thinking clearly&lt;/a&gt;, &lt;a href=&quot;http://www.shubhro.com/2014/12/27/software-engineers-should-write/&quot;&gt;understanding something deeply&lt;/a&gt;, generating more ideas, and just getting better at the act of writing itself.&lt;/p&gt;
&lt;p&gt;This first post should serve as a sort of template of what the writing on this site may look like, a mix of personal and technical anecdotes, roughly in the same ratio (all subject to change!). I&#39;m not a technical authority by any means, so I won&#39;t pretend to be. These posts are more like a public journal for myself, which others may or may not find useful. Even if nobody reads them, I think I&#39;ll get value from writing them. Beyond practicing writing, these posts serve as little note-to-selfs for me to look back to (now I&#39;ll hopefully avoid unnecessarily switching back to React for this site a year from now!).&lt;/p&gt;
&lt;p&gt;I chose to put this writing on my own static website, as opposed to a Medium blog or something, because I like the idea of decentralizing the internet, and &lt;a href=&quot;https://hedgehogreview.com/issues/the-human-and-the-digital/articles/tending-the-digital-commons&quot;&gt;operating outside the walled gardens of big social media companies&lt;/a&gt;. On this site there is no content moderation (not that I&#39;ll be sharing anything controversial 😅) and no ads!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title></title>
    <link href="https://www.bnor.me/posts/weightless-post-mortem/" />
    <updated>2020-01-17T00:00:00Z</updated>
    <id>https://www.bnor.me/posts/weightless-post-mortem/</id>
    <content type="html">&lt;p&gt;&lt;img src=&quot;https://github.com/brian-norman/weightLess/raw/master/feature-graphic.png&quot; alt=&quot;WeightLess app feature graphic&quot;&gt;&lt;/p&gt;
&lt;p&gt;I just launched v1.0 of &lt;a href=&quot;https://github.com/brian-norman/weightLess&quot;&gt;WeightLess&lt;/a&gt; today after 3 days of working on it, and I thought I&#39;d reflect!&lt;/p&gt;
&lt;p&gt;This was the first app where I had a Figma design first before diving into code, which was epic! Knowing where you&#39;re going makes it much faster to get there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.bnor.me/images/weightless-figma.webp&quot; alt=&quot;WeightLess Figma&quot;&gt;&lt;/p&gt;
&lt;p&gt;A lot of the code is directly ripped from another similar project, so the process went by super quick since I had experience.&lt;/p&gt;
&lt;p&gt;There&#39;s a lot more I wanted to add, but in the spirit of quick iteration/feedback, I &lt;a href=&quot;https://play.google.com/store/apps/details?id=com.brian.weightless&amp;amp;pli=1&quot;&gt;released an MVP&lt;/a&gt;. This was great because I got super useful and actionable feature requests I hadn&#39;t thought of!&lt;/p&gt;
&lt;p&gt;Tip: leave every day on an interesting solvable problem for the next morning, so the activation energy to get back in is low&lt;/p&gt;
</content>
  </entry>
</feed>