<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: forbit</title>
    <description>The latest articles on DEV Community by forbit (@forbit).</description>
    <link>https://dev.to/forbit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F644966%2F59c4d8c8-81bb-4f95-8679-54b0919ecb07.png</url>
      <title>DEV Community: forbit</title>
      <link>https://dev.to/forbit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/forbit"/>
    <language>en</language>
    <item>
      <title>recent thoughts about gen-ai</title>
      <dc:creator>forbit</dc:creator>
      <pubDate>Mon, 24 Nov 2025 12:45:37 +0000</pubDate>
      <link>https://dev.to/forbit/recent-thoughts-about-gen-ai-57hj</link>
      <guid>https://dev.to/forbit/recent-thoughts-about-gen-ai-57hj</guid>
      <description>&lt;p&gt;i feel robbed of my own progress when i rely solely on AI to code for me. there has been, over the past 4 years since i started working as a software engineer, a clear increase in my skills as a programmer. at my latest new job - i am surrounded by people more talented &amp;amp; experienced than me, and i feel like i rob myself of the opportunity to actually learn &amp;amp; grow by trying to force AI to write the code for me, rather than do it myself.&lt;/p&gt;

&lt;p&gt;i have aspirations, too many projects, that i felt the need to go to vibe coding as a crux. i was able to alt-tab between 4 different projects, just being a code reviewer &amp;amp; prompter, and i felt a similar flow state to original coding. but after a 2 month break and trying to get back into it (&lt;a href="https://forbit.dev/projects/mycelia" rel="noopener noreferrer"&gt;mycelia&lt;/a&gt;), im left with the consequences of my own haste.&lt;/p&gt;

&lt;p&gt;the projects aren't laid out in the way i would in my head, so im searching for things that i thought would exist where they should - but don't. the code isn't of a high quality - it's verbose and over-fitted to edge cases &amp;amp; bugs that the ai managed to pickup, but has holes that it would've missed. ironically - it fills up it's own context window as if it gets a prize for writing large files.&lt;/p&gt;

&lt;p&gt;part of what i've learnt at my current job (one of the faang ones) is the benefits of writing less. functional-style programming that favours composition of base building blocks in order to structure higher-level business logic with ease is something that i'll likely spend the next 10,000 hours of my career mastering. im robbing myself of that opportunity to ask "how could i write this better" when i don't go through the motions of typing that text out myself.&lt;/p&gt;

&lt;p&gt;the cracked engineers aren't using ai to save time coding. they're using it to save time identifying areas in the code. i almost want a "read-only" mode for the ai. getting llm's on the device through things like copilot, and then cursor &amp;amp; now claude-cli and codex (and &lt;a href="https://opencode.ai/" rel="noopener noreferrer"&gt;opencode&lt;/a&gt;, which i use) - have been a great advancement. i think giving these cli-based tools write access was a mistake.&lt;/p&gt;

&lt;p&gt;ai is at it's most powerful when summarizing - that's why i started working on &lt;a href="https://forbit.dev/projects/chamber" rel="noopener noreferrer"&gt;chamber&lt;/a&gt;, i always knew this. it isn't great at creation, it's not &lt;em&gt;really&lt;/em&gt; generative, it's transformative. no wonder the discovery that kicked off the llm cold war was the transformer. i'll probably spend some time now investing in how to get the most out of a read-only AI. i can see a couple uses, but it has some pre-reqs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;indexing a code project&lt;/li&gt;
&lt;li&gt;understanding how the project went from spec -&amp;gt; implementation (git timeline)&lt;/li&gt;
&lt;li&gt;updating with tips on how to code better after each commit (pr bot but in terminal, not on a UI somewhere in the cloud.)&lt;/li&gt;
&lt;li&gt;agent baked with knowledge of how i want to write code

