<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>f0ssel</title>
    <link>https://f0ssel.com/</link>
    <description>Notes on Go, game development, and the things I build.</description>
    <language>en-us</language>
    <lastBuildDate>Wed, 27 Mar 2024 14:09:36 -0400</lastBuildDate>
    <atom:link href="https://f0ssel.com/index.xml" rel="self" type="application/rss+xml"/>
    <item>
      <title>Go Patterns</title>
      <link>https://f0ssel.com/posts/golang-patterns/</link>
      <guid>https://f0ssel.com/posts/golang-patterns/</guid>
      <pubDate>Wed, 27 Mar 2024 14:09:36 -0400</pubDate>
      <category>go</category>
      <description>I began learning Go in 2019, and it swiftly became my most productive and preferred backend programming language. In this article, I’ll share some common patterns I’ve observed in Go applications and…</description>
      <content:encoded>&lt;p&gt;I began learning Go in 2019, and it swiftly became my most productive and preferred backend programming language. In this article, I’ll share some common patterns I’ve observed in Go applications and explain why I favor them over other options.&lt;/p&gt;
&lt;h2 id=&#34;errors&#34;&gt;Errors&lt;/h2&gt;
&lt;p&gt;Instead of checking for &lt;code&gt;nil&lt;/code&gt; values or comparing empty structs, it’s preferable to return both a value and an error, then check the error. This approach is familiar to others and simplifies error handling throughout the codebase. It’s essential to always wrap errors, ensuring a clean and unambiguous error stack that traces back to the source of the error. Additionally, I prefer to explicitly return &lt;code&gt;val, nil&lt;/code&gt; even when the error is &lt;code&gt;nil&lt;/code&gt; for clarity.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// this is just OK&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parseInt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// this is better - clean error stack&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;parseInt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;strconv&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Atoi&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;convert string to int: %w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
Some like to return an OK boolean instead of an error and I think that is just &lt;code&gt;OK&lt;/code&gt; at times but I’d almost always reccomend returning an error. I do not think you should use an OK boolean over an error if the code path has multiple failure cases.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// this is just OK&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lookup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;boolean&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// an error is better&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lookup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;value does not exist in map1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// errors are required to know the failure case&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lookup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;value does not exist in map1&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;value does not exist in map2&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
If you are returning the same error in multiple places, or perhaps the same &lt;em&gt;kind&lt;/em&gt; of error, you should consider declaring the error as a package variable. These are exported and usually the name of the variable take the shape of &lt;code&gt;Err*&lt;/code&gt; so it’s clear to consumers what it’s for. The advantage of this is so consumers of the package can use &lt;code&gt;errors.Is&lt;/code&gt; to check if the error matches a declared error they are antisipating.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ErrNoKey&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;key missing&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ErrNotValid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;New&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;value is not valid&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lookup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;&#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;length is 0: %w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ErrNotValid&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;map1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ok&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;map1 lookup: %w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ErrNoKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;useLookup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;lookup&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;val&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;errors&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Is&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ErrNoKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;			&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;404 - %w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;			&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;400 - %w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;200 - %d&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;i&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;json-parsing&#34;&gt;JSON Parsing&lt;/h2&gt;
&lt;p&gt;I prefer using a combination of pointers and the &lt;code&gt;omitempty&lt;/code&gt; JSON tag for detecting optional field values when parsing JSON. This approach aligns well with frontends consuming the APIs I build, which often distinguish between &lt;code&gt;undefined&lt;/code&gt; and &lt;code&gt;0&lt;/code&gt; for number fields on a payload. It helps bridge the gap between frontend and backend communication by ensuring consistency in JSON representation.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MyStruct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;	        &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&#34;name&#34;`&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MyOptionalValue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;`json:&#34;myValue,omitempty&#34;`&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;printValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mystruct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MyStruct&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;json&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Unmarshal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mystruct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// first check if it was even sent&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mystruct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MyOptionalValue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;value is missing&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// this means we have a value, but it&#39;s zero&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// safe to dereference value since we checked it&#39;s not nil&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mystruct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MyOptionalValue&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;==&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;value is zero&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// we have a non-zero value&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Printf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;value is %d\n&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;mystruct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MyOptionalValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
When using &lt;code&gt;omitempty&lt;/code&gt; and returing JSON responses over HTTP/S you do not send the field if it’s &lt;code&gt;nil&lt;/code&gt; or another zero value. You can then create the respective interface in TypeScript. At my current company Coder we’ve created a tool that generates TypeScript interfaces from Go structs based on this behavior and it works great.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-Typescript&#34;&gt;&lt;span class=&#34;kd&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;MyStruct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;name&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myValue?&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;number&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;main&#34;&gt;Main&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;main&lt;/code&gt; function should primarily handle signals and start the application, ultimately returning an error. It’s essential to confine exit functions like &lt;code&gt;os.Exit()&lt;/code&gt; or &lt;code&gt;log.Fatal()&lt;/code&gt; to the &lt;code&gt;main&lt;/code&gt; function only. All other functions should return errors, which not only delineates the application’s start and end points but also facilitates easier testing.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;&lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;main&lt;/span&gt;

&lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;context&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;log&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;os&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;os/signal&#34;&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;syscall&#34;&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;main&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cancel&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;WithCancel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Background&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;defer&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cancel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sig&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;make&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;chan&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;os&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Signal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;signal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Notify&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sig&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;syscall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;SIGINT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;syscall&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;SIGTERM&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;go&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;sig&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;cancel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}()&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;log&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Fatalf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;error: %v&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// setup logging&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// setup database&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// setup api&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// setup http server&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;-&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Done&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;interfaces&#34;&gt;Interfaces&lt;/h2&gt;
&lt;p&gt;As Rob Pike aptly stated, “The bigger the interface, the weaker the abstraction.” Interfaces should have a narrow scope and usually end in &lt;code&gt;er&lt;/code&gt; to denote their behavior. This pattern is widely used in the standard library for interfaces like &lt;code&gt;io.Reader&lt;/code&gt;, &lt;code&gt;http.Handler&lt;/code&gt;, &lt;code&gt;http.RoundTripper&lt;/code&gt;, and &lt;code&gt;http.ResponseWriter&lt;/code&gt;. Following the principle of “accept interfaces, return structs” ensures your codebase is easy to test and gives the consumer of your package the concrete type if needed.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;&lt;span class=&#34;c1&#34;&gt;// keep the interface as narrow as possible&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Reader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;interface&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;kd&#34;&gt;type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myReader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kd&#34;&gt;struct&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Reader&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// implement the interface&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;m&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Errorf&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;read from reader: %w&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// return a struct that implements the interface&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NewMyReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;io&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Reader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myReader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// accept the interface&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;useReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Reader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// use the reader&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;		&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;reading reader: %v&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Println&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;read %d bytes&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;

&lt;span class=&#34;c1&#34;&gt;// use the struct that implements the interface&lt;/span&gt;
&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;doTheRead&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NewMyReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;strings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;NewReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&#34;hello&#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;make&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([]&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;byte&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;w&#34;&gt;	&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;useReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;p&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;br /&gt;
You can also validate if a struct implements an interface by using an interface assertion. This check is typically placed above the declaration of the struct and results in a compile-time error if the struct does not implement the interface.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code class=&#34;language-go&#34;&gt;&lt;span class=&#34;kd&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;_&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Reader&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;myReader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;directory-structure&#34;&gt;Directory Structure&lt;/h2&gt;
&lt;p&gt;Organizing commands in a &lt;code&gt;cmd&lt;/code&gt; directory is a common pattern I prefer, especially for &lt;code&gt;main&lt;/code&gt; packages. This practice makes it clear to consumers of the package where the entry points are located. I also favor keeping packages flat rather than nested or placed under a top-level &lt;code&gt;pkg&lt;/code&gt; directory. This preference simplifies codebase navigation and comprehension.&lt;/p&gt;
&lt;pre class=&#34;highlight&#34;&gt;&lt;code&gt;myapp  
│
└───cmd
│   │
│   └───myapp
│	    │   main.go
│   
└───api
│   │   api.go
│   
└───database
│   │   database.go
│
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;These patterns have served me well in my Go journey, and I hope they help you write cleaner, more maintainable code. I encourage you to experiment with these patterns and adapt them to your needs. Remember, the best code is the one that works for you and your team.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Prototyping new Turn Based Tatics Game</title>
      <link>https://f0ssel.com/posts/prototyping-new-turn-based-tatics-game/</link>
      <guid>https://f0ssel.com/posts/prototyping-new-turn-based-tatics-game/</guid>
      <pubDate>Sun, 06 Mar 2016 17:33:20 +0000</pubDate>
      <category>gamedev</category>
      <description>I’ve been brainstorming a new tile based tatics-like game that I suppose I’m designing for mobile. I’m really trying to focus on making a project that’s DOABLE and within a reasonable scope for while…</description>
      <content:encoded>&lt;p&gt;I’ve been brainstorming a new tile based tatics-like game that I suppose I’m designing for mobile. I’m really trying to focus on making a project that’s DOABLE and within a reasonable scope for while I’m in school and have a budget of zero dollars. Without going into much detail, because right now my ideas are pretty scattered, I’ve been working on making a procedurally generated map the last few days and felt like showing off the first steps of the project.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/prototyping-new-turn-based-tatics-game/screenshot-2016-03-06-12-17-37.png&#34; alt=&#34;Screenshot 2016-03-06 12.17.37&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;789&#34; height=&#34;386&#34;&gt;&lt;/p&gt;
&lt;p&gt;Right now the map can be any radius between 1 and 99, has a rock border and rocks scattered throughout the map, and a procedural river that will always touch from the west wall to the east wall. As you can see above it doesn’t always flow so well, which is something I’m gonna be working on. I have just to impliment anything outside of built in unity perlin and random ranges, for the sake of rapid prototyping. I just changed the hexagons from shape to rounded edges today and really thought it gave a lot to the feel of the terrain. So overall pretty happy about it.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>New Terrain Colors and Grid LOD System</title>
      <link>https://f0ssel.com/posts/new-terrain-colors-and-grid-lod-system/</link>
      <guid>https://f0ssel.com/posts/new-terrain-colors-and-grid-lod-system/</guid>
      <pubDate>Thu, 28 Jan 2016 22:45:55 +0000</pubDate>
      <category>gamedev</category>
      <description>I’ve revamped the terrain UV system to better suit the new texture design I had. Before I had a simple grid of 4 colors, and the height of the triangle’s vertices dictated which color was chose. Now,…</description>
      <content:encoded>&lt;p&gt;I’ve revamped the terrain UV system to better suit the new texture design I had. Before I had a simple grid of 4 colors, and the height of the triangle’s vertices dictated which color was chose. Now, I’m using a fancy looking blurred gradient, and the height of the average of the 3 vertices are now scaled to a number between 0 and 1, and then used to choose the Y component of the texture gradient. The X scale is randomly selected at the moment, but I will most likely use a noise function in the future. This is nice because I can go in photoshop and add little details of darker and lighter colors to give the overall terrain a little more variation. It’s made with layer masks, so I can easily change the layer colors without disrupting the other colors or heights of the transitions.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/new-terrain-colors-and-grid-lod-system/terrainblur.png&#34; alt=&#34;TerrainBlur.png&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1000&#34; height=&#34;1000&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/new-terrain-colors-and-grid-lod-system/islandgen04.png&#34; alt=&#34;islandGen04&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1198&#34; height=&#34;535&#34;&gt;&lt;/p&gt;