&lt;ul&gt;
&lt;li&gt;functional&lt;/li&gt;
&lt;li&gt;concise&lt;/li&gt;
&lt;li&gt;composition over inheritance&lt;/li&gt;
&lt;li&gt;multi-faceted&lt;/li&gt;
&lt;li&gt;favour easy testability (in-memory representations of &lt;strong&gt;all&lt;/strong&gt; logic)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;what to work on next (ingests todo lists, project spec, and current progress)&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;let's see where this goes.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to fix glossy selects in webkit (Safari)</title>
      <dc:creator>forbit</dc:creator>
      <pubDate>Sun, 12 Jan 2025 08:18:41 +0000</pubDate>
      <link>https://dev.to/forbit/how-to-fix-glossy-selects-in-webkit-safari-3okh</link>
      <guid>https://dev.to/forbit/how-to-fix-glossy-selects-in-webkit-safari-3okh</guid>
      <description>&lt;p&gt;Making sure your application works the same across all the different browser engines can be a major pain. Recently, I encountered a new battle in one of my projects devpad. This project I decided to not use any UI framework/library, and to rely on the base html elements as much as possible. The &lt;code&gt;&amp;lt;select&amp;gt;&lt;/code&gt; element is probably one we're all familiar with, but it's got some weird behaviour in Safari.&lt;/p&gt;




&lt;p&gt;So there I was, happily building using Arc, a chromium-based browser, when I decided (luckily) to check how things looked in Safari:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoxsjn5w7v6o7oln6aqq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgoxsjn5w7v6o7oln6aqq.png" alt="Safari glossy select elements" width="738" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For comparison, here's the exact same elements on chromium vs safari:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnu6so994m66w1kjytv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbnu6so994m66w1kjytv5.png" alt="chrome vs safari select" width="400" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Why did these select elements have this weird, 2008, original iOS look? They looked perfectly fine in my usual browser, what was going on here? After some stack overflow and chatgpt digging around, I finally landed on a solution, but it was quite the tricky road.&lt;/p&gt;

&lt;p&gt;The top answer on stack overflow is to use something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;-webkit-appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, you'll soon find out this &lt;strong&gt;removes the little arrow icon&lt;/strong&gt;, which indicates to your user that it is a dropdown select menu, so not the best thing to remove.&lt;/p&gt;




&lt;p&gt;The answer underneath that offers the first little insight into the solution: use a background-image svg, however this is a bit tricky to get to work if you already want to set a background-colour on the element, which I imagine most people do.&lt;/p&gt;

&lt;p&gt;Now, I love using &lt;a href="https://lucide.dev" rel="noopener noreferrer"&gt;lucide.dev&lt;/a&gt; icons, so I grabbed the svg with the 'Copy SVG' button, pasted it in, and hey look at that it works! All that you need to change is the stroke colour to whatever you need.&lt;/p&gt;

&lt;p&gt;But that when I came across my first issue, changing the colour scheme didn't change the colour of the svg, and you &lt;strong&gt;can't use CSS variables&lt;/strong&gt; in the background-image value. So I tried to put a &lt;code&gt;@media&lt;/code&gt; clause within the select element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* disable the gloss effect on safari */&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-moz-appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('data:image/svg+xml;utf8,&amp;lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down"&amp;gt;&amp;lt;path d="m6 9 6 6 6-6"/&amp;gt;&amp;lt;/svg&amp;gt;')&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--input-background&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('data:image/svg+xml;utf8,&amp;lt;svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down"&amp;gt;&amp;lt;path d="m6 9 6 6 6-6"/&amp;gt;&amp;lt;/svg&amp;gt;')&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I 100% thought this would work, and then I went to the page, set my theme to dark mode... the arrow was still black. Inspecting the element shows the class is being applied to the element, but there is some "Invalid property value" error, despite it being the exact same string as the one that is being shown (in the wrong colour). The only difference is the &lt;code&gt;stroke="white"&lt;/code&gt; instead of &lt;code&gt;stroke="black"&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz78enoix6w8sg54s8j2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz78enoix6w8sg54s8j2k.png" alt="Perfectly valid invalid property value" width="319" height="196"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No worries, this is where ChatGPT comes in to save the day. By some stroke of genius, it managed to fix it by URL encoding the svg string. Here's the final &lt;strong&gt;(working)&lt;/strong&gt; css classes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;-webkit-appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;-moz-appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;appearance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22black%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M6%209%2012%2015%2018%209%22/%3E%3C/svg%3E')&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;calc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;100%&lt;/span&gt; &lt;span class="n"&gt;-&lt;/span&gt; &lt;span class="m"&gt;3px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="m"&gt;50%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-repeat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;no-repeat&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;--input-background&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nl"&gt;padding-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;24px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url('data:image/svg+xml,%3Csvg%20xmlns=%22http://www.w3.org/2000/svg%22%20width=%2224%22%20height=%2224%22%20viewBox=%220%200%2024%2024%22%20fill=%22none%22%20stroke=%22white%22%20stroke-width=%222%22%20stroke-linecap=%22round%22%20stroke-linejoin=%22round%22%3E%3Cpath%20d=%22M6%209%2012%2015%2018%209%22/%3E%3C/svg%3E')&lt;/span&gt; &lt;span class="cp"&gt;!important&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hopefully, this post can help at least one other person that comes across the same issue and save them a bit of time messing around.&lt;/p&gt;