&lt;p&gt;I’ve been working on adding smaller lakes to the plains areas of the island and messing around with the Selector function in libNoise has gotten me more familiar with how it works. Hopefully soon I can re-write my noise generation function to include sub-biomes and overall be more expandable in the future.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/new-terrain-colors-and-grid-lod-system/islandgen03.png&#34; alt=&#34;islandGen03&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;658&#34; height=&#34;535&#34;&gt;&lt;/p&gt;
&lt;p&gt;I’ve also run into the same problem Facepunch, the developers of Rust, ran into a while back, and that’s having too make LOD Groups in the scene. Since the island is so massive, I was hitting this cap when I tried to add trees. Like Facepunch, I used my already existing grid system to create a LOD Group per grid. Getting this to work is a small milestone for me, since I had no understanding of how combined meshes worked before I tackled it. Basically, for every chunk, the trees get placed on the terrain. Each tree gameobject is actually a LOD Group, with 4 LODs. I took every LOD0 (highest quality) LOD mesh from every tree gameobject on the mesh, and combined them, and made a new LOD0 with all of them combined. I do this for every level of detail for each object. This results in every item on the chunk changing detail at once instead of every item doing so independantly. This drastically helped performace as well. Right now all objects stay active all the time in the scene. They simply get culled once they are too small in the camera space. There’s still issues to be worked out, I would much rather the LOD system be distance based instead of camera space percentage, since the angle of the ground can make that percentage change drastically. But it’s a great start for me and is keeping performance within reason.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/new-terrain-colors-and-grid-lod-system/islandgen07.png&#34; alt=&#34;islandGen07&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1197&#34; height=&#34;541&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/new-terrain-colors-and-grid-lod-system/islandgen06.png&#34; alt=&#34;islandGen06&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1200&#34; height=&#34;542&#34;&gt;&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Island Generation</title>
      <link>https://f0ssel.com/posts/island-generation/</link>
      <guid>https://f0ssel.com/posts/island-generation/</guid>
      <pubDate>Mon, 25 Jan 2016 02:46:25 +0000</pubDate>
      <category>gamedev</category>
      <description>After a good time away I’ve had some free time to spend messing with a problem I’ve had lately, and that is that I wanted a full map generated without watching chunks come into vision in the distance…</description>
      <content:encoded>&lt;p&gt;After a good time away I’ve had some free time to spend messing with a problem I’ve had lately, and that is that I wanted a full map generated without watching chunks come into vision in the distance like they have been. I’ve tweaked my previous generation code in a lot of ways and made a lot of processes simpler and re-useable for other scripts, and finally came up with version numero uno of my island generation code.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/island-generation/islandgen02.png&#34; alt=&#34;islandGen02&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1152&#34; height=&#34;533&#34;&gt;&lt;/p&gt;
&lt;p&gt;It basically just generates the infinite noise like before but starts stretching the mesh downwards under sea level after it passes a threshhold. I was not happy with how drastic the linear approach was (you could see the change in slope very obviously, or you had mile long beaches) so I tried a quadtratic approach and ended up settling with an power of 4 for the curve from 0  to 1. Like so:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/island-generation/power-curve.svg&#34; alt=&#34;Graph of y = x⁴ against a straight line, from 0 to 1&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34;&gt;&lt;/p&gt;
&lt;p&gt;This meant that after passing the threshhold, it would very slowly start to lower elevation until it got very close to the maxium distance (this being a factor of 1 of the threshold) where it would very quickly fall off. This allows mountains to still be very near beaches without a visually obvious fall off towards the shore.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/island-generation/islandgen01.png&#34; alt=&#34;islandGen01&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1092&#34; height=&#34;531&#34;&gt;&lt;/p&gt;
&lt;p&gt;My first concern with the generations as I went through 20-30 different random seeds is that the mountain ranges always seem to start at the northwest side of the island and will continue towards the southeast side, dispite the seed being changed every iteration.&lt;/p&gt;
&lt;p&gt;Hope to post more soon, exploring this island felt really great. I estimate running from one side of the island to the other should take anywhere from 15-30 minutes, so it feels massive. The much larger polygons and giant scale in general makes it feel a lot better than before and really opens up a lot of awesome views from the vantage points on the island.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Vertex Manipulation</title>
      <link>https://f0ssel.com/posts/vertex-manipulation/</link>
      <guid>https://f0ssel.com/posts/vertex-manipulation/</guid>
      <pubDate>Fri, 25 Sep 2015 23:58:32 +0000</pubDate>
      <category>gamedev</category>
      <description>I’ve been out of sorts with what I want to work on next with my project. Also, school has been keeping me pretty busy. Runtime-player-action-based vertex manipulation is something I’ve planned on…</description>
      <content:encoded>&lt;p&gt;I’ve been out of sorts with what I want to work on next with my project. Also, school has been keeping me pretty busy.&lt;/p&gt;
&lt;p&gt;Runtime-player-action-based vertex manipulation is something I’ve planned on tackling for a while. Today I’ve started the ground level on how to do it. This means that a player can select a vertex on a mesh, and raise or lower it. (Think leveling an area to build a settlement) I plan to expand this idea to being able to manipulate vertices on all items and weapons in the game within margins to make things more personal and possibly add new function.&lt;/p&gt;
&lt;figure class=&#34;not-prose my-8&#34;&gt; &lt;video src=&#34;https://f0ssel.com/media/videos/mvHmkVEw5HM.mp4&#34; poster=&#34;/media/videos/mvHmkVEw5HM.jpg&#34; controls playsinline preload=&#34;none&#34; width=&#34;1280&#34; height=&#34;720&#34; aria-label=&#34;Working on Vertex Manipulation&#34; class=&#34;aspect-video w-full rounded-lg border border-line bg-black&#34;&gt;&lt;/video&gt; &lt;figcaption class=&#34;mt-2 font-mono text-xs text-muted&#34;&gt;Working on Vertex Manipulation&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;More to come on this topic in the future.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Glider, Moon Phases, and A First Look at the Combat System</title>
      <link>https://f0ssel.com/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/</link>
      <guid>https://f0ssel.com/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/</guid>
      <pubDate>Mon, 31 Aug 2015 01:42:36 +0000</pubDate>
      <category>gamedev</category>
      <description>Enemy AI What you see above is a cute little Slime. It wanders, it stays on the ground and doesn’t fly away, and it (tries) to avoid running into trees. If you get too close, it comes after you, but…</description>
      <content:encoded>&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-03-09.png&#34; alt=&#34;Screenshot 2015-08-30 21.03.09&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;628&#34; height=&#34;474&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;enemy-ai&#34;&gt;Enemy AI&lt;/h2&gt;
&lt;p&gt;What you see above is a cute little Slime. It wanders, it stays on the ground and doesn’t fly away, and it (tries) to avoid running into trees. If you get too close, it comes after you, but don’t worry it doesn’t do damage (yet). Instead it tries to get so close to the center of your hitbox if you position yourself correctly it’ll dance on your head.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-03-25.png&#34; alt=&#34;Screenshot 2015-08-30 21.03.25&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;670&#34; height=&#34;498&#34;&gt;&lt;/p&gt;
&lt;p&gt;The slime has a very basic AI and is the starting point of my mob system. They are inactive unless within a certain range. I may consider turning them off completely if I can find a way to do so without messing with the behavior. They have 100 health and 1 arrow shot does 25 damage, and as they lose health they change color from a nice see-thru green to a see-thru yellow and see-thru red. Eventually when it’s health drops below zero it destroys itself. But how do you do damage to it???…&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-05-03.png&#34; alt=&#34;Screenshot 2015-08-30 21.05.03&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;708&#34; height=&#34;387&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;arrows&#34;&gt;Arrows&lt;/h2&gt;
&lt;p&gt;I modeled an arrow prefab and worked up a system for shooting it out from in front of the player to a target that is raycasted from the center of the camera view (it sorta matches up). They do damage to Slimes. They fly nicely through the air and are rigidbodies so they are affected by gravity and take time to reach their target. This means you have to lead your shots based on distance and enemy movement. There is also no crosshair. Good luck!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-06-00.png&#34; alt=&#34;Screenshot 2015-08-30 21.06.00&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1869&#34; height=&#34;1014&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;glider&#34;&gt;Glider&lt;/h2&gt;
&lt;p&gt;I wrote up a Glider system that works very similarly and is inspired in almost every regard from the glider in Cubeworld. It makes traveling quicker and gives great views. It works like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Having the glider out makes you fall slower&lt;/li&gt;
&lt;li&gt;While in the air with the glider you travel faster&lt;/li&gt;
&lt;li&gt;“rigging” the glider (Space Bar) uses stamina* but lets you travel farther&lt;/li&gt;
&lt;li&gt;While rigging, your y-direction velocity is frozen and it’s ceiling is zero. This means if you time your rigging correctly with your jump you can have virtually zero falling velocity until you run out of stamina*&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;*Stamina is not in yet. You can rig forever at the moment&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-06-24.png&#34; alt=&#34;Screenshot 2015-08-30 21.06.24&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1866&#34; height=&#34;927&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;clouds&#34;&gt;Clouds&lt;/h2&gt;
&lt;p&gt;Clouds are in! Volumetric and very in size, rotation, and density of cloud clusters. I’m STILL working on fog, but once I have a good solution they will be noticeably in the distance and not such a clear view like they are now.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-08-49.png&#34; alt=&#34;Screenshot 2015-08-30 21.08.49&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1824&#34; height=&#34;960&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;moon-and-moon-accessories-phasing&#34;&gt;Moon and Moon Accessories (Phasing)&lt;/h2&gt;
&lt;p&gt;The moon is in, and it rotated around just like the sun does. It has it’s own special light that only shines on it, and that light rotates a little bit every day, and gives the moon phases, just like in real life! When full, the moon will brighten up the night sky with a foggy glow, and will illuminate a dim bluish-white light. As it changes phases the fog will dim along with the ambient light. Right now there are 12 days between full moons. Two pictures below contrast a full moon and a half moon.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-09-35.png&#34; alt=&#34;Screenshot 2015-08-30 21.09.35&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1158&#34; height=&#34;825&#34;&gt; &lt;img src=&#34;https://f0ssel.com/media/posts/glider-moon-phases-and-a-first-look-at-the-combat-system/screenshot-2015-08-30-21-11-52.png&#34; alt=&#34;Screenshot 2015-08-30 21.11.52&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1078&#34; height=&#34;718&#34;&gt;&lt;/p&gt;
&lt;p&gt;Got a lot done this week, and seems I’ve got a little bump in viewers of this blog so that’s awesome. I hope you guys like what I’m putting out. I’ve become a little more ambitious in my development goals as I’ve talked to people about it, so I’ll be trying my best to keep moving with new content.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Skybox, Time of Day, 3rd Person Camera, New Trees</title>
      <link>https://f0ssel.com/posts/skybox-time-of-day-3rd-person-camera-new-trees/</link>
      <guid>https://f0ssel.com/posts/skybox-time-of-day-3rd-person-camera-new-trees/</guid>
      <pubDate>Wed, 26 Aug 2015 16:20:28 +0000</pubDate>
      <category>gamedev</category>
      <description>3rd Person Camera I got tired of the old cube dude model so I made another equally temporary low poly dude to take his place. I think he’s a little cuter. I’m having a hard time committing to a…</description>
      <content:encoded>&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/skybox-time-of-day-3rd-person-camera-new-trees/screenshot-2015-08-26-11-53-45.png&#34; alt=&#34;Screenshot 2015-08-26 11.53.45&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1912&#34; height=&#34;1080&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;3rd-person-camera&#34;&gt;3rd Person Camera&lt;/h2&gt;