&lt;p&gt;The final product, perfect cross-browser select elements with dark/light mode variants:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3z6pipsir2ydijpf8yd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy3z6pipsir2ydijpf8yd.png" alt="Perfect cross-browser select elements" width="400" height="200"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you're interested in the project (devpad) that inspired this, check out my latest &lt;a href="https://forbit.dev/blog/dev/devpad-redesign-6" rel="noopener noreferrer"&gt;blog post&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>safari</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>5 Things I Would Teach Myself 10 Years Ago</title>
      <dc:creator>forbit</dc:creator>
      <pubDate>Tue, 18 Oct 2022 10:39:12 +0000</pubDate>
      <link>https://dev.to/forbit/5-things-i-would-teach-myself-10-years-ago-3gn8</link>
      <guid>https://dev.to/forbit/5-things-i-would-teach-myself-10-years-ago-3gn8</guid>
      <description>&lt;h2&gt;
  
  
  Lesssons
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Show Off Your Work&lt;/li&gt;
&lt;li&gt;Force Yourself To Finish&lt;/li&gt;
&lt;li&gt;Stick to one stack&lt;/li&gt;
&lt;li&gt;Document your progress&lt;/li&gt;
&lt;li&gt;Install Linux&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  1. Show off your work - even if it's horrible
&lt;/h2&gt;

&lt;p&gt;I often reflect and think back on my journey as a programmer. I started in primary school with scratch, and due to my fondness for games, found enjoyment creating games for myself and showing them to my friends. Then, I wanted to write more complex games and one of my teachers from school suggested GameMaker. This engine took me from a drag and drop coder into someone who could actually write code, I felt like a "coder". &lt;/p&gt;

&lt;p&gt;However, my games were never any good, and I was embarrassed to show my friends some of the things I had worked on. The motivation that I had received from showing my friends and them saying "this is really cool" had been the driving force for me to keep learning, but once that pipeline had been taken away, I suddenly found myself unmotivated.&lt;/p&gt;

&lt;p&gt;This is why this lesson would be number one for me. Especially as a younger person, it's sometimes hard to show off things you're passionate about in fear of rejection. So biting the bullet and getting feedback is one of the best things you can do, and it will also set you up for later in your life knowing how to deal with constructive criticism / rejection.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Force yourself to finish
&lt;/h2&gt;

&lt;p&gt;Shiny Object Syndrome often gets the best of us, especially when we're just starting out coding. We learn new technologies and techniques so fast that our old code quickly becomes outdated, and often throwing away everything and starting again might be faster than finishing a project. However this is a quick trap to fall into. For me, one of the most motivating forces that got me to keep coding was imagining my portfolio page, and it being full of projects that I could be proud of and consider completed. However, after about 4 years of coding games with GameMaker, I had no finished and published games. &lt;/p&gt;