&lt;p&gt;I got tired of the old cube dude model so I made another equally temporary low poly dude to take his place. I think he’s a little cuter. I’m having a hard time committing to a character concept, I really am stumped with this part. So I’ve just been going hard at the environment. I added in the old 3rd person camera, and I’m working on the controls because right now it’s shaky when traveling on anything besides flat ground.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/skybox-time-of-day-3rd-person-camera-new-trees/screenshot-2015-08-26-11-54-05.png&#34; alt=&#34;Screenshot 2015-08-26 11.54.05&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1912&#34; height=&#34;1080&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;trees&#34;&gt;Trees&lt;/h2&gt;
&lt;p&gt;New tree models were needed, and I think they look good. I’m going to make a few variations of similar looking trees to start mixing things up. I figured out how to unwrap a UV map in blender, as well as add ambient occlusion map to it in Photoshop, so from now on everything I model will have the sexy shadows in the edges. Only problem I see in the future is a world where everything is AO except the procedural stuff, so we’ll have to figure that one out when we get there. By making all the trees share the same one material with a texture and using more larger trees instead of a bunch of smaller trees I cut my draw calls down from around 7,000 to around 1,200 so the frames shot right back up.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/skybox-time-of-day-3rd-person-camera-new-trees/screenshot-2015-08-26-11-53-25.png&#34; alt=&#34;Screenshot 2015-08-26 11.53.25&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1916&#34; height=&#34;1080&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;skybox&#34;&gt;Skybox&lt;/h2&gt;
&lt;p&gt;I said fuck it to the solid color skybox + fox + camera clipping for now. I just cant find a good way to make the fog work the way I’d like it to. So the default procedural skybox is in, and honestly is looks great. I’m going to try my best to work with this one. The major downside is without fog you see chunks generating in the distance. Oh well. I added stars that fade in and out depending on the sun angle, so that’s pretty cool. Still no moon though.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/skybox-time-of-day-3rd-person-camera-new-trees/screenshot-2015-08-26-11-52-17.png&#34; alt=&#34;Screenshot 2015-08-26 11.52.17&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1912&#34; height=&#34;1080&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;night-time&#34;&gt;Night Time&lt;/h2&gt;
&lt;p&gt;So right now right time is really dark. The stars look great and the only light in the whole world is a very very dim blue light. I would like to have a moon cycle that would change every night, and depending on how full the moon is, the brighter the ambient night light would be. I think I have it figured out, and I’ll probably trying to implement that in the next few updates.&lt;/p&gt;
&lt;p&gt;The lamp has been modified a little on it’s intensity, spread, and position with the player, so it feels a little better. It’s very rust-esque in the fact that you can see whats immediately around you, and you can sorta see stuff in the distance. I may model a little lantern for it soon to pop up.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/skybox-time-of-day-3rd-person-camera-new-trees/screenshot-2015-08-26-11-52-58.png&#34; alt=&#34;Screenshot 2015-08-26 11.52.58&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1916&#34; height=&#34;1080&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;plans&#34;&gt;Plans&lt;/h2&gt;
&lt;p&gt;I hope to start modeling more things to put into the world. Grass, campfires, lantern, animals, clouds, all kinds of stuff. I may not have a solid feel for the main character, but I have good pictures in my head for world objects and I’d like to start making it feel more immersive.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Optimization and Day / Night Cycle</title>
      <link>https://f0ssel.com/posts/optimization-and-day-night-cycle/</link>
      <guid>https://f0ssel.com/posts/optimization-and-day-night-cycle/</guid>
      <pubDate>Fri, 21 Aug 2015 04:53:50 +0000</pubDate>
      <category>gamedev</category>
      <description>Optimization I’ve increased the draw distance to the length I’m happy with and it resulted in a huge amount of draw calls and dropped my locked 60 fps down to an average of 24 fps. So I’ve been doing…</description>
      <content:encoded>&lt;h2 id=&#34;optimization&#34;&gt;Optimization&lt;/h2&gt;
&lt;p&gt;I’ve increased the draw distance to the length I’m happy with and it resulted in a huge amount of draw calls and dropped my locked 60 fps down to an average of 24 fps. So I’ve been doing a lot of under the hood stuff to help with that. One of the main problems is I had 4 different materials for each tree prefab, so I turned those 4 materials into 1 UV map in Blender, and that cut it down to a 1/4th of what it was. I then created LODs for the tree prefab and Occlusion Culling for not only items out of the shot but also covered by other objects in the scene. So now I can look at over 1000 trees in the distance and I can hold a steady 60 fps. Since I’ve set up the LOD and Occlusion Culling is in, I don’t think frame drops will be a problem in the future when I add even more things to the scene, so I’m really glad I started work now on it. I had to learn sometime, so even if I don’t end up using that tree model I’ll have the know how to do it again quickly.&lt;/p&gt;
&lt;figure class=&#34;not-prose my-8&#34;&gt; &lt;video src=&#34;https://f0ssel.com/media/posts/optimization-and-day-night-cycle/draw-distance.mp4&#34; autoplay loop muted playsinline preload=&#34;metadata&#34; aria-label=&#34;Draw distance after LODs and occlusion culling&#34; class=&#34;aspect-video w-full rounded-lg border border-line bg-black&#34;&gt;&lt;/video&gt; &lt;figcaption class=&#34;mt-2 font-mono text-xs text-muted&#34;&gt;Draw distance after LODs and occlusion culling&lt;/figcaption&gt; &lt;/figure&gt;
&lt;h2 id=&#34;day-and-night&#34;&gt;Day and Night&lt;/h2&gt;
&lt;p&gt;Since I’ve decided to try and make the solid color skybox and fog work together, I’ve sacrificed the ability to use a procedural default skybox that’s in Unity. So I’m going to have to figure out how to add gradients and things behind the loaded content to make the skybox look better. I need to add a new sun too. But I messed around with having a dark blue directional light facing the exact opposite of the sun’s directional lighting so that objects in shadows still have depth. It’ looks really good, and I’ll be working on a system that moves them in sync and changes the intensity of each other as the angle and positions move. I simulated some values for night time and gave myself a light like a lantern and I think it looks kind of interesting.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/optimization-and-day-night-cycle/screenshot-2015-08-19-21-12-37-e1440132702823.png&#34; alt=&#34;Screenshot 2015-08-19 21.12.37&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1898&#34; height=&#34;875&#34;&gt; &lt;img src=&#34;https://f0ssel.com/media/posts/optimization-and-day-night-cycle/screenshot-2015-08-19-21-12-54-e1440132727788.png&#34; alt=&#34;Screenshot 2015-08-19 21.12.54&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1891&#34; height=&#34;890&#34;&gt; &lt;img src=&#34;https://f0ssel.com/media/posts/optimization-and-day-night-cycle/screenshot-2015-08-19-21-13-18-e1440132748330.png&#34; alt=&#34;Screenshot 2015-08-19 21.13.18&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1891&#34; height=&#34;905&#34;&gt;&lt;/p&gt;
&lt;p&gt;I’m going to find a good way to implement stars and dynamic clouds once I feel good about the state of the background sky box.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Mind Map, Fog, Water, and Rocks</title>
      <link>https://f0ssel.com/posts/mind-map-fog-water-and-rocks/</link>
      <guid>https://f0ssel.com/posts/mind-map-fog-water-and-rocks/</guid>
      <pubDate>Tue, 18 Aug 2015 05:11:22 +0000</pubDate>
      <category>gamedev</category>
      <description>Mind Map I’ve added a link on the sidebar for my Mind Map. I saw Garry from Rust use the same site and really liked the idea of starting to put something down every time it pops into my head. Now…</description>
      <content:encoded>&lt;h2 id=&#34;mind-map&#34;&gt;Mind Map&lt;/h2&gt;
&lt;p&gt;I’ve added a link on the sidebar for my Mind Map. I saw Garry from Rust use the same site and really liked the idea of starting to put something down every time it pops into my head. Now when I feel stuck I can just look at it and get ideas for other things I can work on. (In a perfect world) Maybe one day I’ll get a little more traffic here and people who seem interested can get a rough road map of what my plans for the future are.&lt;/p&gt;
&lt;figure class=&#34;not-prose my-8&#34;&gt; &lt;video src=&#34;https://f0ssel.com/media/videos/R5EBXc8Wwu8.mp4&#34; poster=&#34;/media/videos/R5EBXc8Wwu8.jpg&#34; controls playsinline preload=&#34;none&#34; width=&#34;1280&#34; height=&#34;720&#34; aria-label=&#34;Fog, Real Water, and Rocks&#34; class=&#34;aspect-video w-full rounded-lg border border-line bg-black&#34;&gt;&lt;/video&gt; &lt;figcaption class=&#34;mt-2 font-mono text-xs text-muted&#34;&gt;Fog, Real Water, and Rocks&lt;/figcaption&gt; &lt;/figure&gt;
&lt;h2 id=&#34;rocks&#34;&gt;Rocks&lt;/h2&gt;
&lt;p&gt;I tweaked the tree placement system and put rocks in. They are rotated randomly and scaled randomly between a range and placed in the same areas as trees, so it still leaves open areas of the grass to travel / build / fight. I also tweaked the code so I can shove any prefab into it and give it a few parameters and it’ll generate other stuff too (I’m thinking underwater items eventually).&lt;/p&gt;
&lt;p&gt;Welp, class started back today. I don’t think I’ll be slowing down on my work though, I’m really starting to feel some momentum. Let’s see how it goes.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Tiling Based on Movement, Trees Placed by Noise</title>
      <link>https://f0ssel.com/posts/tiling-based-on-movement-trees-placed-by-noise/</link>
      <guid>https://f0ssel.com/posts/tiling-based-on-movement-trees-placed-by-noise/</guid>
      <pubDate>Fri, 14 Aug 2015 21:38:44 +0000</pubDate>
      <category>gamedev</category>
      <description>I’ve had some free time before school starts so I’ve been crunching out as many updates as I can. The chunk tiling I mentioned last time (like has Minecraft does it) is started and I learned a lot…</description>
      <content:encoded>&lt;p&gt;I’ve had some free time before school starts so I’ve been crunching out as many updates as I can. The chunk tiling I mentioned last time (like has Minecraft does it) is started and I learned a lot today about making Lists in Unity and working on items from the list every frame, instead of trying to start and finish a loop in a single frame. I originally wrote the tree placement and chunk generator to be done all at Start(), but it started taking a lot longer the more I added things, and I never planned to actually pre-generate the whole map at start anyways, it was just a good place to start learning how to do these things. So now I have chunks filed into a queue whenever you move out of the area that is already generated, and the queue loads exactly 1 chunk every frame. It works surprising well, and I’ll probably keep it like this since I plan to add distance fog in the future that will cover up any chunks being rendered in the distance. Cubeworld has a really nice looking fog that basically increases your draw distance based on your computer’s performance, or maybe based on how many chunks away it’s already rendered, not really sure since it’s just speculation. Either way it’s cool and I’d like to do something like that soon.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/tiling-based-on-movement-trees-placed-by-noise/screenshot-2015-08-14-17-33-511-e1439651023526.png&#34; alt=&#34;Screenshot 2015-08-14 17.33.51&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1440&#34; height=&#34;600&#34;&gt;&lt;/p&gt;
&lt;p&gt;I messed with the colors and the height cutoffs to make it look a little better. Still needs a lot of work. Still cheating with the water plane too. The trees are generated 1 tree per frame per chunk. So where there’s 49 chunks (like in the video below) around you they are generating at 49 trees per frame. Again, except for at initial generation, you will almost never see them being generated. Still looks cool though.&lt;/p&gt;
&lt;figure class=&#34;not-prose my-8&#34;&gt; &lt;video src=&#34;https://f0ssel.com/media/videos/i_WgqQnE6cE.mp4&#34; poster=&#34;/media/videos/i_WgqQnE6cE.jpg&#34; controls playsinline preload=&#34;none&#34; width=&#34;1280&#34; height=&#34;720&#34; aria-label=&#34;ProcGen 0.1 and Tree Placement from Noise&#34; class=&#34;aspect-video w-full rounded-lg border border-line bg-black&#34;&gt;&lt;/video&gt; &lt;figcaption class=&#34;mt-2 font-mono text-xs text-muted&#34;&gt;ProcGen 0.1 and Tree Placement from Noise&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;The placement of the trees are based on a Perlin noise with a cutoff value, and after messing with the cutoff value to find the sweet spot, I really like the results. Here’s a short list off the top of my head that I think are doable goals I’ll be working on next:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;More tree models&lt;/li&gt;
&lt;li&gt;Rock spawning&lt;/li&gt;
&lt;li&gt;Other object spawning(ruins / driftwood / flowers )&lt;/li&gt;
&lt;li&gt;Water Implementation (just the surface)&lt;/li&gt;
&lt;li&gt;Tweak colors / scale / noise of terrain&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And here’s some stuff I have no clue how to do and plan to tackle next:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Biomes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Ocean edges&lt;/li&gt;
&lt;li&gt;Ambient Sounds&lt;/li&gt;
&lt;li&gt;Better Day / Night&lt;/li&gt;
&lt;li&gt;Post Processing Effects&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Honestly I’m not even thinking about a character model / controller because I think the world and the feel should come first, and I think there’s a lot more documentation on the more classical game elements than the other things listed above, so I don’t think I’ll have a hard time with it.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>ProcGen 0.1</title>
      <link>https://f0ssel.com/posts/procgen-0-1/</link>
      <guid>https://f0ssel.com/posts/procgen-0-1/</guid>
      <pubDate>Thu, 13 Aug 2015 22:32:00 +0000</pubDate>
      <category>gamedev</category>
      <description>I am very happy to present the first look at my progress with low poly procedural generation. So there’s a lot going on here. Generally speaking, chunks are assigned starting points, noise is…</description>
      <content:encoded>&lt;p&gt;I am very happy to present the first look at my progress with low poly procedural generation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/procgen-0-1/preview.png&#34; alt=&#34;preview&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;936&#34; height=&#34;542&#34;&gt;&lt;/p&gt;