&lt;p&gt;This feeling was extremely disheartening, and I realised that I had trouble finishing anything. I had trouble with commitment. Everytime I got to something difficult in the creation of a game; creating assets or dialogue, or a tutorial or a nice UI - I would give up and move onto my next big idea. I would try and explain the idea of a new game to my friends and I was always met with the same response - "what about that other game you were working on".&lt;/p&gt;

&lt;p&gt;When that question was asked my stomach always sank a little bit. Because I knew that the game had defeated me - I lost the battle of discipline. It got too hard and I just quit - I was a quitter. It pained me everytime to come up with some excuse that wasn't "I'm lazy and quit".&lt;/p&gt;

&lt;p&gt;Getting into the habit of finishing projects is exponentially good for your development as a programmer. You learn specific skills about publishing - when to consider something "done", cutting down on scope, minimum viable product etc. Also, having something that you can add to your portfolio or resume as something you're proud of is especially beneficial.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Stick to one stack
&lt;/h2&gt;

&lt;p&gt;During my time making games I mostly stuck with GameMaker. However I was aware of the technical limitations and wanted to experiment with something that I thought would be more "powerful", like Java or C++, or Unity and Godot. However, I spent about 6 months trying to make a simple game with these 4 technologies (or tech "stacks"), and had gotten no further than I was currently at with GameMaker. GameMaker was perfectly able to do what I wanted, and I was simply wasting time with the other languages. Sure, I was learning some abstraction ideas and learning other languages never hurts, but in terms of finishing a game - getting something concrete that I could show off - I was wasting my time.&lt;/p&gt;

&lt;p&gt;This is sometimes a lesson I have to tell myself again and again today. The current webdev landscape is full of fresh new frameworks every week it feels like, and everytime I see one I think to myself, "Wow this could do x so much better than what I'm using now". And so I'll do a bit of research into the new framework but then have to stop myself. &lt;/p&gt;

&lt;p&gt;You get to a point where any language or framework can do what you want too with enough code and determination. This is a lesson that should be shouted into new programmers. Sure, some languages may be better at some things than others - but if you're just learning the new languages, there's no way you're going to be comfortable enough to utilise the specific features of each language that makes them better. Understanding the core fundamentals of a tech stack or language is exponentially more important than learning lots of languages.&lt;/p&gt;

&lt;p&gt;One quote - I don't know where it came from - stuck with me. "A beginner programmer will say they know 2 languages, a novice programmer will say they know 10, and an expert will say they know 2."&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Document your progress
&lt;/h2&gt;

&lt;p&gt;This one is especially useful for when it comes to creating your portfolio and resume, but is also extremely useful for finding motivation when things get tough and you're on the edge of burnout. There are many different tools for this: Pen and Paper, A Blog, or GitHub repos even. Just something to track your projects, what you've learnt from something, and a little description on why this project has furthered your skills is enough to count any project as a "success".&lt;/p&gt;

&lt;p&gt;Everyone has those little side projects that you might have spent one week and then got blocked by some implementation that you couldn't get - but even failures like this can be useful. You now know what you don't know, and for those keen on becoming a better programmer, this knowledge is more valuable than knowing what you do know.&lt;/p&gt;

&lt;p&gt;To be able to look back from where you started, from your first for loop to your first public GitHub project, to your first PR, to your first public API - to be able to look at your progress is soul fulfilling. Being able to see the progress you made is reassuring that you're at the right level - and it will help fight the inevitable imposter syndrome.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Install Linux
&lt;/h2&gt;

&lt;p&gt;Now, this may seem like a pretty opinionated lesson, and it very much is. Programming in Linux is just much nicer than the Windows workflow. Being able to do everything via a terminal is so much nicer than having to install 3 different apps just to edit a project on git. The customisation of linux distros (especially Arch 💙) allows for some more programming learning opportunities. If you spend the time to learn linux, you will eventually come across many concepts in computer hardware that are important to know for when it comes to programming later on - especially low-level programming. Linux is the #1 OS for programmers for a reason; switching earlier will be exponentially beneficial.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