&lt;p&gt;So there’s a lot going on here. Generally speaking, chunks are assigned starting points, noise is rendered, the mesh is created for each chunk, height is given to the vertex based on the noise algorithm, and a solid color texture is given to the triangles based on the min height of the three vertices.&lt;/p&gt;
&lt;p&gt;I’m using the Unity port of the noise library LibNoise, the noise generated in the picture above is following the tutorial made by the creator. I plan to tweak it to fit what I want, and hopefully expand into regions / biomes in the future. But for now it’s looking great and really showing off what it can do.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/procgen-0-1/preview4.png&#34; alt=&#34;preview4&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;944&#34; height=&#34;539&#34;&gt;&lt;/p&gt;
&lt;p&gt;Right now I’m generating the meshes in chunks, each 20 x 20 (unity units?). Unity can handle about 20×20 chunks generated at start. I plan to eventually get chunks loaded based on where the camera is in the world, like Minecraft.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/procgen-0-1/preview2.png&#34; alt=&#34;preview2&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;941&#34; height=&#34;543&#34;&gt;&lt;/p&gt;
&lt;p&gt;A straight line is used for the height cutoff values of the colors, and it doesn’t look half bad. I kind of like the even look. But I will probably use a noise function in the future to decides the colors so it looks a little more natural.&lt;/p&gt;
&lt;p&gt;I’m cheating with the water, its just a colored plane I added at about the right spot. That’s the next task on the agenda. That, and implementing my prefab spawning script I wrote into these meshes and seeing how that works out. I’m really happy I finally tackled this daunting task, because I really just couldn’t wrap my head around the process for the longest time.&lt;/p&gt;
&lt;p&gt;Progress is being made!&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/procgen-0-1/preview3.png&#34; alt=&#34;preview3&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;939&#34; height=&#34;539&#34;&gt;&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Baby Steps</title>
      <link>https://f0ssel.com/posts/baby-steps/</link>
      <guid>https://f0ssel.com/posts/baby-steps/</guid>
      <pubDate>Mon, 10 Aug 2015 17:55:30 +0000</pubDate>
      <category>gamedev</category>
      <description>I woke up today with the idea to just mess around with purely my previous knowledge of math and some help from the unity manual, and I got my first baby step into understanding how to create…</description>
      <content:encoded>&lt;p&gt;I woke up today with the idea to just mess around with purely my previous knowledge of math and some help from the unity manual, and I got my first baby step into understanding how to create procedural meshes within unity. It’s a simple code that I’ll have to rewrite once I figure out how to make it fit all purposes, but I got something and I’m super excited about it.&lt;/p&gt;
&lt;p&gt;More details to come! (When I figure it out…)&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/baby-steps/screenshot-2015-08-10-13-49-58.png&#34; alt=&#34;Screenshot 2015-08-10 13.49.58&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;1934&#34; height=&#34;1080&#34;&gt;&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Tinted Lighting, Spawning Prefabs, Terrain Research</title>
      <link>https://f0ssel.com/posts/tinted-lighting-spawning-prefabs-terrain-research/</link>
      <guid>https://f0ssel.com/posts/tinted-lighting-spawning-prefabs-terrain-research/</guid>
      <pubDate>Thu, 23 Jul 2015 04:27:02 +0000</pubDate>
      <category>gamedev</category>
      <description>It’s been a while and I haven’t really worked on much over this break, but I’ve been researching a good bit on different ways I should think about tackling procedural terrain generation that will…</description>
      <content:encoded>&lt;p&gt;It’s been a while and I haven’t really worked on much over this break, but I’ve been researching a good bit on different ways I should think about tackling procedural terrain generation that will still look like what I’m going for. It’s all a bit over my head at the moment so I think I’m going to hold off on that topic for the time being. I like the idea of starting with a hand crafted map to begin with, and then exploring procgen at a later date. For now I have a little flat valley surrounded by mountains, and it’ll be my playground until I need something else.&lt;/p&gt;
&lt;p&gt;Despite handcrafting the terrain itself, I have no interest in placing every object in the world. So I started and finished that project today, or at least the framework for it. Right now the script finds the dimensions of the mesh, shoots rays down through the mesh, finds the normals and then places the objects along the terrain normals so hopefully I can get some interesting results on hills. For some added randomness I have the trees rotate around the trunk randomly, as well as the rocks on their x and y axis. I also added parameters so that trees shouldn’t spawn on too steep of hills, and also added a density function based on the area of available spawning places. Trees shouldn’t spawn on rocks or other trees (hopefully).&lt;/p&gt;
&lt;p&gt;I also worked on tinting the lighting. This means that in the morning there will be a cyan tint to the light, daytime will be a typical white-yellow, and afternoon will be orange-ish into a deeper red for sunset. I’d love to add a weather system soon that can work with and affect the ambient tint of the lighting.&lt;/p&gt;
&lt;figure class=&#34;not-prose my-8&#34;&gt; &lt;video src=&#34;https://f0ssel.com/media/videos/0_Z7ifs9X88.mp4&#34; poster=&#34;/media/videos/0_Z7ifs9X88.jpg&#34; controls playsinline preload=&#34;none&#34; width=&#34;1280&#34; height=&#34;720&#34; aria-label=&#34;Tree and Rock Spawning, Tinted Lighting&#34; class=&#34;aspect-video w-full rounded-lg border border-line bg-black&#34;&gt;&lt;/video&gt; &lt;figcaption class=&#34;mt-2 font-mono text-xs text-muted&#34;&gt;Tree and Rock Spawning, Tinted Lighting&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;That’s really all for today, I hope to work on this more often but not sure for the next few weeks. I’m moving soon, working every now and then, and starting back to school in less than a month so we’ll see.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Basic Movement Controller</title>
      <link>https://f0ssel.com/posts/basic-movement-controller/</link>
      <guid>https://f0ssel.com/posts/basic-movement-controller/</guid>
      <pubDate>Sun, 05 Jul 2015 20:38:58 +0000</pubDate>
      <category>gamedev</category>
      <description>I felt it was important to talk for a second on the movement controller for a second. I am very particular about controllers for games, and I have ran into a few really, really good ones, and a lot…</description>
      <content:encoded>&lt;p&gt;I felt it was important to talk for a second on the movement controller for a second. I am very particular about controllers for games, and I have ran into a few really, really good ones, and a lot of terrible ones. I will be spending a probably more than fair amount of time on tweaking the character controller throughout development, because I feel its one of the most important things in a game. I get a lot of inspiration from games such as the Dark Souls series and Cubeworld (RIP Wollay…) for the 3rd person orbiting camera style that I love so much. Cubeworld has amazing feel to it, and I plan to use a lot of similar mechanisms to achieve a similar feel in movement, camera control, and combat. I also want to make sure the game is completely playable with a controller along side mouse and keyboard, which is another reason why Unity is so great for these kinds of projects.&lt;/p&gt;
&lt;p&gt;I have a character controller in place that I wrote a while back, and will most likely be using it as my baseline code. It’s a shitty little cube man holding it’s place for a real model. I’ve been thinking a lot on what kind of character model for a while and haven’t felt solid on a single idea yet, so he’s staying until I do. (Along with the animations I need to learn how to do at some point) It’s arcade-y and responsive and gets the job done for now. He jumps and climbs so far.&lt;/p&gt;
&lt;figure class=&#34;not-prose my-8&#34;&gt; &lt;video src=&#34;https://f0ssel.com/media/videos/DWlXlTaWYKI.mp4&#34; poster=&#34;/media/videos/DWlXlTaWYKI.jpg&#34; controls playsinline preload=&#34;none&#34; width=&#34;1280&#34; height=&#34;720&#34; aria-label=&#34;First Draft Movement and Camera&#34; class=&#34;aspect-video w-full rounded-lg border border-line bg-black&#34;&gt;&lt;/video&gt; &lt;figcaption class=&#34;mt-2 font-mono text-xs text-muted&#34;&gt;First Draft Movement and Camera&lt;/figcaption&gt; &lt;/figure&gt;
&lt;p&gt;I messed around with lighting for a good hunk of hours today, and really didn’t get anywhere. All the pre-baked stuff I would do turned out awful looking, and the on screen ambient occlusion that is built into Unity was fuzzy and terrible looking. I’m going to have to look more into lighting. Right now the realtime lighting looks good enough, and I think once I get a AO solution it will be great.&lt;/p&gt;
</content:encoded>
    </item>
    <item>
      <title>Starting Work with Dynamic Lighting in Unity 5</title>
      <link>https://f0ssel.com/posts/starting-work-with-dynamic-lighting-in-unity-5/</link>
      <guid>https://f0ssel.com/posts/starting-work-with-dynamic-lighting-in-unity-5/</guid>
      <pubDate>Sun, 05 Jul 2015 20:36:43 +0000</pubDate>
      <category>gamedev</category>
      <description>I know I just posted earlier today but I got home and was itching to figure out the lighting in unity. I came across a method that is new to Unity 5 to simulate a day and night cycle and imported my…</description>
      <content:encoded>&lt;p&gt;I know I just posted earlier today but I got home and was itching to figure out the lighting in unity. I came across a method that is new to Unity 5 to simulate a day and night cycle and imported my little island I made a few days ago so I had something to work with, and it turned out better than I expected. The default settings are being used so I still need to tweak with the GI and AO, as well as the reflections on the shaders. But that’s all besides the point. The shadows look great in Unity 5 and I can’t wait to really dive into working with the lighting and ambient color to get that “awe” effect.&lt;/p&gt;
&lt;p&gt;I guess you could call this an end of day 1 video:&lt;/p&gt;
&lt;figure class=&#34;not-prose my-8&#34;&gt; &lt;video src=&#34;https://f0ssel.com/media/videos/o_rOKqoL5x0.mp4&#34; poster=&#34;/media/videos/o_rOKqoL5x0.jpg&#34; controls playsinline preload=&#34;none&#34; width=&#34;1280&#34; height=&#34;720&#34; aria-label=&#34;Day Night Cycle Test&#34; class=&#34;aspect-video w-full rounded-lg border border-line bg-black&#34;&gt;&lt;/video&gt; &lt;figcaption class=&#34;mt-2 font-mono text-xs text-muted&#34;&gt;Day Night Cycle Test&lt;/figcaption&gt; &lt;/figure&gt;
</content:encoded>
    </item>
    <item>
      <title>First Blender Render</title>
      <link>https://f0ssel.com/posts/first-blender-render/</link>
      <guid>https://f0ssel.com/posts/first-blender-render/</guid>
      <pubDate>Sun, 05 Jul 2015 20:34:17 +0000</pubDate>
      <category>gamedev</category>
      <description>With the official birth of this blog I’d like to show what I have worked on so far while teaching myself Blender. I’ve been following posts on /r/low_poly and love the art style, so I thought I’d…</description>
      <content:encoded>&lt;p&gt;With the official birth of this blog I’d like to show what I have worked on so far while teaching myself Blender. I’ve been following posts on /r/low_poly and love the art style, so I thought I’d give it a shot.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://f0ssel.com/media/posts/first-blender-render/island2.png&#34; alt=&#34;Island2&#34; loading=&#34;lazy&#34; decoding=&#34;async&#34; width=&#34;960&#34; height=&#34;540&#34;&gt;&lt;/p&gt;
&lt;p&gt;I hope to use this art style in upcoming projects I’m going to be working on. Right now there is no clear direction, I’m just trying to dive into something and see what unfolds. I plan to update this blog whenever I have milestones in my work and document my progress throughout my future projects.&lt;/p&gt;
</content:encoded>
    </item>
  </channel>
</rss>
